Exemple #1
0
        /// <summary>
        /// Post the message msg to the slack channel implied by the webhook.
        /// </summary>
        /// <param name="log">Logger instance.</param>
        /// <param name="msg"> Message to be posted.</param>
        /// <returns>Status code: 0 = success.</returns>
        public static async Task <int> PostSlackMessageAsync(ILogger log, string msg)
        {
            log.LogInformation("PostSlackMessageAsync: enter.");

            var slackWebHook = await KeyVaultAccessor.GetInstance().GetSecretAsync("AzTwitterSarSlackHook");

            HttpClient httpClient = new HttpClient();

            httpClient.Timeout = TimeSpan.FromSeconds(30);
            Uri mlFuncUri = new Uri(slackWebHook);

            /* Setting the property link_names is required for the channel
             * alert to work. Alternatively (not tried), see
             * https://discuss.newrelic.com/t/sending-alerts-to-slack-with-channel-notification/35921/3 */
            var payload     = JsonConvert.SerializeObject(new { text = $"{msg}", link_names = "1" });
            var httpContent = new StringContent(payload, Encoding.UTF8, "application/json");

            HttpResponseMessage httpResponseMsg = await httpClient.PostAsync(mlFuncUri, httpContent);

            if (httpResponseMsg.StatusCode == HttpStatusCode.OK &&
                httpResponseMsg.Content != null)
            {
                var result = await httpResponseMsg.Content.ReadAsStringAsync();

                log.LogInformation("PostSlackMessageAsync: response: " + result);
            }
            else
            {
                log.LogInformation($"PostSlackMessageAsync: posting to slack failed, response code: {httpResponseMsg.StatusCode}.");
            }
            log.LogInformation("PostSlackMessageAsync: exit.");
            return(0);
        }
Exemple #2
0
        public static async Task <MlResult> GetMlScore([ActivityTrigger] string tweet, ILogger log)
        {
            log.LogInformation("A_GetMlScore: Start.");
            string mlUriString = await KeyVaultAccessor.GetInstance().GetSecretAsync("AzTwitterSarAiUri");

            MlResult result = new MlResult
            {
                Score     = 0,
                Label     = PublishLabel.NotAssigned,
                MlVersion = ""
            };

            if (mlUriString is null)
            {
                log.LogError($"ML-inference link not configured.");
            }
            else
            {
                var payload     = JsonConvert.SerializeObject(new { tweet = tweet });
                var httpContent = new StringContent(payload, Encoding.UTF8, "application/json");

                HttpClient httpClient = new HttpClient();
                httpClient.Timeout = TimeSpan.FromSeconds(30);
                Uri mlFuncUri = new Uri(mlUriString);

                log.LogInformation($"Calling ML-inference.");
                HttpResponseMessage httpResponseMsg = null;
                try
                {
                    httpResponseMsg = await httpClient.PostAsync(mlFuncUri, httpContent);
                }
                catch (Exception e)
                {
                    log.LogError($"Getting ML score failed: {e.Message}");
                }

                if (httpResponseMsg != null &&
                    httpResponseMsg.StatusCode == HttpStatusCode.OK &&
                    httpResponseMsg.Content != null)
                {
                    var responseContent = await httpResponseMsg.Content.ReadAsStringAsync();

                    ResponseData ml_result = JsonConvert.DeserializeObject <ResponseData>(responseContent);

                    result.Score     = ml_result.Score;
                    result.Label     = ml_result.Label == 1 ? PublishLabel.Positive : PublishLabel.Negative;
                    result.MlVersion = ml_result.Version;
                }
            }
            log.LogInformation("A_GetMlScore: Done.");

            return(result);
        }
Exemple #3
0
 public static KeyVaultAccessor GetInstance()
 {
     // C# thread-safe singleton pattern from refactoring.guru
     // This conditional is needed to prevent threads stumbling over the
     // lock once the instance is ready.
     if (_instance == null)
     {
         lock (_lock)
         {
             // The first thread to acquire the lock, reaches this
             // conditional, goes inside and creates the Singleton
             // instance. Once it leaves the lock block, a thread that
             // might have been waiting for the lock release may then
             // enter this section. But since the Singleton field is
             // already initialized, the thread won't create a new
             // object.
             if (_instance == null)
             {
                 _instance = new KeyVaultAccessor();
             }
         }
     }
     return(_instance);
 }
