Ejemplo n.º 1
0
        public async Task ProcessStreamQueueMessage(
            [QueueTrigger(Constants.FX_CONFIG_STREAM_QUEUE_NAME_VALUE)] string message, ILogger logger)
        {
            var json   = JObject.Parse(message);
            var entity = new ChannelActivityEntity();

            if (json["data"].HasValues)
            {
                var updates = json["data"].ToObject <List <TwitchWebhookStreamResponse> >();
                foreach (var update in updates)
                {
                    entity.Activity     = StreamActivity.StreamStarted.ToString();
                    entity.PartitionKey = update.UserName;
                    entity.RowKey       = update.StartedAt.ToString(Constants.DATETIME_FORMAT).Replace(":", string.Empty).Replace("-", string.Empty);
                    entity.Viewer       = string.Empty;
                }
            }
            else
            {
                entity.Activity     = StreamActivity.StreamStopped.ToString();
                entity.PartitionKey = json["channel"].ToString();
                entity.RowKey       = DateTime.Parse(json["timestamp"].ToString()).ToString(Constants.DATETIME_FORMAT).Replace(":", string.Empty).Replace("-", string.Empty);
                entity.Viewer       = string.Empty;
            }
            await _storageService.AddDataToStorage(entity);

            await DispatchSignalRMessage(entity);
        }
Ejemplo n.º 2
0
        public static async Task <ChannelActivityEntity> InsertOrMergeEntityAsync(CloudTable table,
                                                                                  ChannelActivityEntity entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }

            try
            {
                // Create the InsertOrReplace table operation
                var insertOrMergeOperation = TableOperation.InsertOrMerge(entity);

                // Execute the operation.
                Console.WriteLine($"{DateTime.UtcNow.ToString(CultureInfo.InvariantCulture)}: Adding entity {entity} to the table {table.Name}");
                var result = await table.ExecuteAsync(insertOrMergeOperation);

                var insertedActivity = result.Result as ChannelActivityEntity;

                // Get the request units consumed by the current operation. RequestCharge of a TableResult is only applied to Azure Cosmos DB
                if (result.RequestCharge.HasValue)
                {
                    Console.WriteLine($"{DateTime.UtcNow.ToString(CultureInfo.InvariantCulture)}: Request Charge of InsertOrMerge Operation: {result.RequestCharge}");
                    Console.WriteLine($"{DateTime.UtcNow.ToString(CultureInfo.InvariantCulture)}: Added entity {entity} to the table {table.Name}");
                }

                return(insertedActivity);
            }
            catch (StorageException e)
            {
                Console.WriteLine($"{DateTime.UtcNow.ToString(CultureInfo.InvariantCulture)}: An exception has occured", e);
                throw;
            }
        }
Ejemplo n.º 3
0
        public async Task <HttpStatusCode> AddChannelEvent(string eventType, ChannelActivityEntity entity)
        {
            if (string.IsNullOrEmpty(eventType))
            {
                throw new ArgumentNullException(nameof(eventType));
            }

            if (!_urlDictionary.ContainsKey(eventType))
            {
                throw new ArgumentException($"The url for {eventType} is not available. Please update your appsettings and try again", nameof(eventType));
            }
            var postData = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair <string, string>("viewer", entity.Viewer),
                new KeyValuePair <string, string>("activity", entity.Activity),
                new KeyValuePair <string, string>("channel", entity.PartitionKey),
                new KeyValuePair <string, string>("timestamp", entity.Timestamp.DateTime.ToRowKeyString())
            });

            var uri      = _urlDictionary[eventType];
            var response = await _httpClient.PostAsync(uri, postData);

            response.EnsureSuccessStatusCode();

            return(response.StatusCode);
        }
Ejemplo n.º 4
0
        public static async Task <ChannelActivityEntity> InsertOrMergeEntityAsync(CloudTable table,
                                                                                  ChannelActivityEntity entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }

            try
            {
                // Create the InsertOrReplace table operation
                TableOperation insertOrMergeOperation = TableOperation.InsertOrMerge(entity);

                // Execute the operation.
                TableResult result = await table.ExecuteAsync(insertOrMergeOperation);

                ChannelActivityEntity insertedActivity = result.Result as ChannelActivityEntity;

                // Get the request units consumed by the current operation. RequestCharge of a TableResult is only applied to Azure Cosmos DB
                if (result.RequestCharge.HasValue)
                {
                    Console.WriteLine("Request Charge of InsertOrMerge Operation: " + result.RequestCharge);
                }

                return(insertedActivity);
            }
            catch (StorageException e)
            {
                Console.WriteLine(e.Message);
                Console.ReadLine();
                throw;
            }
        }
