[WeChatBot]接收與回應

上篇已經將接收API功能開啟後,我們要來撰寫如何接收回應了。


 

微信企業的接收訊息為POST請求,他會夾代 timestamp,msg_signature,nonce 

詳細請看文件。

posModel 是 Senparc.Weixin.Work  事前寫好的一個模組,繼承了EncryptPostModel

因此我們要告訴他 我們分別的 timestamp,msg_signature,nonce 為何並set進去

   [HttpPost]
        public HttpResponseMessage Post()
        {        

            var requestQueryPairs = Request.GetQueryNameValuePairs().ToDictionary(k => k.Key, v => v.Value);
            if (requestQueryPairs.Count == 0
                || !requestQueryPairs.ContainsKey("timestamp")
                || !requestQueryPairs.ContainsKey("msg_signature")
                || !requestQueryPairs.ContainsKey("nonce"))
            {
                return Request.CreateErrorResponse(HttpStatusCode.Forbidden, "未授權請求");
            }
          
            PostModel postModel = new PostModel
            {
                Msg_Signature = requestQueryPairs["msg_signature"],
                Timestamp = requestQueryPairs["timestamp"],
                Nonce = requestQueryPairs["nonce"],
                Token = token,
                EncodingAESKey = encodingAESKey,//根据自己后台的设置保持一致
                CorpId = corpId//根据自己后台的设置保持一致
            };
            //v4.2.2之後的版本,可以設置每個人上下文消息儲存的最大數量,防止內存佔用過多,如果該參數小於等於0,則不限制
            var maxRecordCount = 0;           

            //自定義MessageHandler,對微信請求的詳細判斷操作都在這裏面。  

            var messageHandler = new CustomMessageHandler(HttpContext.Current.Request.InputStream, postModel, maxRecordCount);

            try
            {
                /* 如果需要添加消息去重功能,只需打開OmitRepeatedMessage功能,SDK會自動處理。
                 * 收到重複消息通常是因為微信服務器沒有及時收到響應,會持續發送2-5條不等的相同內容的RequestMessage*/
                //messageHandler.OmitRepeatedMessage = true;

                //執行微信處理過程
                messageHandler.Execute();   

                var resMessage = Request.CreateResponse(HttpStatusCode.OK);

                resMessage.Content = new StringContent(messageHandler.FinalResponseDocument.ToString());

                

CustomMessageHandler 為自定義的類別,這邊 HttpContext.Current.Request.InputStream 則是Senparc.Weixin.Work 之前繼承 WorkMessageHandler

所寫的其中一個建構子函數,在webApi 中 我們所需的body.requeset 需要利用這個 HttpContext.Current.Request.InputStream (這邊搞了很久)

當程式跑到自訂義的CustomMessageHandler時,若無錯誤他會自行跑去相對應的OnTestRequeset 

 public class CustomMessageHandler : WorkMessageHandler<MessageContext<IRequestMessageBase, IResponseMessageBase>>
    {
        ruleDomain ruleDomain = new ruleDomain();

        public CustomMessageHandler(Stream inputStream, PostModel postModel, int maxRecordCount = 0)
            : base(inputStream, postModel, maxRecordCount)
        {
         
        }

        public CustomMessageHandler(XDocument requestDocument, PostModel postModel = null, int maxRecordCount = 0)
            : base(requestDocument, postModel, maxRecordCount)
        {
        }

        public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)
        {
            //ResponseMessageText也可以是News等其他类型
            var responseMessage = CreateResponseMessage<ResponseMessageText>();
            //responseMessage.Content = "这条消息来自DefaultResponseMessage。";
            responseMessage.Content = "";
            return responseMessage;
        }

        public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)
        {
            //TODO:这里的逻辑可以交给Service处理具体信息,参考OnLocationRequest方法或/Service/LocationSercice.cs
            var responseMessage = CreateResponseMessage<ResponseMessageText>();           

            //wechat 的uniID
            string uniqueID = requestMessage.FromUserName; //emilyweng 
           
            //透過不同的開頭做不同的事情
            
            var result = ruleDomain.rule(requestMessage.Content, uniqueID, "", "W");


            //FromUserName = emilyweng 發送此消息是利用userID是利用此          
            responseMessage.Content = result;
            //responseMessage.Content = string.Format("您刚才发送了文字信息:{0}", requestMessage.Content);
            return responseMessage;
        }

       
    }    

requestMessage.FromUserName 則是指說發送訊息者的唯一ID為何

ex: 例如 emilyweng 傳送訊息給Wechat 則會在FromUserName 得到 emilyweng,之後如果要傳送訊息也需要這個獨立ID

下方為 wechat 使用者傳訊息實的消息範本 , 若我是想要抓content 則是requestMessage.Content

照理來說如果OK後,放到IIS上就可以試著傳訊息看看有沒有回傳囉。

下一篇來寫,如何主動傳送訊息給使用者。


參考資料:

1.https://dotblogs.com.tw/just_click_button/2017/12/11/110508

2.https://work.weixin.qq.com/api/doc#12973