Exemple #4
0
        public static async Task <List <TweetProcessingData> > GetTweets([ActivityTrigger] string lastTweetId, ILogger log)
        {
            log.LogInformation($"A_GetTweets: Getting new tweets after {lastTweetId}.");
            KeyVaultAccessor kva    = KeyVaultAccessor.GetInstance();
            string           apiKey = await kva.GetSecretAsync("TwitterApiKey");   // aka consumer key

            string apiSecretKey = await kva.GetSecretAsync("TwitterApiSecretKey"); // aka consumer secret

            string accessToken = await kva.GetSecretAsync("TwitterAccessToken");

            string accessTokenSecret = await kva.GetSecretAsync("TwitterAccessTokenSecret");

            string monitoredTwitterAccount  = Environment.GetEnvironmentVariable("MonitoredTwitterAccount");
            List <TweetProcessingData> tpds = new List <TweetProcessingData>(); // return value, empty list if Twitter connection failure

            var userCredentials = Auth.SetUserCredentials(apiKey, apiSecretKey, accessToken, accessTokenSecret);

            try
            {
                // This variable is not used later, but seems to leave an id for the library.
                var authenticatedUser = User.GetAuthenticatedUser(userCredentials);
            }
            catch (AggregateException ae)
            {
                // Inserted try-catch after a seemingly intermittent exception that lead to
                // the service stopping completely, 20210102, ca. 11 am.
                log.LogWarning($"A_GetTweets: User authentication failure: {ae.Message}. Return no tweets and retry in next cycle.");
                return(tpds);
            }

            // Note: The following does NOT get MaximumNumberOfResults tweets
            //       from after lastTweetId!!! Rather it gets the most recent
            //       tweets with the early limit defined by lastTweetId OR the
            //       defined maximum, whichever is more limiting!
            //       (Therefore, in order to test on past tweets, one may need
            //       to increase MaximumNumberOfResults considerably to get ALL
            //       tweets from the one targeted to the current one.
            SearchTweetsParameters searchParameter = new SearchTweetsParameters($"from:{monitoredTwitterAccount}")
            {
                MaximumNumberOfResults = 15,
                SinceId = long.Parse(lastTweetId)
            };

            IEnumerable <ITweet> tweets = null;

            try
            {
                tweets = await SearchAsync.SearchTweets(searchParameter);
            }
            catch (Exception e)
            {
                // Inserted try-catch after a seemingly intermittent exception that lead to
                // the service stopping completely, 20201213, ca. 7 am.
                log.LogWarning($"A_GetTweets: SearchTweets failed with exception: {e.Message}");
            }
            if (tweets is null)
            {
                log.LogWarning($"A_GetTweets: Twitter connection failure. Return no tweets and retry in next cycle.");
                return(tpds);
            }
            // Since the further processing can scramble the order again, we don't need to sort here.

            foreach (var tweet in tweets)
            {
                // Copy the data that we need over to a serializable struct.
                TweetProcessingData tpd = new TweetProcessingData();
                tpd.IdStr     = tweet.IdStr;
                tpd.CreatedAt = tweet.CreatedAt;
                tpd.FullText  = tweet.FullText;

                tpd.Hashtags = String.Join("|", tweet.Hashtags.Select(t => t.Text));

                tpd.InReplyToStatusIdStr = tweet.InReplyToStatusIdStr;
                tpd.Url = tweet.Url;

                tpd.TextWithoutTags = TweetAnalysis.removeHashtagsFromText(tweet.FullText, tweet.Hashtags);

                tpds.Add(tpd);
            }
            log.LogInformation($"A_GetTweets: Done, got {tweets.Count()} new tweets.");

            return(tpds);
        }