Telegram 机器人支持两种方式:轮询和 Webhook。为了节约资源我们将使用 Webhook 的方式开发 Telegram 机器人。

本章代码在01/webhook分支。

创建一个机器人

只需要简单的和BotFather对话,即可创建机器人。注意,在创建成功后,会显示一个Token,这个 Token 是非常重要的,后续的所有操作都需要它。

你可以通过官方文档获取帮助。

流程重现

以下内容中,> 开头的是你要输入的内容,< 开头的是 Telegram 返回的内容,【】里的内容是本站提供的注释。

以下流程是在和BotFather对话后进行:

>  /start

< I can help you create and manage Telegram bots. If you're new to the Bot API, please see the manual (https://core.telegram.org/bots).

You can control me by sending these commands:

/newbot - create a new bot
/mybots - edit your bots [beta]
...

> /newbot

< Alright, a new bot. How are we going to call it? Please choose a name for your bot.

> AXUM.RS  【你的机器人叫什么名称】

< Good. Now let's choose a username for your bot. It must end in `bot`. Like this, for example: TetrisBot or tetris_bot.

> axum_rs_bot 【你的机器人的用户名】

< Done! Congratulations on your new bot. You will find it at t.me/axum_rs_bot. You can now add a description, about section and profile picture for your bot, see /help for a list of commands. By the way, when you've finished creating your cool bot, ping our Bot Support if you want a better username for it. Just make sure the bot is fully operational before you do this.

Use this token to access the HTTP API:
【此处就是你的TOKEN,请妥善保存】
Keep your token secure and store it safely, it can be used by anyone to control your bot.

开发 Webhook

一旦机器人接收到新消息,Telegram 会通过 Webhook 进行通知,我们要做的就是处理它的通知信息。它的通知方式为,以 POST 方式将 JSON 格式的消息发送到 Webhook。

假设,我们的 Webhook 是 https://tg.axum.rs/,那么它是这样通知的:

curl -X POST -H 'content-type:application/json' -d '{{"update_id":994028499, "message" ...}' https://tg.axum.rs/

为此,我们先从路由开始:

路由定义

let app = Router::new().route("/", routing::post(handler::hook).get(handler::index));

路由非常简单,只需要定义一个接收POST请求的处理器就好了。本例中的get(handler::index)仅作演示,你可以只定义POST而不处理GET

hander

我们只关注 hook()。它将接收到的 JSON 数据反序列化为Update结构体。

数据结构

#[derive(Deserialize, Debug)]
pub struct Update {
    pub update_id: u64,
    pub message: Message,
}

#[derive(Deserialize, Debug)]
pub struct Message {
    pub message_id: u64,
}

可以看到,目前为止数据结构非常简单。

  • Update:每次有新消息发送到机器人的时候,Telegram 就会向 Webhook 发送一个序列化为 JSON 的Update对象

  • Message:它包含了新消息的详细数据

注册 Webhook

使用 ngrok 内网穿透进行本地开发

Webhook 必须满足以下条件:

  • 必须是公网可访问

  • 必须是域名

  • 必须是HTTPS协议

很明显,如果我们在开发期间就去折腾这些非常低效,好在有ngrok,它可以实现内网穿透,将本地开发环境暴露给公网。

向 Telegram 注册 Webhook

现在可以向 Telegram 注册我们的 Webhook:

https://api.telegram.org/bot<你的TOKEN>/setWebhook?url=<你的Webhook>

假设 Token 是12345:ABCDE,Webhook 是https://tg.axum.rs/

$ curl 'https://api.telegram.org/bot12345:ABCDE/setWebhook?url=https://tg.axum.rs/'

建议对你的 webhook 地址进行 Url 编码之后再提交。