C#+ashx+Js 获取钉钉个人对话ID进行发送消息
Aspx页面:
1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebTestDingTalkApi.WebForm1" %> 2 3 <!DOCTYPE html> 4 5 <html xmlns="http://www.w3.org/1999/xhtml"> 6 <head runat="server"> 7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 8 <title></title> 9 <script src="jquery-1.8.2.min.js"></script> 10 <script type="text/javascript" src="http://g.alicdn.com/dingding/open-develop/1.6.9/dingtalk.js"></script> 11 <script src="app.js"></script> 12 <script> 13 //获取会话ID只能用一次 14 var cid = ''; 15 var fnReady = $(function () 16 { 17 var fnError = function () { 18 alert("鉴权失败"); 19 }; 20 var jsApiList = ["biz.chat.pickConversation", "biz.chat.chooseConversationByCorpId", "biz.chat.toConversation"]; 21 22 global.configJsSdk(jsApiList, fnReady, fnError); 23 }); 24 </script> 25 </head> 26 <body> 27 <form id="form1" runat="server"> 28 <div> 29 <asp:Button ID="btnGroupSend" runat="server" Text="群消息发送" OnClick="btnGroupSend_Click" /> 30 <asp:Button ID="btnFtFSend" runat="server" Text="部门群组、单个人消息发送" OnClick="btnFtFSend_Click" /> 31 <asp:Button ID="btnPtSend" runat="server" Text="普通会话消息发送" OnClick="btnPtSend_Click" /> 32 </div> 33 34 </form> 35 </body> 36 </html>
app.js代码:
1 var global = { 2 corpId: '', 3 configJsSdk: function (jsApiList, fnReady, fnError) { 4 /// <summary>配置微信的JSSDK</summary> 5 /// <param name="jsApiList" type="function">要请求的api列表,以['biz.chat.chooseConversationByCorpId','biz.chat.toConversation']的形式</param> 6 /// <param name="fnReady" type="function">dd.ready调用的函数</param> 7 /// <param name="fnError" type="function">dd.error调用的函数</param> 8 var url = window.location.href; 9 alert(url); 10 //从后台取出jsapi-oauth配置信息 11 var signRequest = { 12 url:"Handler1.ashx?jsapi-oauth=oauth&href=" + url, 13 type: 'GET', 14 dataType: 'json', 15 success: function (response, textStatus, jqXHR) { 16 //获取jsapi签名成功 17 if( response != null) 18 if (response.errcode =="OK" ) 19 { 20 try { 21 global.corpId = response.corpId; 22 const config = 23 { 24 agentId: response.agentId, 25 corpId: response.corpId, 26 timeStamp: response.timeStamp, 27 nonceStr: response.nonceStr, 28 signature: response.signature, 29 jsApiList: jsApiList 30 }; 31 32 dd.config(config); 33 // alert(JSON.stringify(config)); 34 dd.ready(function () 35 { 36 37 alert('ready'); 38 //根据corpid选择会话获取chatId 39 //dd.biz.chat.chooseConversationByCorpId( 40 // { 41 // corpId: 'dingb6aa72b99615cb3c', //企业id 42 // isConfirm: 'true', //是否弹出确认窗口,默认为true 43 // onSuccess: function (data) { 44 // alert(JSON.stringify(data)); 45 // }, 46 // onFail: function (err) { alert('dd error: ' + JSON.stringify(err)); } 47 // }); 48 //打开与某个用户的聊天页面(单聊会话) 49 //biz.chat.openSingleChat({ 50 // corpId: 'dingb6aa72b99615cb3c', // 企业id 51 // userId: 'xxx', // 用户的工号 52 // onSuccess: function () { }, 53 // onFail: function () { } 54 //}) 55 //会话信息 56 dd.biz.chat.pickConversation({ 57 corpId: global.corpId, //企业id 58 isConfirm:'false', //是否弹出确认窗口,默认为true 59 onSuccess: function (data) { 60 alert("获取"+data.cid); 61 $.ajax({ 62 type: "post", 63 url: "Handler1.ashx", 64 data: "FTTSendMessage=" + data.cid, 65 datatype: "json", 66 async: false, 67 success: function (msg, textstatus, xmlhttprequest) { 68 alert('会话 OK: ' + JSON.stringify(msg)); 69 }, 70 error: function (errorinfo) { 71 alert("会话错误。"); 72 } 73 }); 74 }, 75 onFail: function () { } 76 }); 77 ding消息 78 //dd.biz.ding.create({ 79 // users: ['121820590530614633'],// 用户列表,工号 80 // corpId: 'dingb6aa72b99615cb3c', // 企业id 81 // type: 1, // 附件类型 1:image 2:link 82 // alertType: 2, // 钉发送方式 0:电话, 1:短信, 2:应用内 83 // alertDate: { "format": "yyyy-MM-dd HH:mm", "value": "2017-09-24 08:00" }, 84 // attachment: { 85 // images: [''], 86 // }, // 附件信息 87 // text: '星期一开会讨论周发注事情', // 正文 88 // bizType: 0, // 业务类型 0:通知DING;1:任务;2:会议; 89 // confInfo: { 90 // bizSubType: 0, // 子业务类型如会议:0:预约会议;1:预约电话会议;2:预约视频会议;(注:目前只有会议才有子业务类型) 91 // location: '某某会议室', //会议地点;(非必填) 92 // startTime: { "format": "yyyy-MM-dd HH:mm", "value": "2017-09-24 08:00" },// 会议开始时间 93 // endTime: { "format": "yyyy-MM-dd HH:mm", "value": "2017-09-24 09:00" }, // 会议结束时间 94 // remindMinutes: 30, // 会前提醒。单位分钟-1:不提醒;0:事件发生时提醒;5:提前5分钟;15:提前15分钟;30:提前30分钟;60:提前1个小时;1440:提前一天; 95 // remindType: 2 // 会议提前提醒方式。0:电话, 1:短信, 2:应用内 96 // }, 97 98 // //taskInfo: { 99 // // ccUsers: ['100', '101'], // 抄送用户列表,工号 100 // // deadlineTime: { "format": "yyyy-MM-dd HH:mm", "value": "2015-05-09 08:00" }, // 任务截止时间 101 // // taskRemind: 30// 任务提醒时间,单位分钟0:不提醒;15:提前15分钟;60:提前1个小时;180:提前3个小时;1440:提前一天; 102 // //}, 103 104 // onSuccess: function (info) { 105 // alert('ding OK: ' + JSON.stringify(info)); 106 // //onSuccess将在点击发送之后调用 107 // }, 108 // onFail: function (err) { alert('ding error: ' + JSON.stringify(err)); } 109 //}) 110 111 }); 112 113 dd.error(function (err) { 114 if (err == null) { 115 alert('dd error: ' + JSON.stringify(err)); 116 } 117 else { 118 fnError(); 119 } 120 }); 121 } 122 catch (e) { 123 alert('dd error: ' + JSON.stringify(e)); 124 } 125 126 //global.corpId = response.corpId; 127 //const config = { 128 // agentId: response.agentId || '', 129 // corpId: corpId || '', 130 // timeStamp: response.timeStamp || '', 131 // nonceStr: response.nonceStr || '', 132 // signature: response.signature || '', 133 // jsApiList: jsApiList || [] 134 //}; 135 //dd.config(config); 136 //alert(JSON.stringify(config)); 137 //dd.ready(function () { 138 // if (fnReady != null) { 139 // fnReady(); 140 // } 141 //}); 142 //dd.biz.chat.chooseConversationByCorpId({ 143 // corpId: 'dingb6aa72b99615cb3c', //企业id 144 // // isConfirm:'true', //是否弹出确认窗口,默认为true 145 // onSuccess: function (data) { 146 // alert(JSON.stringify(data)); 147 // }, 148 // onFail: function () { } 149 //}); 150 151 //dd.error(function (err) { 152 // if (err == null) { 153 // alert('dd error: ' + JSON.stringify(err)); 154 // } 155 // else { 156 // fnError(); 157 // } 158 //}); 159 } 160 else//签名失败弹出提示信息 161 { 162 alert(JSON.stringify(response.errmsg) + 'sign'); 163 } 164 }, 165 error: function () { 166 167 } 168 }; 169 $.ajax(signRequest); 170 } 171 172 }
config 配置钉钉公司开放账号、密匙和应用ID
1 <?xml version="1.0" encoding="utf-8"?> 2 <!-- 3 有关如何配置 ASP.NET 应用程序的详细信息,请访问 4 https://go.microsoft.com/fwlink/?LinkId=169433 5 --> 6 <configuration> 7 <!-- 8 有关 web.config 更改的说明,请参见 http://go.microsoft.com/fwlink/?LinkId=235367。 9 10 可在 <httpRuntime> 标记上设置以下特性。 11 <system.Web> 12 <httpRuntime targetFramework="4.5.1" /> 13 </system.Web> 14 --> 15 <system.web> 16 <compilation targetFramework="4.6.1" /> 17 <httpRuntime /> 18 <pages controlRenderingCompatibilityVersion="4.0" /> 19 </system.web> 20 <appSettings> 21 <!--自己在钉钉创建应用的名义发送消息--> 22 <add key="AgentID" value="12646174893" /> 23 <!--钉钉中接收的部门id--> 24 <add key="DeptID" value="2542023339" /> 25 <!--钉钉中公司开发者账号及密匙--> 26 <add key="CorpID" value="34aa72b99615cb3c" /> 27 <add key="CorpSecret" value="344i6cKV1ZddUREwg3rK454545N_y8u4W_gl1IQfF3JKBcCi" /> 28 </appSettings> 29 </configuration>
一般处理程序 handler C#代码:
1 using Newtonsoft.Json; 2 using System; 3 using System.Web; 4 using System.Web.Script.Serialization; 5 using static WebTestDingTalkApi.ApiTool; 6 7 namespace WebTestDingTalkApi 8 { 9 /// <summary> 10 /// Handler1 的摘要说明 11 /// </summary> 12 public class Handler1 : IHttpHandler 13 { 14 15 public void ProcessRequest(HttpContext context) 16 { 17 context.Response.ContentType = "text/plain"; 18 if (!string.IsNullOrEmpty(context.Request["jsapi-oauth"])&& !string.IsNullOrEmpty(context.Request["href"])) 19 { 20 if (!false && AccessToken.Begin.AddSeconds(ConstVars.CACHE_TIME) >= DateTime.Now) 21 {//没有强制更新,并且没有超过缓存时间 22 return; 23 } 24 //string CorpID = ConfigHelper.FetchCorpID(); 25 //string CorpSecret = ConfigHelper.FetchCorpSecret(); 26 //string TokenUrl = Urls.gettoken; 27 //string apiurl = $"{TokenUrl}?{Keys.corpid}={CorpID}&{Keys.corpsecret}={CorpSecret}"; 28 //TokenResult tokenResult = Analyze.Get<TokenResult>(apiurl); 29 //if (tokenResult.ErrCode == ErrCodeEnum.OK) 30 //{ 31 // AccessToken.Value = tokenResult.Access_token; 32 // AccessToken.Begin = DateTime.Now; 33 //} 34 #region //旧的测试 35 var nonceStr = Guid.NewGuid().ToString(); 36 var timeStamp = DingTalkAuth.GetTimeStamp(); 37 //获取jsapi_ticket 38 var sign = string.Empty; 39 ApiTool.EndUpdateAccessToken(false); 40 string apiurl = $"{Urls.get_jsapi_ticket}?{Keys.access_token}={AccessToken.Value}"; 41 42 var result = Analyze.Get<SendMessageResult>(apiurl); 43 JavaScriptSerializer js = new JavaScriptSerializer(); 44 dynamic modelDy = js.Deserialize<dynamic>(result.Json); //反序列化 45 //进行JS-API权限签名获取signature 时间戳等 46 var signature = DingTalkAuth.GetGenSigurate(nonceStr, timeStamp, modelDy["ticket"], "http://open.dingtalk.com", ref sign); 47 // 这里参数的顺序要按照 key 值 ASCII 码升序排序 48 string rawstring = $"{Keys.jsapi_ticket}=" + modelDy["ticket"] 49 + $"&{Keys.noncestr}=" + nonceStr 50 + $"&{Keys.timestamp}=" + DingTalkAuth.GetTimeStamp() 51 + $"&{Keys.url}=" + context.Request["href"]; 52 var config = new 53 { 54 agentId = ConfigHelper.FetchAgentID(), 55 corpId = ConfigHelper.FetchCorpID(), 56 timeStamp = DingTalkAuth.GetTimeStamp(), 57 nonceStr = nonceStr, 58 signature = sign, 59 errcode= modelDy["errcode"], 60 errmsg= modelDy["errmsg"], 61 url = context.Request["href"], 62 rawstring = rawstring, 63 jsticket = modelDy["ticket"] 64 }; 65 #endregion 66 // string json = JsonConvert.SerializeObject(config); 67 var hh = SignPackageHelper.FetchSignPackage(//"http://localhost:63079/WebForm1.aspx", 68 context.Request["href"], 69 SignPackageHelper.FetchJSTicket()); 70 string json = js.Serialize(hh); 71 context.Response.Write(json); 72 } 73 //员工可以在微应用中把消息发送到同企业的人或群,消息发送管理是个人向个人或者群发送,发送普通消息需要的 74 //cid和群消息的chatid不一样,(通过JSAPI之pickConversation接口唤起联系人界面选择之后即可拿到会话cid,之//后您可以使用获取到的cid调用此接口)。 75 if (!string.IsNullOrEmpty(context.Request["FTTSendMessage"])) 76 { 77 var txtmsg = new 78 { 79 sender = "01276230686802",//消息发送者员工ID 80 cid = context.Request["FTTSendMessage"],//群消息或者个人聊天会话Id 81 msgtype = MsgType.text.ToString(), 82 text = new 83 { 84 content = "hello" 85 } 86 }; 87 string apiurl = ApiTool.FormatApiUrlWithToken(Urls.conversation_message_send); 88 string json = JsonConvert.SerializeObject(txtmsg); 89 var result = Analyze.Post<SendMessageResult>(apiurl, json); 90 context.Response.Write(result); 91 } 92 } 93 94 public bool IsReusable 95 { 96 get 97 { 98 return false; 99 } 100 } 101 } 102 }