These instructions are for AWS. The bot has not been tested under Azure/Google functions, and may require minor modification to work in those environments.
Go to the Lambda console
- Create a function
- Function name:
dalibot - Runtime: the Python version that matches your build environment (check with
python -Vorpython3 -V) - Architecture: arm64
- Hit Create Function
- Function name:
- You should now be in the function on the Code tab. Scroll down to Runtime settings, and Edit
- Handler:
bot.lambda_handler - Hit Save
- Handler:
- Go to the Configuration tab
- Go to General configuration and Edit
- Timeout:
1min - Hit Save
- Timeout:
- Go to General configuration and Edit
Go to the API Gateway console
- Build an API of type REST API
- API Name:
dalibot - Hit Create API
- API Name:
- From the Action menu, Create a method of type POST
- Lambda function:
dalibot - Hit Save.
- Lambda function:
- Under your POST method > Integration Request:
- Expand HTTP Headers and add a header named
X-Amz-Invocation-Typemapped from'Event'(with quotes). This tells Lambda to process incoming requests asyncronously, preventing duplicate notifications from Telegram. - Expand Mapping Templates and add a mapping template for Content-Type
application/json. Scroll down and enter the following mappings and Save. This allows the bot to route the request appropriately, and read Telegram's auth header:
- Expand HTTP Headers and add a header named
{
"method": "$context.httpMethod",
"uri": "$context.path",
"Content-Type" : "$input.params('Content-Type')",
"body" : $input.json('$'),
"headers": {
#foreach($param in $input.params().header.keySet())
"$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end
#end
}
}
- From the Action menu, hit Deploy API
- Deployment stage:
[New Stage] - Stage name:
dalibot(this name forms your URI) - Hit Deploy
- Take note of the Invoke URL at the top of the stage editor
- Deployment stage:
sudo $(which apt dnf yum) install git
git clone https://github.com/robdevops/dalibot.git ~/dalibot
cd ~/dalibot
bash build_serverless.sh -p arm64
cd staging
Edit dalibot.ini
- Set
openai_api_keyto the key from OpenAI - Set
telegramOutgoingTokento a secret token of your choice - Set
telegramOutgoingWebhookto your API gateway stage Invoke URL from previous section - Set
telegramBotTokento the token provided by BotFather
Example:
openai_api_key = sk-p999HAfj6Cm1bO00SXgJc7kFxvFPtQ1KBBWrqSOU
telegramBotToken = 4839574812:AAFD39kkdpWt3ywyRZergyOLMaJhac60qc
telegramOutgoingToken = sLnHdQmYoohmysecret7PX5VDM4cPW
telegramOutgoingWebhook = https://xxxxxx.execute-api.us-east-2.amazonaws.com/dalibot
You can make stderr more verbose:
debug = 1
You can customise the bot command:
telegramBotCommand = dream
You can enable private messaging by listing telegram numeric ids separated by a space:
telegramAllowedUserIDs = 123456789 987654321
zip dalibot_arm64.zip dalibot.ini
Back in the Lambda function, go to the Code tab and then upload from .zip file, and choose dalibot_arm64.zip from your staging folder.
- Message the bot, then monitor the logs from Lambda Function > Monitor > Logs, or from the CloudWatch console under Logs > Log groups.
- The function can also be triggered in various ways, but these will fail at various points because they won't receive the Telegram json payload:
- From the Test tab in the Lambda function
- From the POST - Method execution in API Gateway console.
- With curl, for example:
curl -iH "Content-Type: application/json" -H "X-Telegram-Bot-Api-Secret-Token: yoursecret" -X POST -d '{"message": {"message_id": 1, "from": {"id": 1, "first_name": "test" }, "chat": {"id": 123, "type": "private"}, "text": "hello" }}' https://xxxxxx.execute-api.us-east-2.amazonaws.com/dalibot - If variations don't work and the error contains
ImportError: cannot import name '_imaging' from 'PIL', make sure the Python version and CPU architecture under Function > Code > Runtime settings match your build environment.
(Optional) Improved security by locking down access to Telegram IP addresses. API Gateway Console > dalibot > Resource Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "execute-api:/*/*/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"149.154.160.0/22",
"149.154.164.0/22",
"149.154.172.0/22",
"91.108.4.0/22",
"91.108.56.0/24"
]
}
}
}
]
}
