Example #1
0
        public static async Task Run(
            [QueueTrigger("visionscanner")] string tweetQuery,
            [Table("visiontweet")] CloudTable visionTweetTable,
            [Queue("visionscanned")] IAsyncCollector <string> visionScannedQueue,
            TraceWriter log)
        {
            log.Info($"VisionScanner processing TweetId: {tweetQuery}");

            long          tweetId              = long.Parse(tweetQuery);
            long          originalTweetId      = tweetId;
            List <string> screenNamesToReplyTo = new List <string>();

            var           service     = Helper.TwitterService();
            TwitterStatus tweet       = null;
            TweetEntity   tweetEntity = null;

            while (tweet == null)
            {
                //moving this check inside the while loop to stop processing retweets
                var tweetDetails = Helper.FetchTweetFromStorage(tweetId.ToString());
                if (tweetDetails != null) //already processed
                {
                    log.Info($"VisionScanner Already Processed TweetId: {tweetId}");
                    return;
                }

                tweet = service.GetTweet(new GetTweetOptions
                {
                    Id = tweetId,
                    IncludeEntities = true,
                    TweetMode       = TweetMode.Extended
                });

                //build up mentions list for replyto - will distinct later
                screenNamesToReplyTo.Add("@" + tweet.User.ScreenName);
                foreach (var mention in tweet.Entities.Mentions)
                {
                    screenNamesToReplyTo.Add("@" + mention.ScreenName);
                }

                tweetEntity = new TweetEntity(tweet);

                //no media? try the parent
                if (!tweet.Entities.Media.Any())
                {
                    log.Info($"VisionScanner No media found in TweetId: {tweetQuery}");

                    // Documentation Link: Add an entity to a table - https://cda.ms/nn
                    visionTweetTable.Execute(TableOperation.Insert(tweetEntity));

                    if (tweet.InReplyToStatusId == null)
                    {
                        //walked up the whole chain - no media found
                        return;
                    }
                    else
                    {
                        tweetId = ((long)tweet.InReplyToStatusId);
                        tweet   = null;
                    }
                }
            }

            var mediaDesc = new MediaDescription(tweet.Id);

            var photos = tweet.Entities.Media.Where(m => m.MediaType == TwitterMediaType.Photo);

            foreach (var media in photos)
            {
                log.Info($"VisionScanner FetchVisionDescriptionAsync TweetId/MediaId: {tweetQuery}/{media.Id}");
                var vision = await Helper.FetchVisionDescriptionAsync(tweet, media);

                mediaDesc.VisionDescription.Add(media.IdAsString, vision);
            }

            tweetEntity.VisionJson = JsonConvert.SerializeObject(mediaDesc);

            // Documentation Link: Add an entity to a table - https://cda.ms/nn
            visionTweetTable.Execute(TableOperation.Insert(tweetEntity));

            var dto = new TweetScannedDTO
            {
                TwitterStatus    = tweetEntity.BuildTwitterStatus(),
                OriginalTweetId  = originalTweetId,
                UsersToReplyTo   = screenNamesToReplyTo.Distinct().ToArray(),
                MediaDescription = mediaDesc
            };

            log.Info($"VisionScanner Queuing VisionScanned TweetId: {tweetQuery}");
            await visionScannedQueue.AddAsync(JsonConvert.SerializeObject(dto));

            log.Info($"VisionScanner processed TweetId: {tweetQuery}");
        }
Example #2
0
        public static void Run([QueueTrigger("visionscanned")] string tweetEntity,
                               [Table("visiontweet")] CloudTable visionTweetTable,
                               TraceWriter log)
        {
            TweetScannedDTO dto = JsonConvert.DeserializeObject <TweetScannedDTO>(tweetEntity);

            log.Info($"VisionScanned function processing TweetId: {dto.TwitterStatus.Id}");
            var service = Helper.TwitterService();

            foreach (var vision in dto.MediaDescription.VisionDescription)
            {
                var jsonUrl    = string.Format(Helper.GetEnvironmentVariable("JsonDetailsUrlFormat"), dto.OriginalTweetId);
                var confidence = vision.Value.description.captions[0].confidence;

                string captionPrefix = "Caption";
                if (confidence < .2)
                {
                    captionPrefix = "Guessing";
                }
                else if (confidence < .4)
                {
                    captionPrefix = "Unsure";
                }
                else if (confidence < .6)
                {
                    captionPrefix = "Maybe";
                }
                else if (confidence < .8)
                {
                    captionPrefix = "Probably";
                }

                var replyToNames = string.Join(" ", dto.UsersToReplyTo);
                var status       = $"{replyToNames} Confidence: {confidence,0:P2}" +
                                   $"{Environment.NewLine}{Environment.NewLine}" +

                                   $"{captionPrefix}: {vision.Value.description.captions[0].text}" +
                                   $"{Environment.NewLine}{Environment.NewLine}" +

                                   "Tags: {0}" +
                                   $"{Environment.NewLine}{Environment.NewLine}" +

                                   "Full API Result: {1}";

                const int TCO_LENGTH             = 22;
                const int MAX_LENGTH             = 230;
                const int LINE_BREAKS_CHAR_COUNT = 12;
                //replyToNames are not counted in tweet length
                var spaceAvailable = MAX_LENGTH - status.Length - TCO_LENGTH - LINE_BREAKS_CHAR_COUNT + replyToNames.Length;

                var tags      = new List <string>();
                var tagLength = 0;
                foreach (var tag in vision.Value.description.tags)
                {
                    tagLength += tag.Length + 2; //2 is for the ", " when joined
                    if (tagLength > spaceAvailable)
                    {
                        break;
                    }

                    tags.Add(tag);
                }

                status = string.Format(status, string.Join(", ", tags), jsonUrl);

                log.Info($"VisionScanned function Sending Tweet: {dto.TwitterStatus.Id} - {status}");

                var options = new SendTweetOptions
                {
                    Status            = status,
                    InReplyToStatusId = dto.OriginalTweetId,
                    TrimUser          = false
                };

                var sentStatus = service.SendTweet(options, (tweet, response) =>
                {
                    if (response.StatusCode != HttpStatusCode.OK)
                    {
                        //if a tweet fails to send we log it, in table storage
                        var failedTweet = new FailedTweetEntity(dto.TwitterStatus)
                        {
                            TweetJson = JsonConvert.SerializeObject(response)
                        };

                        // Documentation Link: Add an entity to a table - https://cda.ms/nn
                        visionTweetTable.Execute(TableOperation.Insert(failedTweet));

                        log.Error($"VisionScanned Failed to Send TweetId: {dto.TwitterStatus.Id}, Response: {failedTweet.TweetJson}");
                        throw new Exception(response.StatusCode.ToString());
                    }
                });
            }

            log.Info($"VisionScanned function processed TweetId: {dto.TwitterStatus.Id}");
        }