One of the promotion methods that many bloggers employ with Twitter is to re-tweet their previous blog post tweets with an "In Case You Missed It" (#ICYMI) tag a few hours or days later. In this blog post, and the next one, I'm going to show you a couple of ways you can implement this in Microsoft Flow.

Setup

We'll start by creating a new Flow from the blank template. You can see my previous posts on how to do this. I won't repeat it here.

In this case, we want this process to run on a regular schedule. Because tweets can go by fast, people can miss your initial post. Re-tweeting it once or twice over next 6-48 hours or so is generally the standard. But be careful. Too many #ICYMI tweets can really annoy your followers, so keep that in mind.

How often you run the process will depend on how often you blog. In my case, I generally post sporadically and I'm going to set up this Flow to retweet just once, somewhere between 6 and 9 hours later. So, given that objective, I will run the process every 3 hours.

Our Trigger for this flow will be the Recurrence Trigger. So select that as the starting point of our Flow. It has two parameters, Interval and Frequency. We want this Flow to run every 3 hours, so let's enter 3 and Hour for our values.

Initialize Variables

We're going to make this Flow more complex than necessary so that you can get a feel for how some more of the features of Flow work, and to make it extremely simple to follow the steps.

Variables in Microsoft Flow must all be declared at the top of the Flow. You cannot create variables further down. So immediately after the Recurrence Trigger, we are going to add 5 Initialize Variable actions. We will create three of type Integer, and two of type String. The order doesn't really matter. We will create them as follows:

Name Type Value
startTime Integer sub(ticks(addHours(utcNow(), -6)), ticks(utcNow()))
endTime Integer sub(ticks(addHours(utcNow(), -9)), ticks(utcNow()))
tweetTime Integer 0
strTweetTime String Leave this empty
tweetText String Leave this empty

The tweetTime and strTweetTime will be used later in our Flow when we're looking for tweets to re-tweet. The startTime and endTime values are used to define the start and ending values for the time period we want to consider for re-tweets. We're going to take a closer look at the Value for those two variables.

I should note here that Flow does not have a great deal of functionality for working with. Specifically, for this case, there is no "between" functionality. There isn't even a greater than or less than functionality for date/time values. So the easiest way to approach this is to convert each date/time value to a number using the ticks() function.

Expressions

Both of these variables have similar formulas, so let's just examine the startTime value. In a great many places in Flow, you can use what they call an "Expression" to represent a value. If you are familiar with formulas in Excel spreadsheets, they work almost exactly the same way. You put together a set of functions, values and calculations to figure out the end value you want to get out of it.

In the startTime variable, the Expression is:

sub(ticks(addHours(utcNow(), -6)), ticks(utcNow()))

This breaks down as follows.

  • utcNow(): In two places we get the current datetime
  • addHours(): On the leftmost one, we subtract 6 hours from it, to get the time 6 hours ago
  • ticks(): We convert both time values to ticks (Integers)
  • sub(): We subtract the ticks to get the total number of ticks between now and 6 hours ago

The resulting value is then stored in the startTime variable. We'll use the startTime and endTime values later.

Get the Twitter Data

After we've declared our variables, it's time to get our most recent tweets from Twitter. In this case we'll use the Twitter action "Get user timeline". The required parameter is the username of the Twitter user you want to get Tweets for. This should be whatever account you're using to post tweets about your blog posts.

Under the advanced options, you can also select the number of most recent tweets to retrieve. The current default is 20. You'll want to consider how many tweets you make in a day and make sure this number is high enough that it will cover the number of tweets you make in the time period you're looking at. In our example, that's 9 hours.

Loop Through the Twitter Data

One of the outputs of the "Get user timeline" action is called "Body". This is an array of the tweets that were retrieved from the user timeline. We'll use that to iterate through each tweet, looking for the tweets we want to repost with the #ICYMI tag.

This can get extremely complicated if you want it to be. You can created all kinds of in depth, nested Expressions to determine if a tweet is a retweet, or a reply, or whatever else. Truth is, looking at the raw data, it can be pretty difficult to tell which tweets might be something posted by your previous Flow and which might be something you typed in and posted manually. But we will employ a slightly less complex method here.

First, go back to the Flow you created previous that posts the original tweet that you want to retweet. In the "Tweet text" field of the "Post a tweet" action, add a small hashtag at the end. Use something fairly unique or uncommon that you wouldn't put in your other tweets. For this example, I'll use the hashtag #blog. It's still going to be a complex Expression, but this will eliminate a lot of the mess.

Next we need a looping structure to work through. Add a new action at the bottom of the Flow and search for the "Apply to each" action. This has one parameter which requires an array output from a previous step. In this case we will select the "Body" output from the Twitter "Get user timeline" action.

The "Apply to each" action will loop through the data array you selected and perform a block of actions on each item. It's your standard For/ForEach construct from any programming language.

Initialize the Loop

Again, while not really necessary, we're going to break some of the Flow into smaller pieces for the sake of simplicity and understanding. So we'll start by setting some variable values from the current array item. At the top of the "Apply to each" block, we're going to add three "Set variable" actions.

For the first one, we're going to set the variable tweetText equal to the "Tweet text" value. For the second one, we're going to set the variable strTweetTime to the "Created at" value.

For the third, we're going to set the variable tweetTime to the ticks() value of the strTweetTime variable we just set. Make sure this is done after you set the strTweetTime variable. The Expression we're going to use here is:

sub(ticks(variables('strTweetTime')), ticks(utcNow()))

This Expression works just like the two we set way back up at the top.

Conditional Actions

The next step will be a couple of Condition actions. We could put it all into one, but I'm splitting it into two for readability. At the bottom of our Flow, add a "Condition" action. This will require an advanced condition, so click the "Edit in advanced mode" on your newly created Condition.

Now that we've got our time range in ticks and the tweet time in ticks, we're going to check whether the tweet falls into the time range we're looking at. So add the following Expression into the box.

@and(greater(variables('tweetTime'), variables('endTime')), lessOrEquals(variables('tweetTime'), variables('startTime')))

If the tweet falls into that time range (in ticks), we perform the "If yes" block. Otherwise, it's the "If no" block. We'll leave the "If no" block blank as we don't want to do anything to tweets outside our time range.

In the "If yes" block, we're going to add a second Condition action. In this Condition, we are going to check to make sure the tweet contains our #blog hashtag, but doesn't contain a #ICYMI hashtag. That we, we're making sure we only retweet it once.

The Expression for the second Condition will be as follows:

@and(contains(variables('tweetText'), '#blog'), not(contains(variables('tweetText'), '#ICYMI')))

This Expression will check that the tweetText does contain the text "#blog" and does not contain the text "#ICYMI".

Post Our Retweet

Again, for this Condition, we will leave the "If no" block empty. In the "If yes" block, we will be updating the tweetText to add the text "#ICYMI" and then post a new tweet with our updated text.

First, we'll update our text. Add a "Set variable" action. The Name is our variable tweetText and for our Value, first click in the box and add tweetText from the list that appears. Then click to the right of the added variable and type " #ICYMI" (without the quotes).

Now add a "Post a tweet" action below this and in the Tweet text field, click and add tweetText from the list that appears to the right.

Fin

And that's it! Save your Flow and it will start running. You now have a dirty, ugly, but free, means of rolling your own "In Case You Missed It" tweets for your blog posts. Remember that the free tier of Flow only gives you 2000 runs per month. So consider your other Flows and the numbers you use in this Flow for how often you check. Not a big concern if you only check every few hours and only have a couple Flows, but anyone who manages Azure or AWS subscriptions can tell you: Them numbers can add up fast!

Next time I'll walk you through a somewhat easier way of managing your ICYMI tweets by using an Azure data table.