Skip to content

Telegram bot 和 mini apps 开发简易教程 #65

Open
@brickspert

Description

@brickspert

Telegram 是全球顶流的社交软件,目前其提供了机器人 bot 和 mini app,可以非常方便的开发三方服务。
本文通过实现一个 TodoList 服务,以跑通完整的开发流程。

环境准备

建议使用 Test 环境开发,限制条件会少很多。如何打开 Test 环境,参考官方文档,比较简单。
以 MacOS 版本为例:

  1. 点击 10 下设置按钮,打开 Debug 面板
  2. 开启 Debug 模式
  3. ⌘ + click点击添加账号,即可登录测试账号

Bot

机器人注册

  1. 搜索 BotFather 机器人

  1. 输入 /newbot新建机器人,然后根据提示输入即可。第一次输入昵称,第二次输入机器人账号(全平台唯一,且需要以 bot 结尾),至此新建机器人成功,记得保存返回的机器人 Token,开发时需要

  1. 机器人新建成功,我们可以通过机器人账号「todo_list_demo_bot」搜索到机器人,并与它对话。当然,现在机器人还什么都不会呢。

功能实现

机器人的交互逻辑很简单,用户输入的任意内容,会通知到我们的服务端,服务端根据约定的格式,处理用户请求。
比如我们约定通过 /add 任务的格式来添加任务,那当用户输入 /add 写作业时,服务端会通过文本匹配,来添加一个 写作业的任务。

我们先来实现添加任务的服务端逻辑,极其简单。
这里我们通过 Node.js 语言来写,同时集成了 node-telegram-bot-api 库,只需要几行代码就好了。

const TelegramBot = require('node-telegram-bot-api');

const token = 'your token';

const bot = new TelegramBot(token, { polling: true, testEnvironment: true });

const todos = {};

bot.onText(/\/add (.+)/, (msg, match) => {
  const chatId = msg.chat.id;
  const text = match[1];

  if (!todos[chatId]) {
    todos[chatId] = [];
  }
  todos[chatId].push(text);

  bot.sendMessage(chatId, 'Added "' + text + '" to your to-do list.');
});

上面代码很简单,就是当用户输入的内容是以 /add 开始的话,就给该用户新增一个任务。
启动这个服务,然后我们试一试效果。

现在我们已经可以成功的通过机器人新建一个任务了。

然后我们再加一个 /list命令,列出当前所有的任务

bot.onText(/\/list/, (msg) => {
  const chatId = msg.chat.id;
  const todoList = todos[chatId];

  let message = 'Your to-do items are:\n';
  todoList.forEach((item, index) => {
    message += `${index + 1}. ${item}\n`;
  });
  bot.sendMessage(chatId, message);
});

成功。

接下来我们上点难度,我们希望这样删除任务:

  1. 用户输入 /delete关键字
  2. 用户端显示出所有的任务,并可以点击,用户选择一个任务删除
// 监听 /delete 命令,返回所有的任务
bot.onText(/\/delete/, (msg) => {
  console.log('??delete');
  const chatId = msg.chat.id;
  const todoList = todos[chatId];
  bot.sendMessage(chatId, 'Click an item to delete:', {
    reply_markup: {
      inline_keyboard: todoList.map((item, index) => [
        {
          text: `${index + 1}. ${item}`,
          callback_data: JSON.stringify({ command: 'delete', index })
        },
      ]),
    },
  });
});

// 监听用户点击
bot.on('callback_query', (callbackQuery) => {
  const message = callbackQuery.message;
  const data = JSON.parse(callbackQuery.data);
  const chatId = message.chat.id;

  if (data.command === 'delete') {
    const deleted = todos[chatId].splice(data.index, 1);
    bot.answerCallbackQuery(callbackQuery.id, { text: 'Deleted "' + deleted[0] + '" from your to-do list.' });
  }

});

上面的代码很简单,做了两件事情:

  1. 当用户输入 /delete后,返回所有的任务,注意 inline_keyboard,就是控制在返回消息中添加按钮的。
  2. 监听用户点击任务,监听到之后删除该任务。

通过上述几个步骤,我们实现了一个简单的 TodoList Demo。

然后我们稍微优化一下,/list/delete命令做成直接点击选择的,不需要每次都手动输入。
找到 BotFather 机器人,输入 /setcommands 命令,然后按要求输入我们约定的命令。

这样用户就可以通过我们机器人左下角的菜单按钮,直接快捷选择命令了。

Mini apps

上面的 Bot 还是以文本的形式操作 TodoList,当然没有可视化界面操作着舒服。这一小节我们实现一个集成在 Telegram 中的可视化页面,来管理 TodoList。

APP 注册

注册 APP 说白了,就是给我们的 Bot 机器人,绑定一个网站域名,这个网站就是一个 mini app 了。
老规矩,找到 BotFather,输入 /newapp,告诉它我们要新建一个 app,然后选择需要绑定的 Bot,然后根据提示一步一步输入即可。

这里需要注意的是,Test 环境域名可以绑定 127.0.0.1,开发起来非常方便。
最终 BotFather 会给我们一个 t.me/bot_name/name格式的域名,通过这个域名就可以打开我们的 app 了。

APP 实现

App 就是一个普通的网页,比如我们写一个最简单的 HTML 文件

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Todo List</title>
  </head>

  <body>
    Hello Todo List
  </body>

</html>

上面的 HTML 文件,我们启动一个服务,通过 http://127.0.0.1:8000 可以访问到即可。

然后我们在 Telegram 中打开刚才注册 app 给的网址:t.me/todo_list_demo_bot/manager,即可成功访问我们的 app 了,效果如下图。

如果只是一个单纯的网页,肯定不能满足我们的需求。
我们需要拿到 Telegram 的各种状态,比如当前用户信息,用户位置,主题配置等等各种。
同时我们需要能和 Telegram 进行各种交互。

很简单,在我们的 HTML 中集成 telegram-web-app.js即可,然后我们就可以通过 window.Telegram.WebApp变量和 Telegram 进行交互了。

<script src="https://telegram.org/js/telegram-web-app.js"></script>

具体的 API 可以参考官方文档
具体 TodoList 代码这里就不做实现了。

更多能力

通过上述文档,我们跑通了 Bot 和 APP 的开发流程,使用了一些最基础的功能。
当然 Telegram Bot 和 APP 还有其它更多更强大的功能,可以参见官方文档。这里我简单罗列一些功能。

  1. 支持给不同的用户组设置不通的命令
  2. 支持控制多种按钮位置

  1. 支持在群聊中给机器人发送命令,同时支持如图的内联响应。

  1. 支持附件菜单,不过只对特定应用开放权限。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions