钉钉发送消息(非群机器人)
保姆式记录,亲测
一、钉钉的准备工作
首先进入钉钉的开发者后台 https://open.dingtalk.com/
应用开发—> 企业应用开发
进入之后选择创建应用
小程序和h5微应用都可以。这里只是把他们作为一个载体,只需要他们的一些对应信息就可以了,不需要前端进行开发对应的应用,如果前端想开发那也可以。
接下来就是点击自己创建的应用
最重要的就是下面的三个参数
AgentId
AppKey
AppSecret
这里的服务器出口ip地址,就是你本地服务器的公网地址,如果是本地测试不知道的话,后面调用钉钉接口,获得access_token 时候,会报错(某某地址不是白名单ip,这是你把他提示的地址放在下面就好了)
然后就是下面的权限管理
一般是全部员工,然后,你想调用那个接口就申请那个权限。如果你不知道申请那个权限可以再他的官方文档里找,那里有提示。
(建议不管是新旧API,找到符合你需求的即可)
因为这里是做的发送消息通知,那么就需要通讯录的权限,找到通讯录,把需要的都选了。
二、开发的准备工作
-
pom的导入 <!-- 钉钉 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dingtalk</artifactId>
<version>1.2.15</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>alibaba-dingtalk-service-sdk</artifactId>
<version>2.0.0</version>
</dependency>
-
配置文件(yml配置文件) dingtalk:
agentId: 146xxxcs
appKey: dingwxsssdcs
appSecret: jHsdsBvsdsdsdccccsss
这里需要的参数,在前面已经说了再那里找 -
配置类
@Data
@Configuration
@ConfigurationProperties(prefix="dingtalk")
public class DingTalkProperties {
private String agentId;
private String appKey;
private String appSecret;
}
-
工具类
-
首先获得对应的access_token
@Slf4j
@Component
@AllArgsConstructor
public class DingTalkUtil {
private final DingTalkProperties dingTalkProperties;
public String getAccessToken() {
try {
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
OapiGettokenRequest request = new OapiGettokenRequest();
request.setAppkey(dingTalkProperties.getAppKey());
request.setAppsecret(dingTalkProperties.getAppSecret());
request.setHttpMethod("GET");
OapiGettokenResponse response = client.execute(request);
return response.getAccessToken();
} catch (ApiException e) {
log.error("请求获取钉钉的access_token失败:{}", e.getErrMsg());
}
return null;
}
-
根据这个access_token就是获得了对应的接口凭证,现在根据api 根据用户电话获得钉钉的userId
public String getDingTalkUserId(String phone) {
String accessToken = this.getAccessToken();
if (accessToken == null) {
throw new CiErrorException(63001, "钉钉出现异常,没有获取到对应的access_token,请联系管理员进行检查!");
}
try {
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getbymobile");
OapiV2UserGetbymobileRequest req = new OapiV2UserGetbymobileRequest();
req.setMobile(phone);
OapiV2UserGetbymobileResponse rsp = client.execute(req, accessToken);
String userId = rsp.getResult().getUserid();
return userId;
} catch (ApiException e) {
log.error("请求获取钉钉用户的userid失败:{}", e.getErrMsg());
}
return null;
}
-
根据userId可以发送消息 这里采用的是工作消息(消息类型是oa)
public void sendDingTalkMsg(String userIdList, MsgVO msgVO) {
String accessToken = this.getAccessToken();
if (accessToken == null) {
throw new CiErrorException(63001, "钉钉出现异常,没有获取到对应的access_token,请联系管理员进行检查!");
}
try {
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
OapiMessageCorpconversationAsyncsendV2Request req = new OapiMessageCorpconversationAsyncsendV2Request();
req.setAgentId(Long.parseLong(dingTalkProperties.getAgentId()));
req.setUseridList(userIdList);
OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
msg.setMsgtype("oa");
OapiMessageCorpconversationAsyncsendV2Request.OA oa = new OapiMessageCorpconversationAsyncsendV2Request.OA();
oa.setPcMessageUrl(msgVO.getPcMessageUrl());
oa.setMessageUrl(msgVO.getMessageUrl());
OapiMessageCorpconversationAsyncsendV2Request.Body body = new OapiMessageCorpconversationAsyncsendV2Request.Body();
body.setAuthor("xxxx");
body.setTitle(msgVO.getTitle());
body.setForm(this.setMsgForm(msgVO.getFormVOList()));
oa.setBody(body);
OapiMessageCorpconversationAsyncsendV2Request.StatusBar statusBar = new OapiMessageCorpconversationAsyncsendV2Request.StatusBar();
statusBar.setStatusBg("0xFFF65E5E");
statusBar.setStatusValue(msgVO.getStatusContent());
oa.setStatusBar(statusBar);
OapiMessageCorpconversationAsyncsendV2Request.Head head = new OapiMessageCorpconversationAsyncsendV2Request.Head();
head.setBgcolor("0xFFF65E5E");
oa.setHead(head);
msg.setOa(oa);
req.setMsg(msg);
OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(req, accessToken);
} catch (ApiException e) {
log.error("发送钉钉消息失败:{}", e.getErrMsg());
}
}
private List<OapiMessageCorpconversationAsyncsendV2Request.Form> setMsgForm(List<FormVO> list) {
List<OapiMessageCorpconversationAsyncsendV2Request.Form> formList = new ArrayList<>(7);
for (FormVO formVO : list) {
OapiMessageCorpconversationAsyncsendV2Request.Form form = new OapiMessageCorpconversationAsyncsendV2Request.Form();
form.setKey(formVO.getKey());
form.setValue(formVO.getValue());
formList.add(form);
}
return formList;
}
这里对应的vo
import lombok.Data;
@Data
public class FormVO {
private String key;
private String value;
}
import lombok.Data;
import java.util.List;
@Data
public class MsgVO {
private String messageUrl;
private String pcMessageUrl;
private String title;
private List<FormVO> formVOList;
private String statusContent;
}
-
然后只要调用这里面的发送消息的方法就可以了,但是必须满足对应的参数。 当前也可以使用其他方式的消息类型,我这边使用了最复杂的一个,因为业务需要。
三、总结
这里的所有方法都是从钉钉的调试里面进行修改的,可以直接现在钉钉的调试中进行调试,然后再把代码借鉴过来,然后进行修改,符合自己的需求就可以了。
(1)、获取企业内部的access_token https://open.dingtalk.com/document/orgapp-server/obtain-orgapp-token
(2)、根据用户phone获得userId https://open.dingtalk.com/document/orgapp-server/query-users-by-phone-number
(3)、发送工作通知 https://open.dingtalk.com/document/orgapp-server/asynchronous-sending-of-enterprise-session-messages
消息类型 https://open.dingtalk.com/document/orgapp-server/message-types-and-data-format
一定要好好的阅读钉钉的接口文档,并且使用他们的原生方法,节省时间(自己能力不足,所以直接那人家的方法用)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ItIm7NeO-1645434398518)(C:\Users\Yuki\AppData\Roaming\Typora\typora-user-images\image-20220221170307997.png)]
ment/orgapp-server/query-users-by-phone-number>
(3)、发送工作通知 https://open.dingtalk.com/document/orgapp-server/asynchronous-sending-of-enterprise-session-messages
消息类型 https://open.dingtalk.com/document/orgapp-server/message-types-and-data-format
一定要好好的阅读钉钉的接口文档,并且使用他们的原生方法,节省时间(自己能力不足,所以直接那人家的方法用)
注意: 这里的消息不会发送重复消息,比如你把一条消息发给三个人,但是你在把这样的消息发给其他的四个人,那么这后面的四个人是收不到消息的,因为钉钉任务你在发送重复消息。
资源连接 https://download.csdn.net/download/zhuwenaptx/81739940
|