How to integrate Azure Functions, GIPHY and Microsoft Teams?

Today I have pretty funny topic to show you all - we'll try to create a simple Azure Function, which will... find a random GIF image and post in on a channel in Microsoft Teams! Why such article? Well, we can't always do serious things :)

To bo honest, such triangle shows easily how to achieve integration on a corporate level using minimal resources. 

Setup

To start you have to have a Microsoft Teams channel created. I won't go into details of creating one(since it's pretty basic stuff) and just assume, you already have one. What we're interested in are the Connectors available:

When you click on the menu item, you'll see a window with many available connectors. We're searching for a particular one named Incoming Webhook:

When you click Configure, you'll see a simple wizard where you can insert a name of a WebHook and select an image. Once you click Create, a webhook URL will be provided so copy and save it. It'll look like this:

https://outlook.office.com/webhook/.../IncomingWebhook/.../...

Now we have to create a function.

Function

I decided to create a function, which will be triggered from Monday to Friday at 9:30 AM. To do so selected TimerTrigger with the following signature:

[TimerTrigger("0 30 9 * * 1-5")]TimerInfo myTimer

The whole code looks like this:

/
public static class GiphyTrigger
{
	private const string WebhookUrl = "https://outlook.office.com/webhook/.../IncomingWebhook/.../...";

	private static Lazy<HttpClient> HttpClient = new Lazy<HttpClient>(() => new HttpClient());

	[FunctionName("GiphyTrigger")]
	public static async Task Run([TimerTrigger("0 30 9 * * 1-5")]TimerInfo myTimer, TraceWriter log)
	{
		log.Info($"C# Timer trigger function executed at: {DateTime.Now}");

		var randomGif = await HttpClient.Value.GetAsync("https://api.giphy.com/v1/gifs/random?api_key=...&tag=&rating=PG-13");
		var content = await randomGif.Content.ReadAsStringAsync();
		var model = JsonConvert.DeserializeObject<GiphyModel>(content);

		log.Info($"Sending GIF to Microsoft Teams");
		var result = await HttpClient.Value.PostAsync(WebhookUrl, new StringContent($"{{\"@type\": \"MessageCard\",\"@context\": \"http://schema.org/extensions\",\"summary\": \"This is GIF\",\"themeColor\": \"0075FF\",\"sections\": [{{\"startGroup\": true,\"title\": \"**GIPHY says:**\",\"text\": \"![Text]({model.Data.Url})\"}}]}}"));

		result.EnsureSuccessStatusCode();
		log.Info($"Result is {result.StatusCode}");
	}       
}

public sealed class GiphyModel 
{
		public GiphyDataModel Data {get;set;}
}

public class GiphyDataModel
{
	public string Title {get;set;}
	[JsonProperty("image_url")]
	public string Url {get;set;}
}

In general it's more or less generic code, which calls GIPHY API and obtains a random gif. One thing is important however - when calling a webhook, the body of a request is a valid Actionable message, which is a special schema used within Office 365. You can find more info here.

Result

When a function is triggered, you may see following result:

I named my webhook Squirrel Commando, and now it greets me everyday with a random GIF. Of course you can use Incoming Webhooks in Microsoft Teams for more serious tasks(like some reports, alerts or notifications) and integrate all using Azure Functions(with Consumption Plan it'll cost you almost nothing...) - with such generic functionality, only the sky is the limit.

Working with Azure Functions in Visual Studio Code like a boss

So after a while I decided to finally check Azure Functions extensions out in Visual Studio Code. I often want to check something really quickly and being forced to open Visual Studio each time makes me furious. I must say that initially I was a bit skeptical regarding Code functionality, but it turns out to be superb. Let's check what it offers for now.

Installing

Installing the extensions is super easy. Just go to the Extensions menu and search for Azure Functions:

Once extensions is installed you can easily disable or uninstall it

For now - that's really all!

Creating a function

With Azure Functions plugin installed you should be able to see available subscriptions in the Explorer area. If not left-click on the status bar where your username is displayed and select the ones you're interested in:

Workspace with only one subscription selected

 

Installing the extension gives you some more features. Now you're able to work with a project, create a function and publish it. Let's start with a function triggered by a HTTP request. Click on "Create New Project Button":

Now you're able to select a current location or create a new one where your project will be placed. Once you're satisfied you can select a language and... that's all, your workspace is ready to start working on a function.

Empty Functions project ready to rock!

Now let's create a function. You can create in in a similar way as a project. After providing all necessary data(like a name, a type of trigger, security level), a template will be created so you can start modyfing it as you wish.

A template, very similar to the one created in Visual Studio

Running a function

You can easily start testing your function by pressing F5. It'll start runtime and you'll be given an endpoint, which you can call anytime:

Publishing a function

Publishing a function from Visual Studio Code is as easy as other tasks. Once more go to the Azure Functions workspace and select "Deploy to Function App". You'll be asked about many different parameters like a subscription, resource group or storage account. Once everything's configured wait a second(or maybe two) until a function is published. You can start using it!

Function published along with a storage account and consumption plan

Summary

In the current shape VS Code will not replace full Visual Studio(at least for me personally), but I found Azure Functions extension extremely helpful in the smaller projects, which are developed fully in Code. If I don't have to switch between IDEs, I'm more than happy.