Exemple #1
0
        private static async Task OnMessageEventAsync(IDurableOrchestrationClient client, MessageEvent messageEvent)
        {
            if (messageEvent.Message is TextEventMessage message)
            {
                var str = message.Text.Replace("\r\n", "\n").Replace("\n", "。");

                // テンプレート入力中であればテンプレートにメッセージを追加
                var tmplStatus = await client.GetStatusAsync("tmpl_" + messageEvent.Source.UserId);

                if (tmplStatus?.RuntimeStatus == OrchestrationRuntimeStatus.ContinuedAsNew ||
                    tmplStatus?.RuntimeStatus == OrchestrationRuntimeStatus.Pending ||
                    tmplStatus?.RuntimeStatus == OrchestrationRuntimeStatus.Running)
                {
                    // Durable Functionsの外部イベントとして送信メッセージを投げる
                    await client.RaiseEventAsync("tmpl_" + messageEvent.Source.UserId, Consts.DurableEventNameAddToTemplate, str);

                    await lineMessagingClient.ReplyMessageAsync(messageEvent.ReplyToken,
                                                                new List <ISendMessage>
                    {
                        new TextMessage("テンプレートに追加しました。",
                                        new QuickReply
                        {
                            Items = { new QuickReplyButtonObject(new PostbackTemplateAction("作成を終了する", "action=endTemplateSetting")) }
                        })
                    });
                }
                else
                {
                    // 待機中になるまで待つ
                    while (true)
                    {
                        // ひとつ前のイベントを処理している最中は無視されるので注意
                        var ventStatus = await client.GetStatusAsync(messageEvent.Source.UserId);

                        if (ventStatus.RuntimeStatus == OrchestrationRuntimeStatus.ContinuedAsNew ||
                            ventStatus.RuntimeStatus == OrchestrationRuntimeStatus.Pending ||
                            ventStatus.RuntimeStatus == OrchestrationRuntimeStatus.Running)
                        {
                            // Durable Functionsの外部イベントとして送信メッセージを投げる
                            await client.RaiseEventAsync(messageEvent.Source.UserId, Consts.DurableEventNameLineVentriloquismInput, str);

                            break;
                        }
                        else if (ventStatus.RuntimeStatus == OrchestrationRuntimeStatus.Terminated ||
                                 ventStatus.RuntimeStatus == OrchestrationRuntimeStatus.Canceled ||
                                 ventStatus.RuntimeStatus == OrchestrationRuntimeStatus.Failed)
                        {
                            // キャンセル、失敗時はスキル起動していない状態のため、スキル起動を促す
                            await lineMessagingClient.ReplyMessageAsync(messageEvent.ReplyToken,
                                                                        new List <ISendMessage>
                            {
                                new TextMessage("Clovaで「テキスト腹話術」のスキルを起動してください。")
                            });

                            break;
                        }
                    }
                }
            }
        }
Exemple #2
0
        protected override async Task OnMessageAsync(MessageEvent ev)
        {
            var result = null as List <ISendMessage>;

            switch (ev.Message)
            {
            //文字訊息
            case TextEventMessage textMessage:
            {
                //頻道Id
                var channelId = ev.Source.Id;
                //使用者Id
                var userId = ev.Source.UserId;

                //回傳 hellow
                result = new List <ISendMessage>
                {
                    new TextMessage("yes")
                };
            }
            break;
            }

            if (result != null)
            {
                await _messagingClient.ReplyMessageAsync(ev.ReplyToken, result);
            }
        }
        private async Task HandleTextAsync(string replyToken, string userMessage, string userId)
        {
            userMessage = userMessage.ToLower().Replace(" ", "");
            if (userMessage == "チョコレート")
            {
                var reserve = new Reserve()
                {
                    ProductName    = "チョコレート",
                    Amount         = 1,
                    Currency       = Currency.JPY,
                    OrderId        = Guid.NewGuid().ToString(),
                    ConfirmUrl     = $"{appsettings.ServerUri}/api/linebot/confirm",
                    ConfirmUrlType = ConfirmUrlType.SERVER
                };

                var response = await payClient.ReserveAsync(reserve);

                // ユーザーの情報を設定
                reserve.Mid = userId;
                CacheService.Cache.Add(response.Info.TransactionId, reserve);
                var replyMessage = new TemplateMessage(
                    "Button Template",
                    new ButtonsTemplate(
                        text: $"{reserve.ProductName}を購入するには下記のボタンで決済に進んでください",
                        actions: new List <ITemplateAction> {
                    new UriTemplateAction("LINE Pay で決済", response.Info.PaymentUrl.Web)
                }));

                await messagingClient.ReplyMessageAsync(replyToken, new List <ISendMessage> {
                    replyMessage
                });
            }
        }
Exemple #4
0
 protected override async Task OnFollowAsync(FollowEvent ev)
 {
     await _messagingClient.ReplyMessageAsync(ev.ReplyToken,
                                              new List <ISendMessage> {
         new TextMessage("機器人可查詢附近口罩庫存數量"),
         new TextMessage("查詢方式: 傳送 LINE 定位"),
         new TextMessage("資料來源: 健康保險資料開放服務"),
         new ImageMessage(
             "https://fysh711426.github.io/iMaskMap/image/mask_info.jpg",
             "https://fysh711426.github.io/iMaskMap/image/mask_info_preview.jpg",
             new QuickReply
         {
             Items = new List <QuickReplyButtonObject>
             {
                 new QuickReplyButtonObject(
                     new LocationTemplateAction("查詢"))
             }
         })
     });
 }
Exemple #5
0
        protected override async Task OnMessageAsync(MessageEvent ev)
        {
            var result = null as List <ISendMessage>;

            switch (ev.Message)
            {
            //文字訊息
            case TextEventMessage textMessage:
            {
                //頻道Id
                var channelId = ev.Source.Id;
                //使用者Id
                var userId = ev.Source.UserId;

                var Msg = "";
                //回傳 hellow
                if (textMessage.Text.Contains("鴻銡"))
                {
                    Msg = textMessage.Text + "看來是死定了";
                }
                else if (textMessage.Text.Contains("和和"))
                {
                    Msg = textMessage.Text + "對方還在測試";
                }
                else if (textMessage.Text.Contains("威鉅"))
                {
                    Msg = textMessage.Text + "不明不白的就簽收了";
                }
                else if (textMessage.Text.Contains("今天"))
                {
                    Msg = textMessage.Text + "哈哈哈,今天是TPS和Angular 分享";
                }
                else if (textMessage.Text.Contains("開會"))
                {
                    Msg = textMessage.Text + "我的人生又少了一個小時";
                }
                else
                {
                    Msg = "我老闆什麼都不會";
                }
                result = new List <ISendMessage> {
                    new TextMessage(Msg)
                };
                if (result != null)
                {
                    await _messagingClient.ReplyMessageAsync(ev.ReplyToken, result);
                }
                break;
            }
            }
        }
Exemple #6
0
        private async Task StartBatchSubSkills(string replyToken, Context context)
        {
            // 子コンテキスト
            var childQuery = context.UserQuery.SubSkills[0].UserQuery;

            childQuery.Timestamp = DateTime.UtcNow.Ticks;
            var childEntityId = new EntityId(nameof(ContextEntity), $"{childQuery.IntentName}-{context.UserId}");
            var childContext  = new Context
            {
                UserId    = context.UserId,
                SkillName = childQuery.IntentName,
                UserQuery = childQuery
            };
            await DurableClient.SignalEntityAsync <IContextEntity>(childEntityId, proxy => proxy.SetContext(childContext));

            // 先頭スキルの実行
            var childMessages = await Skills.First(s => s.IntentName == context.UserQuery.SubSkills[0].UserQuery.IntentName).GetReplyMessagesAsync(childContext);

            await LineMessagingClient.ReplyMessageAsync(replyToken, childMessages);
        }
 /// <summary>
 /// Send LINE messages to LINE Channel. If reply fails, try push instead.
 /// </summary>
 /// <param name="messages">LINE messages</param>
 /// <param name="replyToken">ReplyToken</param>
 /// <param name="userId">UserId</param>
 /// <returns></returns>
 public async Task SendAsync(List <ISendMessage> messages, string userId, string replyToken)
 {
     try
     {
         // If messages contain more than 5 items, then do reply for first 5, then push the rest.
         for (int i = 0; i < (double)messages.Count / 5; i++)
         {
             if (i == 0)
             {
                 await messagingClient.ReplyMessageAsync(replyToken, messages.Take(5).ToList());
             }
             else
             {
                 await messagingClient.PushMessageAsync(replyToken, messages.Skip(i * 5).Take(5).ToList());
             }
         }
     }
     catch (LineResponseException ex)
     {
         if (ex.Message == "Invalid reply token")
         {
             try
             {
                 for (int i = 0; i < (double)messages.Count / 5; i++)
                 {
                     await messagingClient.PushMessageAsync(userId, messages.Skip(i * 5).Take(5).ToList());
                 }
             }
             catch (LineResponseException innerEx)
             {
                 await messagingClient.PushMessageAsync(userId, innerEx.Message);
             }
         }
     }
     catch (Exception ex)
     {
         await messagingClient.PushMessageAsync(userId, ex.Message);
     }
 }
