I’ve written about hosting a python based Telegram bot here before. This time we’ll take look at doing it with NET 6, C#, Azure Functions V4 and the still fresh execution mode called isolated process. In this mode, each function runs in a separate environment.
What we’ll cover
- creating a sample Azure Functions project and deploying it to your Azure subscription
- creating a Telegram Bot and using it in a webhook configuration
- NET 6 installed
- Azure Functions Core tools 4 installed
- Azure CLI installed
- Azure subscription created
- An IDE may be useful, I’m using Visual Studio Code
Check out this article for step by step instructions – https://docs.microsoft.com/en-us/azure/azure-functions/create-first-function-cli-csharp
We’ll first create the blank Azure Functions project with a sample HTTP Trigger
func init TelegramFunctions --worker-runtime dotnet-isolated cd TelegramFunctions func new --name SetUpBot --template "HTTP trigger" --authlevel "anonymous"
The above commands should create all necessary files to run the functions. There’s one manual step you need to do to use the V4 Azure Functions. Open the .csproj file in the TelegramFunctions folder and bump the version manually from v3 to:
Now you should be ready to run the Functions, do it with this command:
In the output, you should see a link to the sample HTTP trigger function called ‘SetUpBot’. It was created above with the func new command. Open the link to make sure that the Function is working properly:
Perfect! 🎊 Now let’s deploy it online. Before doing that, we first need to prepare the needed resources in Azure. Run the following scripts (make sure to update the parameters to your own names):
az login // below creates a resource group in a specified location az group create --name RESOURCE_GROUP_NAME --location germanywestcentral // below creates a storage account needed to set up the functions az storage account create --name STORAGE_ACCOUNT_NAME --location germanywestcentral --resource-group RESOURCE_GROUP_NAME --sku Standard_LRS // below creates the functions app on a Consumption plan with isolated execution mode az functionapp create --resource-group RESOURCE_GROUP_NAME --consumption-plan-location germanywestcentral --runtime dotnet-isolated --functions-version 4 --name FUNCTIONS_APP_NAME --storage-account STORAGE_ACCOUNT_NAME
… and then we’ll deploy our project:
func azure functionapp publish FUNCTIONS_APP_NAME
If everything went well (hopefully), in the output you’ll see the link to your publicly available Azure Function – after opening it in your browser, you should see the exact same output as when running it locally. Your sample function is officially alive 🎉
To start using the bot, we first need to create it, which is super easy:
- Open the Telegram app on any device and start a conversation with @ botfather
- Send this command: /newbot
- Answer his questions about the bot’s name and handle
- He’ll responsd with the bot’s token similar to the one below:
We’ll use it in the next steps. Make sure to keep it safe, anyone who has access to it can fully control your bot! 🚨
To make things easier, we’ll use the Telegram.Bot nuget for communication with the Telegram services. Add it to your project with this command:
dotnet add package Telegram.Bot --version 17.0.0
Now we’re ready to create 2 HTTP Triggered Azure Functions, we’ll do it in the SetUpBot.cs file which you should already have in your project folder.
- /setup – the first function will setup our bot to operate in a webhooks mode. This means that whenever anyone interacts with the bot, Telegram will send a POST request to the endpoint we specify (as you can see below, we specify the link to the second function, handleupdate)
- /handleupdate – this function receives the Update object from Telegram services and reacts accordingly. All of the messages, replies, images etc will arrive to this endpoint. For the purposes of this tutorial, we’ll try to evaluate user’s message as a math expression and will return the result
Both functions are using the _botClient instance, which is created in the class constructor and uses the bot token from the environment variables.
When functions are run locally, you can specify the value for the TelegramBotToken variable in the local.settings.json file. For the deployed Functions app, you can configure it with the below command:
az functionapp config appsettings set --name FUNCTIONS_APP_NAME --resource-group RESOURCE_GROUP_NAME --settings "TelegramBotToken=YOUR_BOT_TOKEN"
Deploy the updated project with the same command as before:
func azure functionapp publish FUNCTIONS_APP_NAME
In the output, you’ll see 2 links to our Functions – before talking to the bot, we first need to open the /setup link, which will configure the bot to call our second function.
Then we should be ready to get some answers from the bot. Start a conversation with it on Telegram and either try to ask some math questions or try to recreate the Space Oddysey scene (at your own risk!) ☺️
Things are working as expected, that’s great! I’m positively surprised how fast the interaction is – the questions go through and back the Telegram API & Azure in a blink of an eye as you can see above 👁
After you’re done, make sure to remove the Azure resources you’ve created, you don’t want to pay for the resources that you don’t use. Deleting the whole resource group can be done with the following command:
az group delete --name RESOURCE_GROUP_NAME
Now that you know how to use Azure Functions as the brain for your bots, diving deeper into documentations might give you some nice ideas on what to do next. The API is quite rich, you can create pools, send locations, even accept payments or validate user’s identity with Telegram Passport.
Also before deploying your Bot, it might be wise to think twice about the security of your API. The setup function above should probably be authenticated with a Function access key. The handleupdate function could also have a password/token in the URL, to make sure that the request comes from Telegram services.
Let me know if you’d have any questions/problems with creating the bots with Azure Functions, I’d be happy to help 🚀
Follow me on Twitter for more insights about Azure 🚀
Michał Żołnieruk@michalzolnierukYour app generates #Azure Blob Storage links using SAS tokens? Here's how you can show a descriptive expiration message to your users 👨💻 (instead of a harsh XML error) miszu.medium.com/handling-expir… @AzureFunctions #Microsoft365Dev #azurefunctions08:03 AM - 11 Feb 2021