In this article, you will learn how to connect the Amazon Lex service to your telegram bot. We will create a bot in Amazon Lex, configure a role, add the code and test it.
Introduction
Everybody has messengers today. We all use messengers every day - they are convenient and easy to use, intuitive, safe, and, of course, we all love stickers. In addition to personal correspondence, we also use group chats - with family, friends and colleagues. In addition, we use a variety of kind of bots. They are created to automate responses. That is, the bot reacts to specific messages - commands and performs some actions.
In my previous article, I described how to create a Telegram bot using C# and publish on Amazon Web Services. However, it has several cons. One of them is from the point of view of an ordinary user, messages must have a strict format up to a symbol, or you need to implement a menu with already available commands. In this article, I want to tell you how to give this bot a little intelligence using the Amazon Lex
service. Moreover, Amazon Lex
can act as a single service for managing your bots, no matter Telegram or Facebook, or built-in chat bots on websites. I will show you how to create a response message for a customer
in an online store who has certain problems with the delivery of goods. Structure of our service is shown in Image 1.
Image 1 - Structure of our service
Creating Amazon Lex Bot
First, we need to go to the Amazon Lex service.
Here, we select to create a new bot. Since there is no right template, we choose to create our own bot (Image 2).
Image 2 - Creating the Lex Bot
Fill in Bot name
, Language
, output voice
, session timeout
, COPPA
. Then press the Create
button. After that, we will get to the bot control window (Image 3).
Image 3 - Control Window of Bot
Click Create Intent
and give it a name. The first will be with the title Intent with the title Welcome. Let's create a couple of possible scenarios of action (Image 4).
Image 4 - Sample utterances of bot
Next, open the Response
tab and create a message (Image 5).
Image 5 - Response of Lex bot
Click the Save Intent button and fill in another one. Next, the new script will ask for the order number and then respond to the request (Image 6).
Image 6 - Order issue utterances
Next, we will create a new slot by going to the Slots
tab and creating AMAZON.NUMBER
with the name order and Slot type (Image 7).
Image 7 - Creating a new slot
Next, let's create a new Response
(Image 8).
Image 8 - Response of Lex bot
Click Save Intent.
For our example, handling two events is already enough. You can add a lot more scripts to handle a user's request, but I'm showing you a simple example of Amazon Lex, Lambda and Telegram integration.
Next, click the Build button, and then we can test the bot in the Test Bot
window (Image 9,10).
Image 9 - Testing of bot, Part 1
Image 10 - Testing of bot, Part 2
Next, press the Publish button and select Alias (Image 11).
Image 11 - Publishing of bot
The Amazon Lex bot is ready.
Creating a Role of IAM
In order for our Lambda function to process requests from the bot, we need to edit the role that we used in the previous example.
Do not forget that in order to work with Amazon Lex, we must have special permissions set in Roles. Using a role is much safer than storing access keys in your bot code, so let's go to IAM
and find Basic Lambda
role (I created it to work with Amazon Lambda). Let's go to the IAM service, go to the Roles tab and find the required role (I used Basic Lambda) (Image 12).
Image 12 - To find the role
Next, click on the role and select Attach policies and add Policy AmazonLexFullAccess (Image 13).
Image 13 - Attaching policies
Role setup complete.
Making Code of Lambda Bot
First, we need to add the required Nuget
packages. We need AWSSDK.Lex
and Amazon.Lambda.Core
packages (Image 14).
Image 14 - Adding packages
In the previous article, we wrote the code for the classes.
class Connect
{
private readonly TelegramBotClient botClient;
private readonly ILogger<Connect> logger;
public Connect()
{
this.botClient = new TelegramBotClient("!!!!!!Your token");
}
public async Task RespFromTelegram(Update update)
{
if (update == null)
{
return;
}
if (update.Type != UpdateType.Message)
{
return;
}
var message = update.Message;
this.logger?.LogInformation("Received Message from {0}", message.Chat.Id);
switch (message.Type)
{
case MessageType.Text:
await this.botClient.SendTextMessageAsync
(message.Chat.Id, message.Text);
break;
}
}
}
The second:
static Function()
{
lambdaClient = new AmazonLambdaClient();
connect = new Connect();
}public async Task<string> FunctionHandler(JObject request, ILambdaContext context)
{
LambdaLogger.Log("REQUEST: " + JsonConvert.SerializeObject(request));
try
{
var updateEvent = request.ToObject<Update>();
await connect.RespFromTelegram(updateEvent);
}
catch (Exception e)
{
LambdaLogger.Log("exception: " + e.Message);
}
return "Hello from AWS Lambda" + DateTimeOffset.UtcNow.ToString();
}
First, let's add libraries to Connext.cs:
using Amazon.Lex;
using Amazon.Lex.Model;
Next, we will create a new task. Since it will return only a text message, we will specify string
as the return value. As parameters, we will specify two variables of the string
type - this is the message
text from the user and chatid
.
public async Task<string> ConnectLex(string text, string chatid)
Next, we need to create a new object of the AmazonLexClient
class. Let's choose the default constructor.
var amazonLexClient = new AmazonLexClient();
Next, we will create objects for the request and response from the Lex bot. To do this, we use the PostTextRequest
and PostTextResponse
classes from Amazon.Lex.Model
.
var amazonPostRequest = new Amazon.Lex.Model.PostTextRequest();
var amazonPostResponse = new Amazon.Lex.Model.PostTextResponse();
Next, let's fill in the attributes of the amazonPostRequest
object.
amazonPostRequest.BotAlias = "dev";
amazonPostRequest.BotName = "MyBot_lex";
amazonPostRequest.InputText = text;
amazonPostRequest.UserId = chatid;
Next, let's send the text for processing using the asynchronous method:
amazonPostResponse = await amazonLexClient.PostTextAsync(amazonPostRequest);
Let's specify the response from the Lex bot as the return value:
return amazonPostResponse.Message.ToString();
As a result, at this stage, we should get the following code:
public async Task<string> Conne(string text, string chatid)
{
var amazonLexClient = new AmazonLexClient();
var amazonPostRequest = new Amazon.Lex.Model.PostTextRequest();
var amazonPostResponse = new Amazon.Lex.Model.PostTextResponse();
amazonPostRequest.BotAlias = "dev";
amazonPostRequest.BotName = "MyBot_lex";
amazonPostRequest.InputText = text;
amazonPostRequest.UserId = chatid;
amazonPostResponse = await amazonLexClient.PostTextAsync(amazonPostRequest);
return amazonPostResponse.Message.ToString();
}
Next, we need to change the code in the RespFromTelegram
method.
Let's send a request from the user to the return
.
string LexResp = await ConnectLex (message.Text, message.Chat.Id.ToString());
Next, we will send a response from the Lex bot to Telegram:
await this.botClient.SendTextMessageAsync(message.Chat.Id, LexResp);
As a result, at this stage, you should get the code:
private readonly TelegramBotClient botClient;
private readonly ILogger<Connect> logger;
public Connect()
{
this.botClient = new TelegramBotClient("YOUR TOKEN");
}
public async Task RespFromTelegram(Update update)
{
if (update == null)
{
return;
}
if (update.Type != UpdateType.Message)
{
return;
}
var message = update.Message;
this.logger?.LogInformation("Received Message from {0}", message.Chat.Id);
switch (message.Type)
{
case MessageType.Text:
string LexResp = await Conne(message.Text, message.Chat.Id.ToString());
await this.botClient.SendTextMessageAsync(message.Chat.Id, LexResp);
break;
}
}
public async Task<string> Conne(string text, string chatid)
{
var amazonLexClient = new AmazonLexClient();
var amazonPostRequest = new Amazon.Lex.Model.PostTextRequest();
var amazonPostResponse = new Amazon.Lex.Model.PostTextResponse();
amazonPostRequest.BotAlias = "dev";
amazonPostRequest.BotName = "MyBot_lex";
amazonPostRequest.InputText = text;
amazonPostRequest.UserId = chatid;
amazonPostResponse = await amazonLexClient.PostTextAsync(amazonPostRequest);
return amazonPostResponse.Message.ToString();
}
Testing and Publishing
At this point, we need to test the request locally.
Let's start debugging and enter the request in Json
format.
{
"update_id":1,
"Message":{
"message_id":"1",
"date": "20210612",
"text":"Hello",
"chat":{
"id":{YOUR TELEGRAM ID,
"type":"private",
}
}
}
You should receive the result directly in Telegram in private messages from the bot. An example is shown in Image 15.
Image 15 - Locally testing bot
In this picture, I have hidden my ID, but you can find out your ID when exporting any of your chats.
We can now publish on the Amazon Lambda service (Image 16).
Image 16 - Uploading Lambda function
After publishing, let's go to Amazon service and test with exactly the same Json code. You should receive exactly the same answer in your telegram account. If something doesn't work, you'll get a message in aws Lambda. The first time I did, I had a problem with assigning permissions to a role.
Conclusion
As a result, in this article, I showed you how to connect the Amazon Lex service to your telegram bot. We created a bot in Amazon Lex, configured a role, added the code and tested it.
History
- 18th June, 2021: Initial version