C# 企業微信:開啓消息接受&接收消息&推送消息

前言:微信吧!接觸的人都會100%各種踩坑,就算同樣東西去年做過,今年來一樣踩坑,因爲太多你稍微不記得一點點的細節就能讓你研究N久。爲此,我要把這個過程詳細的記錄下來。

 

一、開啓消息接受


 1.拿到企業corpId,應用的Token,EncodingAESKey

2.這界面先別關,拿到 Token,EncodingAESKey後,建個接口

鑑於公司系統的架構類型,我這裏創建的是一個aspx文件,代碼如下:

public partial class request_WxMsgApi : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //開啓消息接受
        if (Request.HttpMethod.ToUpper() == "GET")
        {
            string signature = HttpContext.Current.Request.QueryString["msg_signature"];
            string timestamp = HttpContext.Current.Request.QueryString["timestamp"];
            string nonce = HttpContext.Current.Request.QueryString["nonce"];
            string echostr = HttpContext.Current.Request.QueryString["echostr"];
            string decryptEchoString = "";
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt("your token", "your EncodingAESKey", System.Configuration.ConfigurationManager.AppSettings["Corpid"]);
            int ret = wxcpt.VerifyURL(signature, timestamp, nonce, echostr, ref decryptEchoString);
            if (ret != 0)
            {
                //有錯誤的話記錄日誌
                //WriteLogFile("ERR: VerifyURL fail, ret: " + ret);
            }
            HttpContext.Current.Response.Write(decryptEchoString);
            HttpContext.Current.Response.End();
            return;
        }
}
}

注意:WXBizMsgCrypt類和Cryptography類,到微信官方下載即可鏈接

3.寫完代碼,將文件更新到服務器,讓這個 aspx文件能外網訪問。然後再在

把這個aspx文件的鏈接填上去,若能正常返回,這裏就會保存成功,若不能那就得再去補坑了....

 

二、接收消息


上面已經與微信那邊打通了接口,接下來就是要正真接受消息了。開啓消息是get請求,而正式使用接受消息則微信是post數據過來,所以  接口打通之後上面那些代碼就沒用了,因爲數據傳輸模式和處理模式都不一樣了

我這裏的接收消息,會把各種類型的文件存到數據庫或者服務器,非文本的則存到服務器,放個路徑到數據庫

代碼如下:

