工作中有個(gè)需求,是要把錄入的銷售機(jī)會(huì)由系統(tǒng)自動(dòng)分配給銷售,然后對(duì)接釘釘給銷售人員發(fā)送企業(yè)消息,通知他進(jìn)行跟單。
參考資料
1. 獲取Access_Token
Access_Token是企業(yè)訪問(wèn)釘釘開(kāi)放平臺(tái)全局接口的唯一憑證,即調(diào)用接口時(shí)需攜帶Access_Token。
對(duì)于企業(yè)接入來(lái)說(shuō),AccessToken需要用CorpID和CorpSecret來(lái)?yè)Q取,CorpID是企業(yè)在釘釘中的標(biāo)識(shí);每個(gè)企業(yè)擁有一個(gè)唯一的CorpID,CorpSecret是企業(yè)每個(gè)微應(yīng)用的憑證密鑰。
注意:token 一段時(shí)間后會(huì)刷新,因此必須實(shí)時(shí)動(dòng)態(tài)獲取。
獲取方式:token獲取方式
2. 創(chuàng)建微應(yīng)用
比如發(fā)送企業(yè)消息,需要?jiǎng)?chuàng)建微應(yīng)用,獲取agent_id,步驟如下:
- 登錄OA,點(diǎn)擊工作臺(tái),選擇『自建應(yīng)用』
20180326152204804041237.png -
進(jìn)行微應(yīng)用內(nèi)容的設(shè)置,獲取agent_id
20180326152204828144931.png
3. 根據(jù)需求調(diào)用對(duì)應(yīng)的API
4. 編寫釘釘工具類
package com.yuxin.wx.util;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.CorpMessageCorpconversationAsyncsendRequest;
import com.dingtalk.api.response.CorpMessageCorpconversationAsyncsendResponse;
import com.taobao.api.ApiException;
import com.yuxin.wx.model.user.Users;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @Description:對(duì)接釘釘?shù)墓ぞ哳?* @Authod:zhang_cq
* @Date:2018/3/19 下午2:59
*/
public class DingDingUtil {
private static String CORPID = "Xxx"; // 企業(yè)Id
private static String CORPSECRET = "Xxx"; // 企業(yè)應(yīng)用的憑證密鑰
public static Long AGENTID = 1677000L; // 自動(dòng)分配微應(yīng)用的ID
/**
* @Description:獲得token
* @Method:getToken
* @Authod:zhang_cq
* @Date:2018/3/19 下午3:00
* @param corpid 企業(yè)Id
* @param corpsecret 企業(yè)應(yīng)用的憑證密鑰
*/
private static String getToken(String corpid, String corpsecret){
try {
String result = ClientUtil.sendGet("https://oapi.dingtalk.com/gettoken?corpid="+ corpid + "&corpsecret=" + corpsecret);
JSONObject json = JSONObject.fromObject(result);
if (json != null && "0".equals(json.get("errcode").toString())) {
return json.get("access_token").toString();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* @Description:發(fā)送消息
* @Method:sendDDMessage
* @Authod:zhang_cq
* @Date:2018/3/19 下午4:55
* @param agentId 微應(yīng)用的ID
* @param userId 接收者的用戶userid列表
* @param msgcontent 消息內(nèi)容
*/
public static JSONObject sendDDMessage(Long agentId, String userId, String msgcontent) {
DingTalkClient client = new DefaultDingTalkClient("https://eco.taobao.com/router/rest");
CorpMessageCorpconversationAsyncsendRequest req = new CorpMessageCorpconversationAsyncsendRequest();
req.setMsgtype("oa"); // 消息類型
req.setAgentId(agentId);
req.setUseridList(userId);
req.setToAllUser(false); // 是否發(fā)送給企業(yè)全部用戶
req.setMsgcontentString(msgcontent);
try {
String token = getToken(CORPID,CORPSECRET);
CorpMessageCorpconversationAsyncsendResponse rsp = client.execute(req, token);
JSONObject json = JSONObject.fromObject(rsp.getResult());
if (json != null) {
return json;
}
} catch (ApiException e) {
e.printStackTrace();
}
return null;
}
/**
* @Description:根據(jù)部門ID獲取用戶信息
* @Method:getDDUsersByDeptId
* @Authod:zhang_cq
* @Date:2018/3/20 上午11:19
* @param departmentId
*/
public static List<Users> getDDUsersByDeptId(Long departmentId){
try {
String accessToken = getToken(CORPID,CORPSECRET);
String result = ClientUtil.sendGet("https://oapi.dingtalk.com/user/list?access_token="+accessToken+"&department_id=" + departmentId);
JSONObject json = JSONObject.fromObject(result);
if (json != null && "0".equals(json.get("errcode").toString())) {
JSONArray userlist = JSONArray.fromObject((json.get("userlist")));
if (userlist != null && userlist.size() > 0) {
List<Users> userList = new ArrayList<Users>();
for(int i=0;i<userlist.size();i++){
JSONObject user = userlist.getJSONObject(i);
String mobile = user.getString("mobile");
String userId = user.getString("userid");
String name = user.getString("name");
Users users = new Users();
if(!StringUtils.isBlank(mobile)){
users.setMobile(mobile);
users.setDDUserId(userId);
users.setRealName(name);
userList.add(users);
}
}
return userList;
}
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* @Description:根據(jù)部門ID獲取用戶信息(userid和name)
* @Method:getDDSimpleUsersByDeptId
* @Authod:zhang_cq
* @Date:2018/3/20
* @param accessToken
* @param departmentId
*/
public static void getDDSimpleUsersByDeptId(String accessToken, Long departmentId){
try {
String result = ClientUtil.sendGet("https://oapi.dingtalk.com/user/simplelist?access_token="+accessToken+"&department_id=" + departmentId);
JSONObject json = JSONObject.fromObject(result);
if (json != null && "0".equals(json.get("errcode").toString())) {
JSONArray userlist = JSONArray.fromObject((json.get("userlist")));
if (userlist != null && userlist.size() > 0) {
for(int i=0;i<userlist.size();i++){
JSONObject user = userlist.getJSONObject(i);
String name = user.getString("name");
String userId = user.getString("userid");
System.out.println(name + ":" + userId);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @Description:獲取員工的打卡記錄
* @Method:getRecordInfo
* @Authod:zhang_cq
* @Date:2018/3/21 下午5:42
* @param checkDateFrom 查詢考勤打卡記錄的起始工作日
* @param checkDateTo 查詢考勤打卡記錄的結(jié)束工作日。注意,起始與結(jié)束工作日最多相隔7天
*/
private static String getRecordInfo(String userId, String checkDateFrom, String checkDateTo){
try {
String token = getToken(CORPID,CORPSECRET);
Map<String, String> data = new HashMap<String, String>();
data.put("userIds","["+userId+"]");
data.put("checkDateFrom",checkDateFrom);
data.put("checkDateTo",checkDateTo);
JSONObject dataJson = JSONObject.fromObject(data);
String result = sendHttpPost("https://oapi.dingtalk.com/attendance/listRecord?access_token="+token,dataJson.toString());
System.out.println(result);
JSONObject json = JSONObject.fromObject(result);
if (json != null && "0".equals(json.get("errcode").toString())) {
JSONArray recordresult = JSONArray.fromObject((json.get("recordresult")));
if (recordresult != null && recordresult.size() > 0) {
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String sendHttpPost(String url, String body) throws Exception {
String result = null;
HttpClient client = HttpClients.createDefault();
URIBuilder builder = new URIBuilder();
try {
HttpPost post = new HttpPost(url);
//設(shè)置請(qǐng)求頭
post.setHeader("Content-Type", "application/json");
//設(shè)置請(qǐng)求體
post.setEntity(new StringEntity(body));
//獲取返回信息
HttpResponse response = client.execute(post);
HttpEntity entity = response.getEntity();
if (entity != null) {
entity = new BufferedHttpEntity(entity);
InputStream in = entity.getContent();
byte[] read = new byte[1024];
byte[] all = new byte[0];
int num;
while ((num = in.read(read)) > 0) {
byte[] temp = new byte[all.length + num];
System.arraycopy(all, 0, temp, 0, all.length);
System.arraycopy(read, 0, temp, all.length, num);
all = temp;
}
result = new String(all,"UTF-8");
if (null != in) {
in.close();
}
}
return result;
} catch (Exception e) {
System.out.println("接口請(qǐng)求失敗"+e.getStackTrace());
}
return result;
}
public static String doPost(String url, JSONObject jsonObject, String charset){
HttpClient httpClient = null;
HttpPost httpPost = null;
String result = null;
try{
httpClient = HttpClients.createDefault();
httpPost = new HttpPost(url);
//設(shè)置參數(shù)
List<NameValuePair> list = new ArrayList<NameValuePair>();
StringEntity entity = new StringEntity(jsonObject.toString(),charset);
entity.setContentEncoding("UTF-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost);
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity resEntity = response.getEntity();
if(resEntity != null){
result = EntityUtils.toString(resEntity,charset);
}
}
}catch(Exception ex){
ex.printStackTrace();
}
return result;
}
/**
* @Description:銷售是否上班打卡
* @Method:getSignInInfo
* @Authod:zhang_cq
* @Date:2018/3/22 上午10:08
*/
public static Boolean getSignInInfo(String userId){
String token = getToken(CORPID,CORPSECRET);
String recordUrl = "https://oapi.dingtalk.com/attendance/list?access_token=" + token;
JSONObject jsonObject = new JSONObject();
jsonObject.put("workDateFrom","2018-03-21 06:00:00");
jsonObject.put("workDateTo","2018-03-21 19:00:00");
List<String> usersList = new ArrayList<String>();
usersList.add(userId);
jsonObject.put("userIdList",usersList);
jsonObject.put("offset",0);
jsonObject.put("limit",1);
String result = doPost(recordUrl,jsonObject,"utf-8");
JSONObject resutJSON = jsonObject.fromObject(result);
String msg = (String)resutJSON.get("errmsg");
if("ok".equals(msg)){
JSONArray jsonArray = JSONArray.fromObject(resutJSON.get("recordresult"));
if (jsonArray != null && jsonArray.size() > 0) {
JSONObject recordInfo = JSONObject.fromObject(jsonArray.get(0));
String checkType = recordInfo.get("checkType").toString();
if("OnDuty".equals(checkType)){
return true;
}
//System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(time))); // 上班打卡時(shí)間
}
}
return false;
}
// 測(cè)試主方法
public static void main(String[] args) {
//String msgcontent = "{\"message_url\": \"http://dingtalk.com\",\"head\": {\"bgcolor\": \"FFBBBBBB\",\"text\": \"頭部標(biāo)題\"},\"body\": {\"title\": \"正文標(biāo)題\",\"form\": [{\"key\": \"姓名:\",\"value\": \"張三\"},{\"key\": \"愛(ài)好:\",\"value\": \"打球、聽(tīng)音樂(lè)\"}],\"rich\": {\"num\": \"15.6\",\"unit\": \"元\"},\"content\": \"大段文本大段文本大段文本大段文本大段文本大段文本大段文本大段文本大段文本大段文本大段文本大段文本\",\"image\": \"@lADOADmaWMzazQKA\",\"file_count\": \"3\",\"author\": \"李四 \"}}";
//String msgcontent = "{\"message_url\": \"http://qixiantong.info\",\"head\": {\"bgcolor\": \"FFBBBBBB\",\"text\": \"頭部標(biāo)題\"},\"body\": {\"title\": \"銷售機(jī)會(huì)自動(dòng)分配\",\"form\": [{\"key\": \"公司名稱:\",\"value\": \"騰訊\"}],\"content\": \"您的銷售機(jī)會(huì)已分配,請(qǐng)擼起袖子抓緊干吧!\",\"image\": \"http://upload-images.jianshu.io/upload_images/763193-c46dd76b34b3d1cb.JPG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240\",\"author\": \"云朵課堂 \"}}";
//sendDDMessage(AGENTID,"manager4807","",msgcontent);
getSignInInfo("071323270524189541");
}
}
5. 分配成功后的調(diào)用
// 釘釘通知銷售
String DDUserid = sales.getDDUserId();
if(!org.apache.commons.lang.StringUtils.isBlank(DDUserid)){
String toUrl = ""; // 點(diǎn)擊查看詳情跳轉(zhuǎn)的路徑
String companyName = cCompany.getCompanyName()==null?"":cCompany.getCompanyName();
String msgcontent = "{\"message_url\": \""+toUrl+"\",\"head\": {\"bgcolor\": \"FFBBBBBB\",\"text\": \"頭部標(biāo)題\"},\"body\": {\"title\": \"銷售機(jī)會(huì)自動(dòng)分配\",\"form\": [{\"key\": \"公司名稱:\",\"value\": \""+companyName+"\"}],\"content\": \"您的銷售機(jī)會(huì)已分配,請(qǐng)擼起袖子抓緊干吧!\",\"image\": \"\",\"author\": \"云朵課堂 \"}}";
JSONObject json = DingDingUtil.sendDDMessage(DingDingUtil.AGENTID,DDUserid,msgcontent);
if (json != null) {
if (!"true".equals(json.get("success").toString())){
logger.info("自動(dòng)分配釘釘通知銷售人員失敗,失敗原因:" + json.get("errorMsg").toString());
}
}
}

