/// <summary> /// 取得Line Webhook 事件 /// </summary> /// <param name="httpContext">HttpContext</param> /// <param name="channelSecret">Line ChannelSecret</param> /// <returns></returns> public static async Task <ReceiveEventModel> GetWebhookEvent(HttpContext httpContext, string channelSecret) { HttpRequest request = httpContext.Request; //嘗試取得header中line的Signature StringValues headerValues; if (request.Headers.TryGetValue("X-Line-Signature", out headerValues) == false) { return(null); } ReceiveEventModel receiveEventModel = new ReceiveEventModel(); string lineSignature = headerValues.ToString(); string requestBody = string.Empty; //[dotnet core 2.2]使用Microsoft.AspNetCore.Http.Internal中的EnableRewind來允許搜尋body(Stream) //[dotnet core 3.1]使用EnableBuffering來允許搜尋body(Stream) //HttpContext.Request.Body是一種FrameRequestStream, 會不允許搜尋並跳出例外(NotSupportedException) //資料[dotnet core 3.1]:https://devblogs.microsoft.com/aspnet/re-reading-asp-net-core-request-bodies-with-enablebuffering/ //資料[dotnet core 2.2]:https://gunnarpeipman.com/aspnet-core-request-body/ //資料[dotnet core 3.1]:https://blog.johnwu.cc/article/asp-net-core-3-read-request-response-body.html //request.EnableRewind(); request.EnableBuffering(); //取得body資料 using (StreamReader streamReader = new StreamReader(request.Body, Encoding.UTF8, true, 1024, true)) { //Stream從頭讀到尾 requestBody = await streamReader.ReadToEndAsync(); //Stream讀完後要把Stream Position還原(歸零),否則之後還要讀取Request Body時, //會從Stream的結尾開始取資料, 導致取出的資料都是空的 request.Body.Seek(0, SeekOrigin.Begin); } //對比header的Signature與計算後的是否相同 if (!VerifyXLineSignature(requestBody, lineSignature, channelSecret)) { return(null); } receiveEventModel = JsonConvert.DeserializeObject <ReceiveEventModel>(requestBody); return(receiveEventModel); }
public async Task <IActionResult> Webhook() { HttpContext httpContext = HttpContext; LineMessagingClient client = new LineMessagingClient(accessToken); ReceiveEventModel model = await WebhookRequestMessage.GetWebhookEvent(httpContext, channelSecret); if (model == null) { return(BadRequest()); } if (model.events == null) { return(BadRequest()); } foreach (EventModel q in model.events) { string senderId = ""; switch (q.source.type) { case SourceType.user: senderId = q.source.userId; break; case SourceType.room: senderId = q.source.roomId; break; case SourceType.group: senderId = q.source.groupId; break; } if (q.type == EventType.message) { MessageEventTypeUtility messageEventTypeUtility = new MessageEventTypeUtility(accessToken); #region ReplyMessage /*ReplyMessageModel replyMessageBody = new ReplyMessageModel() * { * replyToken = q.replyToken, * messages = await messageEventTypeUtility.AutoProcessMessageType(q.message) * }; * * await client.ReplyMessageAsync(replyMessageBody);*/ #endregion #region ReplyMessageWithJson await client.ReplyMessageWithJsonAsync(q.replyToken, await messageEventTypeUtility.AutoProcessMessageTypeWithJson(q.message)); #endregion //await client.ReplyMessageWithJsonAsync(q.replyToken, new ApparelFlexMessage().Create2()); #region push message /*PushMessageModel pushMessageBody = new PushMessageModel() * { * to = "someone's UID", * messages = messageEventTypeUtility.PushMessageType() * }; * await client.PushMessageAsync(pushMessageBody);*/ #endregion #region broadcast message /*BroadcastModel broadcast = new BroadcastModel() * { * messages = messageEventTypeUtility.BroadcastMessageType() * }; * await client.BroadcastMessageAsync(broadcast);*/ #endregion Console.WriteLine("Sender: " + senderId); Console.WriteLine("Message: " + q.message.text); } else if (q.type == EventType.follow) { MessageEventTypeUtility messageEventTypeUtility = new MessageEventTypeUtility(accessToken); FollowEventTypeUtility followEventTypeProcessor = new FollowEventTypeUtility(accessToken); UserProfileResponseModel profileModel = await followEventTypeProcessor.GetProfileAsync(q.source.userId); string text = $"Welcome, {profileModel.displayName}"; ReplyMessageModel replyMessageBody = new ReplyMessageModel() { replyToken = q.replyToken, messages = messageEventTypeUtility.CreateTextMessage(text) }; await client.ReplyMessageAsync(replyMessageBody); } } return(Ok()); }