public partial class request_WxMsgApi : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        byte[] btHtml = Request.BinaryRead(Request.ContentLength);
        string strHtml = System.Text.Encoding.Default.GetString(btHtml);

        //接受消息
        if (Request.HttpMethod.ToUpper() == "POST")
        {
            string token = "your token";//從配置文件獲取Token
            string encodingAESKey = "your EncodingAESKey";//從配置文件獲取EncodingAESKey
            string corpId = System.Configuration.ConfigurationManager.AppSettings["corpid"];//從配置文件獲取corpId

            string signature = HttpContext.Current.Request.QueryString["msg_signature"];
            string timestamp = HttpContext.Current.Request.QueryString["timestamp"];
            string nonce = HttpContext.Current.Request.QueryString["nonce"];
            string decryptEchoString = "";

            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(token, encodingAESKey, corpId);
            int ret = wxcpt.DecryptMsg(signature, timestamp, nonce, strHtml, ref decryptEchoString);
            if (ret == 0)
            {
                //WriteLogFile("ERR: VerifyURL fail, ret: " + ret);
                if (!string.IsNullOrEmpty(decryptEchoString))
                {
                    try
                    {
                        XmlDocument doc = new XmlDocument();
                        doc.LoadXml(decryptEchoString);
                        XmlNode root = doc.FirstChild;
                        var msgType = root["MsgType"].InnerText;//voice(MediaId),video(MediaId),text(Content),image(PicUrl),
                        if (msgType == "voice" || msgType == "video" || msgType == "text" || msgType == "image")
                        {
                            var msgId = root["MsgId"].InnerText;
                            var fromuser = root["FromUserName"].InnerText;
                            var timesend = root["CreateTime"].InnerText;//時間戳
                            DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
                            long lTime = long.Parse(timesend + "0000000");
                            TimeSpan toNow = new TimeSpan(lTime);
                            var cTime = dtStart.Add(toNow);
                            var content = "";

                            switch (msgType)
                            {
                                case "voice":
                                    content = root["MediaId"].InnerText;
                                    break;
                                case "video":
                                    content = root["MediaId"].InnerText;
                                    break;
                                case "text":
                                    content = root["Content"].InnerText;
                                    break;
                                case "image":
                                    content = root["PicUrl"].InnerText;
                                    break;
                                default:
                                    break;
                            }
                            string sql = "insert into T_CmpWxMsg([MsgId],[MsgType],[FromUser],[CreateTime],[Content]) values(@MsgId,@MsgType,@FromUser,@CreateTime,@Content)";
                            DataHelper.ExecuteNonQuery(sql, new System.Data.SqlClient.SqlParameter[]
                            {
                                new System.Data.SqlClient.SqlParameter("@MsgId", msgId),
                                new System.Data.SqlClient.SqlParameter("@MsgType", msgType),
                                new System.Data.SqlClient.SqlParameter("@FromUser", fromuser),
                                new System.Data.SqlClient.SqlParameter("@CreateTime", cTime),
                                new System.Data.SqlClient.SqlParameter("@Content", content)
                            }, conString);
                            //WriteLogFile("存入數據庫成功" + cTime);

                            //異步任務-檢索未下載的媒體文件
                            System.Threading.Tasks.Task.Factory.StartNew(() =>
                            {
                                //WriteLogFile("異步任務開始");
                                try
                                {
                                    //拉取媒體源文件
                                    string sql_ = "select ID,Content,MsgType from T_CmpWxMsg WHERE ISNULL(MediaSavePath,'')='' and MsgType in ('voice','video')";
                                    var mediaList = DataOperation.DataCenter.ExecuteReader(sql_, Base.ConString, new object[] { });
                                    foreach (var item in mediaList)
                                    {
                                        string corpsecret = System.Configuration.ConfigurationManager.AppSettings["corpsecret"];//你的應用對應的secrect
                                        string tocken = Base.GetCorpToken(corpsecret, corpId).Access_Token;//拿取tocken,注意有效時間,最好用緩存控制
                                        string url = string.Format("https://qyapi.weixin.qq.com/cgi-bin/media/get?access_token={0}&media_id={1}", tocken, item.Content);

                                        string upfile = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, @"file\wxMaterial");
                                        if (!System.IO.Directory.Exists(upfile))
                                            System.IO.Directory.CreateDirectory(upfile);

                                        string filePath = upfile + "\\" + item.Content + (item.MsgType == "voice" ? ".amr" : ".mp4");
                                        WebClient client = new WebClient();
                                        client.DownloadFile(url, filePath);

                                        //更新存儲的物理路徑
                                        string updatesql = "update T_CmpWxMsg set MediaSavePath = '" + (@"\file\wxMaterial\" + item.Content + (item.MsgType == "voice" ? ".amr" : ".mp4")) + "' where ID='" + item.ID + "'";
                                        DataHelper.ExecuteNonQuery(updatesql, Base.ConString);
                                    }
                                }
                                catch (Exception ex) {
                                    //WriteLogFile("異步任務執行出錯:" + ex.Message);
                                }
                            });
                        }
                    }
                    catch (Exception ex)
                    {
                       // WriteLogFile("程序異常:" + ex.Message);
                    }
                    finally
                    {
                        //WriteLogFile("解密消息內容:" + decryptEchoString);
                        HttpContext.Current.Response.Write(decryptEchoString);
                        HttpContext.Current.Response.End();
                    }
                }
            }
        }
    }
}

注意:這裏用到的WXBizMsgCrypt類,在上面有提到可以到官方下載。

 

三、發送消息


string msg = "你好!<a href=\"https://blog.csdn.net/u012847695/article/details/102936505\">點這裏查看</a>";
//按部門發送
//item = new { toparty = "438|439|471", msgtype = "text", agentid = "8", text = new { content = msg }, safe = "0" };
//按人發送
dynamic item = new { touser = "wanger|liuer", msgtype = "text", agentid = "你的應用對應的agentid", text = new { content = msg }, safe = "0" };
var body = Base.DataToJson(item);
var corpsecret = System.Configuration.ConfigurationManager.AppSettings["corpsecret"];
string tocken = Base.GetCorpToken(corpsecret).Access_Token;//獲取token,注意有效時間,可用緩存控制
string url = string.Format("https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={0}", tocken);
var result = Base.InfoPost(url, body);//post request 請求
JavaScriptSerializer js = new JavaScriptSerializer();
IDictionary obj = js.DeserializeObject(result) as IDictionary;

post請求代碼

 public static string InfoPost(string url, string body)
    {
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
        request.Timeout = 30000;//30秒
        request.Method = "POST";
        byte[] payload = System.Text.Encoding.UTF8.GetBytes(body);
        Stream writer = request.GetRequestStream();
        writer.Write(payload, 0, payload.Length);
        writer.Close();
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8"));
        var result = reader.ReadToEnd();
        return result;
    }

下次來寫個支付的,自己寫的看得懂點,不然每次才坑都要各種百度查資料

以上純屬個人獨自研究成果,僅供參考,轉載請註明出處

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章