在笔者开发的大数据平台XSailboat中有 消息中心 模块,用来全平台的消息收集,整理分拆、订阅发送等功能。消息推送方式支持钉钉群聊、钉钉单聊、短信通知。现记录一下企业机器人消息单聊推送的实现过程。
这是官方的开发文档地址:《机器人发送、查询和撤回单聊消息》
将其中的主要过程抄录一下:
步骤一:登录开发者后台,点击应用开发-企业内部开发,创建机器人。
步骤二:点击机器人应用-基础信息,获取AppKey和AppSecret。
步骤三:添加接口调用权限,点击“机器人”,申请企业内机器人发送消息权限。申请权限无需审批,默认开通。
步骤四:上线机器人。进入版本管理与发布页面,点击上线,机器人的状态变更为已发布。
步骤五:获取应用访问凭证获取企业内部应用的accessToken。调用接口时,通过accessToken鉴权调用者身份。
步骤六:调用机器人单聊相关的API:
package com.cimstech.sailboat.ms.msg;
import com.cimstech.sailboat.ms.msg.sender.Letter;
import com.cimstech.xfront.common.http.HttpClient;
import com.cimstech.xfront.common.http.Request;
import com.cimstech.xfront.common.json.JSONArray;
import com.cimstech.xfront.common.json.JSONObject;
import com.cimstech.xfront.common.text.XString;
import com.cimstech.xfront.common.time.XTime;
public class Test
{
/**
* 获取token,查询userId的服务地址
*/
static final String sDingService = "https://oapi.dingtalk.com" ;
/**
* 发送钉钉消息的服务地址
*/
static final String sDingSendService = "https://api.dingtalk.com" ;
/**
* 凭借appKey和appSecret获取token
*/
static final String sPath_GetToken = "/gettoken" ;
/**
* 通过手机号获取企业账号用户
*/
static final String sPath_GetUserByMobile = "/topapi/v2/user/getbymobile" ;
static final String sPath_SendMsgOfSingleChat = "/v1.0/robot/oToMessages/batchSend" ;
static final String sDetailPtn_n = "[以及另外{}条详情..]({})" ;
static final String sDetailPtn_1 = "[详情..]({})" ;
static final String sNoLink = "以及另外{}条" ;
static String[] sColors = new String[] {"#FF0000"
, "#ffa500"
, "#0fdbdb"
, "#12e512"} ;
static String sDetailLink = "http://XXXXX/sailmsg/msgrow?sendBatch={}&totalAmount={}" ;
static JSONObject toJSON(Letter aLetter)
{
int level = aLetter.getLevel() ;
String color = level < sColors.length? sColors[level]:null ;
StringBuilder strBld = new StringBuilder("【消息中心-").append(aLetter.getSubscriberItemName())
.append("】")
.append("-[") ;
if(color != null)
strBld.append("<font color=").append(color).append(">") ;
strBld.append(level).append("级") ;
if(color != null)
strBld.append("</font>") ;
// String partition = aLetter.getPartition() ;
strBld.append("]") ; // .append(sSiteMap.getOrDefault(partition , partition)) ;
String title = strBld.toString() ;
strBld.setLength(0);
strBld.append("**").append(title).append("** \n > ")
.append("<font color=#000000>")
.append(aLetter.getContent())
.append("</font>")
.append(" \n \n ") ;
strBld.append("<font color=#666666>")
.append(aLetter.getEventTime())
.append("</font>")
.append(" ") ;
if(XString.isEmpty(sDetailLink))
{
if(aLetter.getReduceAmount() > 0)
strBld.append(XString.msgFmt(sNoLink , aLetter.getReduceAmount())) ;
}
else
{
if(aLetter.getReduceAmount() > 1)
{
strBld.append(XString.msgFmt(sDetailPtn_n, aLetter.getReduceAmount()
, XString.msgFmt(sDetailLink , aLetter.getSendBatch() , aLetter.getReduceAmount()))) ;
}
else
{
strBld.append(XString.msgFmt(sDetailPtn_1
, XString.msgFmt(sDetailLink , aLetter.getSendBatch() , aLetter.getReduceAmount()))) ;
}
}
String content = strBld.toString() ;
return new JSONObject().put("title" , title)
.put("text", content)
;
}
public static void main(String[] args) throws Exception
{
String appKey = "ddddddddddddddd" ;
String appSecret = "ssssssssssssssssssssssssssssssss" ;
String mobile = "130XXXXXXXXX" ;
String robotCode = "dingXXXXXXXXX" ;
// 1.获取AccessToken
HttpClient client = HttpClient.ofUrl(sDingService) ;
long expireTime = System.currentTimeMillis() ;
/**
* {
* "errcode": 0,
* "access_token": "aaaaaaaaaaaaaaaaa",
* "errmsg": "ok",
* "expires_in": 7200
* }
*/
JSONObject jo = client.askJo(Request.GET().path(sPath_GetToken)
.queryParam("appkey" , appKey)
.queryParam("appsecret", appSecret)) ;
System.out.println("获取到的Token:"+jo) ;
String accessToken = jo.optString("access_token") ;
expireTime += jo.optLong("expires_in") * 1000 ;
/**
* {
* "errcode": 0,
* "errmsg": "ok",
* "result":
* {
* "exclusive_account_userid_list": [],
* "userid": "bbbbbbbbbbbbb"
* },
* "request_id": "ccccccc"
* }
*/
// 2. 查询userId
jo = client.askJo(Request.POST().path(sPath_GetUserByMobile).queryParam("access_token" , accessToken)
.setJsonEntity(new JSONObject().put("mobile" , mobile)
.put("support_exclusive_account_search" , true))) ;
System.out.println("获取到的User信息:"+jo);
String userId = jo.pathString(null , "result" , "userid") ;
Letter letter = new Letter(null) ;
letter.setLevel(5);
letter.setContent("单聊测试") ;
letter.setEventTime(XTime.current$yyyyMMddHHmmss());
letter.setReduceAmount(1) ;
letter.setSendBatch("xxxxxxxxxxxxxxx") ;
letter.setSubscriberItemName("单聊测试订阅项");
String msgParam = toJSON(letter).toJSONString() ;
/**
* {
* "flowControlledStaffIdList": [],
* "invalidStaffIdList": [],
* "processQueryKey": "xxxxxxxxxxxxxx"
* }
*/
// 3.发送消息
jo = HttpClient.ofUrl(sDingSendService).askJo(Request.POST().path(sPath_SendMsgOfSingleChat)
.header("x-acs-dingtalk-access-token" , accessToken)
.setJsonEntity(new JSONObject().put("robotCode" , robotCode)
.put("userIds", new JSONArray().put(userId))
.put("msgKey", "sampleMarkdown")
.put("msgParam" , msgParam))) ;
System.out.println("发送消息收到的回复:"+jo);
}
}
效果: