예제 #1
0
        public void Dispatch <T>(IList <T> webhookEvents, LineMessagingApiConfig config) where T : WebhookEvent
        {
            var messageList = webhookEvents.OfType <MessageEvent>().Where(x => x.Message.Type == EventMessageType.Text)
                              .Select(x => new Message
            {
                Type   = MessageType.Text,
                Text   = (x.Message as TextEventMessage)?.Text,
                Source = x.Source.Type == MessagingEventSourceType.User ? new EventSource {
                    Type = WebHookModelEventSourceType.User, UserId = x.Source.UserId
                } :
                x.Source.Type == MessagingEventSourceType.Group ? new EventSource {
                    Type = WebHookModelEventSourceType.Group, UserId = x.Source.UserId, GroupId = x.Source.Id
                } :
                x.Source.Type == MessagingEventSourceType.Room ? new EventSource {
                    Type = WebHookModelEventSourceType.Room, UserId = x.Source.UserId, RoomId = x.Source.Id
                } : default(EventSource),
                ReplyToken = x.ReplyToken,
                Timestamp  = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(x.Timestamp)
            }).ToList();

            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'");
            }

            var traceToken = $"line-message-{Guid.NewGuid()}";

            var redisHelper = new AzureRedisHelper(redisConnectionString);

            redisHelper.SetRedis(traceToken, JsonConvert.SerializeObject(config),
                                 (int)new TimeSpan(days: 0, hours: 1, minutes: 0, seconds: 0).TotalSeconds);

            var publishHelper = new EventGridPublishHelper(new Uri(eventGridEndpoint), eventGridKey);

            publishHelper.PublishEventAsync(
                new List <EventGridEvent>
            {
                EventGridUtility.CreateTraceableEventGridEvent($"/line/webhook/message/", new MessagesEvent
                {
                    ChannelId = config.ChannelId,
                    Messages  = messageList
                }, traceToken)
            }
                ).GetAwaiter().GetResult();
        }
예제 #2
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"));
        }