public static async Task <int> PublishTweets([ActivityTrigger] List <TweetProcessingData> tpds, ILogger log) { log.LogInformation($"A_PublishTweets: Publishing {tpds.Count} tweets."); double minScoreBLAlert = TweetAnalysis.GetScoreFromEnv("AZTWITTERSAR_MINSCORE_ALERT", log, 0.1f); foreach (var tpd in tpds) { string slackMsg = ""; if (tpd.Score > minScoreBLAlert) { slackMsg += $"@channel\n"; } slackMsg += $"{tpd.FullText}\n" + $"Score (v{AzTwitterSarVersion.get()}): {tpd.Score.ToString("F", CultureInfo.InvariantCulture)}, " + $"ML ({tpd.VersionML}): {tpd.ScoreML.ToString("F", CultureInfo.InvariantCulture)}\n" + $"Link: http://twitter.com/politivest/status/{tpd.IdStr}"; log.LogInformation($"Message: {slackMsg}"); int sendResult = await SlackClient.PostSlackMessageAsync(log, slackMsg); log.LogInformation($"Message posted to slack, result: {sendResult}"); } log.LogInformation($"A_PublishTweets: Done."); return(0); }
public static Tuple <double, PublishLabel, string> GetBusinessLogicScore([ActivityTrigger] string textWithoutTags, ILogger log) { log.LogInformation("A_GetBusinessLogicScore: Start."); string highlightedText; double score = TweetAnalysis.ScoreTweet(textWithoutTags, out highlightedText); double minScoreBL = TweetAnalysis.GetScoreFromEnv("AZTWITTERSAR_MINSCORE", log, 0.01f); PublishLabel label = PublishLabel.Negative; if (score > minScoreBL) { label = PublishLabel.Positive; } log.LogInformation("A_GetBusinessLogicScore: Done."); return(new Tuple <double, PublishLabel, string>(score, label, highlightedText)); }
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); }