Exemple #8
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequestMessage req,
            [OrchestrationClient] DurableOrchestrationClient client,
            ILogger log)
        {
            try
            {
                var ev = (await req.GetWebhookEventsAsync(Consts.LineMessagingApiChannelSecret)).FirstOrDefault();

                if (ev is MessageEvent messageEvent)
                {
                    if (messageEvent.Message is TextEventMessage message)
                    {
                        // テンプレート入力中であればテンプレートにメッセージを追加
                        var tmplStatus = await client.GetStatusAsync("tmpl_" + messageEvent.Source.UserId);

                        if (tmplStatus?.RuntimeStatus == OrchestrationRuntimeStatus.ContinuedAsNew ||
                            tmplStatus?.RuntimeStatus == OrchestrationRuntimeStatus.Pending ||
                            tmplStatus?.RuntimeStatus == OrchestrationRuntimeStatus.Running)
                        {
                            // Durable Functionsの外部イベントとして送信メッセージを投げる
                            await client.RaiseEventAsync("tmpl_" + messageEvent.Source.UserId, Consts.DurableEventNameAddToTemplate, message.Text);

                            await lineMessagingClient.ReplyMessageAsync(messageEvent.ReplyToken,
                                                                        new List <ISendMessage>
                            {
                                new TextMessage("テンプレートに追加しました。",
                                                new QuickReply
                                {
                                    Items = { new QuickReplyButtonObject(new PostbackTemplateAction("作成を終了する", "action=endTemplateSetting")) }
                                })
                            });
                        }
                        else
                        {
                            // 待機中になるまで待つ
                            while (true)
                            {
                                // ひとつ前のイベントを処理している最中は無視されるので注意
                                var ventStatus = await client.GetStatusAsync(messageEvent.Source.UserId);

                                if (ventStatus.RuntimeStatus == OrchestrationRuntimeStatus.ContinuedAsNew ||
                                    ventStatus.RuntimeStatus == OrchestrationRuntimeStatus.Pending ||
                                    ventStatus.RuntimeStatus == OrchestrationRuntimeStatus.Running)
                                {
                                    // Durable Functionsの外部イベントとして送信メッセージを投げる
                                    await client.RaiseEventAsync(messageEvent.Source.UserId, Consts.DurableEventNameLineVentriloquismInput, message.Text);

                                    break;
                                }
                                else if (ventStatus.RuntimeStatus == OrchestrationRuntimeStatus.Terminated ||
                                         ventStatus.RuntimeStatus == OrchestrationRuntimeStatus.Canceled ||
                                         ventStatus.RuntimeStatus == OrchestrationRuntimeStatus.Failed)
                                {
                                    // キャンセル、失敗時はスキル起動していない状態のため、スキル起動を促す
                                    await lineMessagingClient.ReplyMessageAsync(messageEvent.ReplyToken,
                                                                                new List <ISendMessage>
                                    {
                                        new TextMessage("Clovaで「腹話術」のスキルを起動してください。")
                                    });

                                    break;
                                }
                            }
                        }
                    }
                }
                else if (ev is PostbackEvent postbackEvent)
                {
                    switch (postbackEvent?.Postback?.Data)
                    {
                    // テンプレート作成開始
                    case "action=startTemplateSetting":
                        await lineMessagingClient.ReplyMessageAsync(postbackEvent.ReplyToken,
                                                                    new List <ISendMessage>
                        {
                            new TextMessage("テンプレートに追加したいセリフを送ってください。")
                        });

                        await client.StartNewAsync(nameof(MakeTemplate), "tmpl_" + ev.Source.UserId, null);

                        break;

                    // テンプレート作成終了
                    case "action=endTemplateSetting":
                        // Durable Functionsの外部イベントとして送信メッセージを投げる
                        await client.RaiseEventAsync("tmpl_" + ev.Source.UserId, Consts.DurableEventNameAddToTemplate, $"{Consts.FinishMakingTemplate}_{postbackEvent.ReplyToken}");

                        break;

                    // 無限セッション終了
                    case "action=terminateDurableSession":
                        // Durable Functionsの外部イベントとして送信メッセージを投げる
                        await client.TerminateAsync(ev.Source.UserId, "User Canceled");

                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                log.LogError(ex.Message);
                log.LogError(ex.StackTrace);
            }

            return(new OkObjectResult("OK"));
        }
        protected override async Task OnMessageAsync(MessageEvent ev)
        {
            var textMessage = (ev.Message as TextEventMessage);

            if (textMessage == null)
            {
                return;
            }

            if (textMessage.Text == "RegisterMenu")
            {
                var debugUser = ConfigurationManager.AppSettings["DebugUser"];
                if (debugUser != null && debugUser == ev.Source.UserId)
                {
                    var menuManager = new BingoMenuManager(_messagingClient);
                    await menuManager.RegisterBingoMenuAsync();

                    await _messagingClient.ReplyMessageAsync(ev.ReplyToken, "Registerd Bingo Menus.");

                    return;
                }
            }
            var user = await _messagingClient.GetUserProfileAsync(ev.Source.UserId);

            await TalkAsync(ev.ReplyToken, user, textMessage.Text);
        }
Exemple #10
0
        protected override async Task OnMessageAsync(MessageEvent ev)
        {
            await OnBeforeMessageAsync(ev);

            if (ShouldEnd)
            {
                return;
            }

            UserQuery query = null;

            switch (ev.Message.Type)
            {
            case EventMessageType.Text:
                var text = ((TextEventMessage)ev.Message).Text;

                // テキスト・インテント待ちを確認
                var waiterId    = new EntityId(nameof(ContextEntity), $"{WaiterEntityPrefix}_{ev.Source.UserId}");
                var waiterState = await DurableClient.ReadEntityStateAsync <ContextEntity>(waiterId);

                var     isWaitingForIntents = false;
                var     isWaitingForText    = false;
                Context waitingContext      = null;
                if (waiterState.EntityExists && waiterState.EntityState.Context != null)
                {
                    waitingContext = waiterState.EntityState.Context;
                    if (waitingContext.ExpectedIntentNames != null)
                    {
                        isWaitingForIntents = true;
                    }
                    else
                    {
                        isWaitingForText = true;
                    }
                }

                if (isWaitingForIntents || !isWaitingForText)
                {
                    // detect intent
                    query = await NluClient.DetectIntent(text, ev.Source.UserId);

                    Logger.LogInformation(query.IntentName);
                }

                if (isWaitingForIntents)
                {
                    Logger.LogInformation(waitingContext.SkillName);
                }

                // 実行スキルを選択
                var targetSkill = (isWaitingForIntents && waitingContext.ExpectedIntentNames.Contains(query.IntentName)) || isWaitingForText
                        ? waitingContext.SkillName  // 待機スキル
                        : query.IntentName;         // 解析スキル

                if (isWaitingForText)
                {
                    query = new UserQuery
                    {
                        IntentName = targetSkill,
                    };
                }

                // テキストをセット
                query.Text = text;

                var skill = Skills.FirstOrDefault(s => s.IntentName == targetSkill);
                if (skill != null)
                {
                    // コンテキスト確認を行う
                    var entityId = new EntityId(nameof(ContextEntity), $"{targetSkill}-{ev.Source.UserId}");
                    var state    = await DurableClient.ReadEntityStateAsync <ContextEntity>(entityId);

                    Context context = null;

                    if (state.EntityExists && state.EntityState.Context != null)
                    {
                        context = state.EntityState.Context;
                        var savedTimestamp = context.UserQuery.Timestamp;

                        // Execute incomplete sub-skills when restarting from a pause between sub-skills of a batch execution skill
                        var resume = context.UserQuery.SubSkills?.Where((s, idx) => idx != 0 && !s.IsFinished).FirstOrDefault();
                        if (resume != null)
                        {
                            context = new Context
                            {
                                UserId    = ev.Source.UserId,
                                SkillName = resume.UserQuery.IntentName,
                                UserQuery = resume.UserQuery
                            };
                        }
                        else
                        {
                            context.UserQuery = query;
                        }
                    }
                    else
                    {
                        context = new Context {
                            UserId = ev.Source.UserId, IsNew = true
                        };
                        query.Timestamp   = DateTime.UtcNow.Ticks;
                        context.UserQuery = query;
                    }
                    context.SkillName = targetSkill;

                    var messages = await skill.GetReplyMessagesAsync(context);

                    // Save context
                    await DurableClient.SignalEntityAsync <IContextEntity>(entityId, proxy => proxy.SetContext(context));

                    // Waiter
                    if (context.IsWaiting)
                    {
                        await DurableClient.SignalEntityAsync <IContextEntity>(waiterId, proxy => proxy.SetContext(context));
                    }

                    if (messages != null)
                    {
                        if (!skill.IsContinued)
                        {
                            var quickReply = await FinishAndGetResumeQuickReplyAsync(context);

                            if (messages.Last().QuickReply != null && messages.Last().QuickReply.Items.Count > 0)
                            {
                                messages.Last().QuickReply = MergeQuickReply(messages.Last().QuickReply, quickReply);
                            }
                            else
                            {
                                messages.Last().QuickReply = quickReply;
                            }
                        }
                        await LineMessagingClient.ReplyMessageAsync(ev.ReplyToken, messages);
                    }
                    // Batch execution skill
                    else if (context.UserQuery.SubSkills != null)
                    {
                        await StartBatchSubSkills(ev.ReplyToken, context);
                    }
                }
                else if (query.IsFallback)
                {
                    Logger.LogError("Fallback");
                    // TODO connect to knowledge base
                    await LineMessagingClient.ReplyMessageAsync(ev.ReplyToken,
                                                                query.FulfillmentText ?? "すみません、よくわかりませんでした。");
                }
                else
                {
                    Logger.LogError("Intentに対応するスキル定義がありません。");
                    await LineMessagingClient.ReplyMessageAsync(ev.ReplyToken,
                                                                query.FulfillmentText ?? "すみません、よくわかりませんでした。");
                }

                break;

            case EventMessageType.Sticker:
            case EventMessageType.Image:
            case EventMessageType.Video:
            case EventMessageType.Location:
            case EventMessageType.Audio:
            case EventMessageType.File:
            default:
                break;
            }

            await OnAfterMessageAsync(ev, query);
        }
Exemple #11
0
        protected override async Task OnPostbackAsync(PostbackEvent ev)
        {
            var query = JsonConvert.DeserializeObject <UserQuery>(ev.Postback.Data);

            await OnBeforePostbackAsync(ev, query);

            if (ShouldEnd)
            {
                return;
            }

            // テキスト・インテント待ちを確認
            var waiterId    = new EntityId(nameof(ContextEntity), $"{WaiterEntityPrefix}_{ev.Source.UserId}");
            var waiterState = await DurableClient.ReadEntityStateAsync <ContextEntity>(waiterId);

            var     isWaitingForIntents = false;
            var     isWaitingForText    = false;
            Context waitingContext      = null;

            if (waiterState.EntityExists && waiterState.EntityState.Context != null)
            {
                waitingContext = waiterState.EntityState.Context;
                if (waitingContext.ExpectedIntentNames != null)
                {
                    isWaitingForIntents = true;
                }
                else
                {
                    isWaitingForText = true;
                }
            }

            // 実行スキルを選択
            var targetSkill = (isWaitingForIntents && waitingContext.ExpectedIntentNames.Contains(query.IntentName)) || isWaitingForText
                ? waitingContext.SkillName  // 待機スキル
                : query.IntentName;         // 解析スキル

            if (isWaitingForText)
            {
                query = new UserQuery
                {
                    IntentName = targetSkill,
                };
            }

            var skill = Skills.FirstOrDefault(s => s.IntentName == targetSkill);

            if (skill != null)
            {
                var requestedTimestamp = query.Timestamp;

                // コンテキスト確認を行う
                var entityId = new EntityId(nameof(ContextEntity), $"{targetSkill}-{ev.Source.UserId}");
                var state    = await DurableClient.ReadEntityStateAsync <ContextEntity>(entityId);

                Context context = null;

                if (state.EntityExists && state.EntityState.Context != null)
                {
                    context = state.EntityState.Context;
                }
                else
                {
                    context = new Context {
                        UserId = ev.Source.UserId, IsNew = true
                    };
                    query.Timestamp = DateTime.UtcNow.Ticks;
                }

                context.UserQuery = query;

                if (!context.UserQuery.IsSubSkill && !context.UserQuery.AllowExternalCalls &&
                    (context.IsNew || context.UserQuery.Timestamp > requestedTimestamp))
                {
                    await LineMessagingClient.ReplyMessageAsync(ev.ReplyToken, "その操作は現在できません。");

                    return;
                }

                // スキル再確認
                var subSkill  = Skills.FirstOrDefault(s => s.IntentName == context.UserQuery.IntentName);
                var execSkill = subSkill ?? skill;

                var messages = await execSkill.GetReplyMessagesAsync(context);

                // 状態を保存
                await DurableClient.SignalEntityAsync <IContextEntity>(entityId, proxy => proxy.SetContext(context));

                // Waiter
                if (context.IsWaiting)
                {
                    await DurableClient.SignalEntityAsync <IContextEntity>(waiterId, proxy => proxy.SetContext(context));
                }

                if (messages != null)
                {
                    if (!execSkill.IsContinued)
                    {
                        var quickReply = await FinishAndGetResumeQuickReplyAsync(context);

                        if (messages.Last().QuickReply != null && messages.Last().QuickReply.Items.Count > 0)
                        {
                            messages.Last().QuickReply = MergeQuickReply(messages.Last().QuickReply, quickReply);
                        }
                        else
                        {
                            messages.Last().QuickReply = quickReply;
                        }
                    }
                    await LineMessagingClient.ReplyMessageAsync(ev.ReplyToken, messages);
                }
                // バッチ実行スキル
                else if (context.UserQuery.SubSkills != null)
                {
                    await StartBatchSubSkills(ev.ReplyToken, context);
                }
            }

            await OnAfterPostbackAsync(ev, query);
        }
Exemple #12
0
        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());
        }