Ejemplo n.º 5
0
        private async Task Client_OnNewSubscriber(object sender, OnNewSubscriberArgs e)
        {
            Console.WriteLine($"{DateTime.UtcNow.ToString(CultureInfo.InvariantCulture)}: New Subscriber Posted");
            var entity = new ChannelActivityEntity
            {
                PartitionKey = e.Channel,
                RowKey       = DateTime.UtcNow.ToString(Constants.DATETIME_FORMAT).Replace(":", string.Empty).Replace("-", string.Empty).Replace(".", string.Empty),
                Activity     = StreamActivity.UserSubscribed.ToString(),
                Viewer       = e.Subscriber.Id
            };

            await AddEntityToStorage(entity);
        }
Ejemplo n.º 6
0
        private async Task DispatchSignalRMessage(ChannelActivityEntity entity)
        {
            try
            {
                await _hubConnection.StartAsync();

                await _hubConnection.InvokeAsync("StreamUpdate", entity);
            }
            finally
            {
                await _hubConnection.StopAsync();
            }
        }
Ejemplo n.º 7
0
        private async Task Client_OnUserLeft(object sender, OnUserLeftArgs e)
        {
            Console.WriteLine(
                $"{DateTime.UtcNow.ToString(CultureInfo.InvariantCulture)}: {e.Username} left the channel {e.Channel}");
            var entity = new ChannelActivityEntity
            {
                PartitionKey = e.Channel,
                RowKey       = DateTime.UtcNow.ToString(Constants.DATETIME_FORMAT).Replace(":", string.Empty).Replace("-", string.Empty).Replace(".", string.Empty),
                Activity     = StreamActivity.UserLeft.ToString(),
                Viewer       = e.Username
            };

            await AddEntityToStorage(entity);
        }
Ejemplo n.º 8
0
        private async Task Client_OnNewSubscriber(object sender, OnNewSubscriberArgs e)
        {
            var date = DateTime.UtcNow;

            _logger.LogInformation($"{date.ToRowKeyString()}: New Subscriber Posted");
            var entity = new ChannelActivityEntity
            {
                PartitionKey = e.Channel,
                RowKey       = date.ToRowKeyString(),
                Activity     = StreamActivity.UserSubscribed.ToString(),
                Viewer       = e.Subscriber.Id
            };
            await Common.AddEntityToStorage(_tableClient, entity, _streamingTable).ConfigureAwait(false);

            await _zapierClient.AddChannelEvent(Constants.ZAPIER_EVENTTYPE_MESSAGE, entity).ConfigureAwait(false);
        }
Ejemplo n.º 9
0
        private async Task Client_OnExisingUsersDetected(object sender, OnExistingUsersDetectedArgs e)
        {
            var date = DateTime.UtcNow;

            Console.WriteLine($"{date.ToString(CultureInfo.InvariantCulture)}: Existing users detected in {e.Channel}: {string.Join(", ",e.Users)}");
            foreach (var user in e.Users)
            {
                var entity = new ChannelActivityEntity
                {
                    PartitionKey = user,
                    RowKey       = date.ToString(Constants.DATETIME_FORMAT).Replace(":", string.Empty).Replace("-", string.Empty).Replace(".", string.Empty),
                    Activity     = StreamActivity.UserJoined.ToString(),
                    Viewer       = e.Channel
                };
                await AddEntityToStorage(entity);
            }
        }
