上篇已經將接收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