Exemple #13
0
        public static async Task <IActionResult> RunAsync([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequestMessage req, TraceWriter log)
        {
            string requestContent = await req.Content.ReadAsStringAsync();

            if (string.IsNullOrWhiteSpace(requestContent))
            {
                return(new BadRequestObjectResult("Empty content is given"));
            }

            var eventGridSubscriber = new TraceableEventGridSubscriber();

            eventGridSubscriber.AddOrUpdateCustomEventMapping(typeof(MessagesEventReply).FullName, typeof(MessagesEventReply));
            var eventGridEvents = eventGridSubscriber.DeserializeEventGridEvents(requestContent).ToList();

            var subscriptionValidationEvent =
                eventGridEvents.FirstOrDefault(x => x.Data is SubscriptionValidationEventData);

            if (subscriptionValidationEvent != null)
            {
                var eventData = (SubscriptionValidationEventData)subscriptionValidationEvent.Data;
                log.Info($"Got SubscriptionValidation event data, validationCode: {eventData.ValidationCode},  validationUrl: {eventData.ValidationUrl}, topic: {subscriptionValidationEvent.Topic}");

                return(new OkObjectResult(new SubscriptionValidationResponse
                {
                    ValidationResponse = eventData.ValidationCode
                }));
            }

            var eventGridEndpoint     = Environment.GetEnvironmentVariable("EventGridTopicEndpoint", EnvironmentVariableTarget.Process);
            var eventGridKey          = Environment.GetEnvironmentVariable("EventGridTopicKey", EnvironmentVariableTarget.Process);
            var redisConnectionString = Environment.GetEnvironmentVariable("RedisConnectionString", EnvironmentVariableTarget.Process);

            if (string.IsNullOrWhiteSpace(eventGridEndpoint) || string.IsNullOrWhiteSpace(eventGridKey) || string.IsNullOrWhiteSpace(redisConnectionString))
            {
                throw new Exception(
                          "Lacks of Environment Variable: 'EventGridTopicEndpoint' or 'EventGridTopicKey' or 'RedisConnectionString'");
            }

            Parallel.ForEach(eventGridEvents, eventGridEvent =>
            {
                try
                {
                    var traceableEventData = (TraceableEventData)eventGridEvent.Data;

                    if (traceableEventData.Data is MessagesEventReply messagesEventReply)
                    {
                        var redisHelper  = new AzureRedisHelper(redisConnectionString);
                        var configString = redisHelper.GetRedis(traceableEventData.TraceToken) ??
                                           throw new Exception($"Get empty serialized LineMessagingApiConfig string with key '{traceableEventData.TraceToken}'");
                        var config = JsonConvert.DeserializeObject <LineMessagingApiConfig>(configString) ??
                                     throw new Exception($"Failed to deserialize LineMessagingApiConfig string with '{configString}'");

                        Parallel.ForEach(messagesEventReply.MessageReplys.GroupBy(x => x.ReplyToken), messageReplyGroupByReplyToken =>
                        {
                            var sendMessages = messageReplyGroupByReplyToken.Select(messageReply => SendMessageConverter.ConvertToISendMessages(messageReply, log)).ToList();
                            var lineId       = messageReplyGroupByReplyToken.First().LineId;
                            var lineClient   = new LineMessagingClient(config.ChannelAccessToken);
                            try
                            {
                                lineClient.ReplyMessageAsync(
                                    messageReplyGroupByReplyToken.Key,
                                    sendMessages
                                    ).GetAwaiter().GetResult();
                            }
                            catch (LineResponseException ex)
                            {
                                log.Warning(ex.ToString());
                                try
                                {
                                    lineClient.PushMessageAsync(
                                        lineId,
                                        sendMessages
                                        ).GetAwaiter().GetResult();
                                }
                                catch (Exception exi)
                                {
                                    log.Warning(exi.ToString());
                                }
                            }
                            catch (Exception ex)
                            {
                                log.Warning(ex.ToString());
                            }
                        });
                    }
                }
                catch (Exception ex)
                {
                    log.Error(ex.ToString());
                }
            });

            return(new OkObjectResult("Ok"));
        }