Ejemplo n.º 10
0
        public async Task <IActionResult> ProcessStreamEvent(string channel)
        {
            _logger.LogFormattedMessage($"Processing Twitch webhook for event on channel: {channel}");

            using var reader = new StreamReader(Request.Body);
            var messageText = await reader.ReadToEndAsync();

            if (string.IsNullOrEmpty(messageText))
            {
                _logger.LogError("The message body is empty");
                return(new NoContentResult());
            }

            // Check if the json["data"] has values. If so, join the Channel. If not, leave the channel
            var json = JObject.Parse(messageText);
            ChannelActivityEntity entity;

            if (json["data"].HasValues)
            {
                var startedAt = json["data"][0]["started_at"].ToString();
                var result    = DateTime.TryParse(startedAt, out DateTime date);
                entity = new ChannelActivityEntity
                {
                    Activity     = StreamActivity.StreamStarted.ToString(),
                    PartitionKey = channel,
                    RowKey       = date.ToRowKeyString()
                };
            }
            else
            {
                entity = new ChannelActivityEntity
                {
                    Activity     = StreamActivity.StreamStopped.ToString(),
                    PartitionKey = channel,
                    RowKey       = DateTime.UtcNow.ToRowKeyString()
                };
            }
            await _hubContext.Clients.All.SendAsync(SIGNALR_UPDATECHANNEL, entity);

            await _storageService.AddDataToStorage(entity, TABLE_STREAMING);

            _logger.LogFormattedMessage($"Completed processing Twitch webhook for event on channel: {channel}");
            return(await Task.FromResult(NoContent()));
        }
Ejemplo n.º 11
0
        public async Task ProcessFollowersQueueMessage(
            [QueueTrigger("followers-data")] string message, ILogger logger)
        {
            var json    = JObject.Parse(message);
            var updates = json["data"].ToObject <List <TwitchWebhookFollowersResponse> >();

            foreach (var update in updates)
            {
                var entity = new ChannelActivityEntity
                {
                    Activity     = StreamActivity.UserFollowed.ToString(),
                    PartitionKey = update.ToName,
                    RowKey       = update.FollowedAt.ToString(Constants.DATETIME_FORMAT).Replace(":", string.Empty).Replace("-", string.Empty),
                    Viewer       = update.FromName
                };

                await _storageService.AddDataToStorage(entity);
            }
        }
Ejemplo n.º 12
0
        public async Task <IActionResult> PostFollowerUpdate([FromBody] object data, string channel)
        {
            var json    = JObject.Parse(data.ToString());
            var updates = json["data"].ToObject <List <TwitchWebhookFollowersResponse> >();

            foreach (var update in updates)
            {
                var entity = new ChannelActivityEntity
                {
                    Activity     = StreamActivity.UserFollowed.ToString(),
                    PartitionKey = channel,
                    RowKey       = update.FollowedAt.ToString("s").Replace(":", string.Empty).Replace("-", string.Empty),
                    Viewer       = update.FromName
                };

                await _storageService.AddDataToStorage(entity);
            }
            return(NoContent());
        }
Ejemplo n.º 13
0
        public async Task AddDataToStorage(ChannelActivityEntity entity)
        {
            try
            {
                if (_tableClient == null)
                {
                    CreateTableClient(_connectionString ?? _configuration[Constants.FX_CONFIG_CONNSTRING_STORAGE_NAME]);
                }

                var insertOperation = TableOperation.InsertOrMerge(entity);
                var table           = _tableClient.GetTableReference(Constants.FX_CONFIG_TABLE_NAME_VALUE);
                await table.CreateIfNotExistsAsync();

                var result = await table.ExecuteAsync(insertOperation);
            }
            catch (StorageException ex)
            {
                _logger.LogError($"{DateTime.UtcNow}: An exception has occurred: {ex.Message}", ex);
                throw;
            }
        }
Ejemplo n.º 14
0
 private async Task AddEntityToStorage(ChannelActivityEntity entity)
 {
     //await Common.AddMessageToQueue(_queueClient, entity);
     await Common.InsertOrMergeEntityAsync(_tableClient, entity);
 }
Ejemplo n.º 15
0
 public static async Task AddMessageToQueue(QueueClient queue, ChannelActivityEntity entity)
 {
     var json = JsonSerializer.Serialize(entity, typeof(ChannelActivityEntity), options: new JsonSerializerOptions {
     });
     await queue.SendMessageAsync(Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(json)));
 }
Ejemplo n.º 16
0
 public async Task StreamUpdate(ChannelActivityEntity entity)
 {
     await Clients.All.SendAsync("StreamUpdate", entity);
 }