不到 40 行代码实现 Telegram 自动发消息机器人

创建一个 Telegram 机器人,定时发送消息,并部署到 AWS Lambda。

AWS Lambda 是一项计算服务,可使你无需预配置或管理服务器即可运行代码。

我们要做什么?

  • 创建一个 Telegram 机器人
  • 自动发送日常信息
  • 把它部署到 AWS Lambda

需要准备什么?

  • 一个 Telegram 帐号
  • Python 3.6
  • Node.js
  • 一个 AWS 帐号

AWS Lambda 可以在一定配额内免费使用,所以需要避免发送大量请求。

AWS Lambda 定价方案如下:

创建机器人

待办清单上的第一件事是创建一个机器人,遵循 Telegram 官方说明:

  • 在 Teletram 中搜索用户 @BotFather
  • 发送命令 /newbot 并为你的机器人指定 nameusername
  • 拿到 token 并记录在一个安全的地方,后边会用到。

现在机器人准备好了,开始编写代码。

准备部署设施

有很多部署 Lambda 的方法,我准备使用 serverless 框架,所以我们先来安装它:

1
$ npm install serverless --global

Serverless 的文档中提供了一些范例,还支持生成模板,像下边这样:

1
$ serverless create --template aws-python3 --path scheduled_telegram_bot

执行这个命令后,会创建出一个 scheduled_telegram_bot 目录,并已经生成了 3 个文件:
.gitignoreserverless.ymlhandler.py

serverless.yml 文件用来描述:部署什么、何时运行、如何运行。 handler.py 文件包含将要运行的代码,所以我们先来编写它。

编写代码

我们将使用是一个封装好的包来调用 Telegram 的 API:python-teletram-bot,创建一个新的文件 requirements.txt 写入:

1
python-telegram-bot==12.2.0

我们需要在程序中导入这个库,不过后边我们会遇到一个问题:由于 python-telegram-bot 不是 AWS Lambda 所提供的标准库,因此我们在部署时需要同时包含这个包中的文件。

所以我们后边会在本地安装这个包的所有内容。现在让我们来定义一个发送消息的函数,打开 handler.py 修改内容如下:

1
2
3
4
5
6
7
8
9
10
import telegram
import os

TOKEN = os.environ['TELEGRAM_TOKEN']
CHAT_ID = 000000 # Change this


def send_message(event, context):
bot = telegram.Bot(token=TOKEN)
bot.sendMessage(chat_id=CHAT_ID, text='Hey there!')

你需要把 CHAT_ID 修改为你想让机器人互动的群组、频道或者会话的 ID。获取 ID 的方法如下,我以频道为例:

首先创建自己的频道,将机器人拉入频道并设置为管理员,随意在频道内发送一个消息。

添加 GetIDsBot,并将上边发的那条消息转发给这个机器人,它会返回这个频道相关信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
👤 You
├ id: xxxxxxx
├ is_bot: false
├ first_name: xxxxx
├ username: xxxxxx
├ language_code: zh-hans (-)
└ created: ~ 9/2017 (?)

💬 Origin chat
├ id: -1001156324531
├ title: Panmax Channel
└ type: channel

📃 Message
├ message_id: 82
└ forward_date: Fri, 15 Nov 2019 15:38:41 GMT

这样可以得到我所在这个频道的 ID 为 -1001156324531

部署定义

现在我们来定义如何运行我们的代码。

编辑 serverless.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
service: scheduled-telegarm-bot

frameworkVersion: ">=1.2.0 <2.0.0"

provider:
name: aws
runtime: python3.6
environment:
TELEGRAM_TOKEN: ${env:TELEGRAM_TOKEN}

functions:
cron:
handler: handler.send_message
events:
- schedule: cron(*/2 * * * ? *)

这里我们告诉了 AWS 我们所需要的运行环境,并且让它从我们的环境变量中获取 Telegram token,这样我们就不需要把 token 硬编码到代码中了。

最后我们还定义了一个定时器,声明每两分钟触发一次这个函数。当然,定时器有很多选项,通过这个文档可以了解更多配置方式,比如每小时或者每周一发送消息。

汇总

我们已经准备好了所有需要的东西。

好吧,准确来说是几乎所有的东西。我们还需要获取 AWS 的凭证,然后和 token 一样,在部署前设置为环境变量,获取凭证步骤如下:

通过 AWS 的控制台:

进入 我的安全凭证 - 用户 - 添加用户

设置用户名并选择编程访问

下一步:选择直接附加现有策略 - AdministratorAccess

下一步会来到添加标签页,直接点击下一步,确认信息无误后点击 创建用户,将 访问密钥 ID私有访问密钥 拷贝并存放起来。

现在,让我们把 AWS 凭证和 Telegram token 导出到环境变量。打开终端,输入:

1
2
3
$ export AWS_ACCESS_KEY_ID=[your key goes here]
$ export AWS_SECRET_ACCESS_KEY=[your key goes here]
$ export TELEGRAM_TOKEN=[your token goes here]

在本地安装 Python 的依赖包(这也是 AWS Lambda 所需要的):

1
$ pip3 install -r requirements.txt -t .

最后将所有的东西部署到 AWS:

1
$ serverless deploy

如果前边配置没有问题,会看到如下输出:

1
2
3
4
5
6
7
8
9
10
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service scheduled-telegarm-bot.zip file to S3 (5.64 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
.........
Serverless: Stack update finished...

完成!机器人会在每 2 分钟给我们发送一次消息。

参考

AWS Python Scheduled Cron Example:https://github.com/serverless/examples/tree/master/aws-python-scheduled-cron