Skip to content

tio-boot 整合 TelegramBots ​

本文档旨在指导开发者如何将 tio-boot 框架与 TelegramBots 库进行整合,采用 长轮询(Long Polling) 模式实现 Telegram Bot 的消息处理。通过本文,您将了解长轮询模式的基本原理,并通过一个简单的示例项目,掌握如何配置和运行一个基本的 Telegram Bot。 ​

TelegramBots 长轮询模式简介 ​

Telegram 提供了多种与 Bot 交互的方式,其中 长轮询(Long Polling) 是最常用的一种模式。在长轮询模式下,Bot 客户端会通过周期性地发送 getUpdates 请求,与 Telegram 服务器保持通信。当服务器有新的消息(Update)时,会立即返回给客户端;若在设定的时间内无新消息,则返回空结果,客户端随后再次发送请求。此循环过程实现了“有消息立即返回,无消息则耐心等待一段时间”的通信机制,相较于传统的短轮询,长轮询更为高效,减少了无效请求的开销。

长轮询工作原理 ​

  1. 客户端请求:Bot 客户端通过 getUpdates 方法向 Telegram 服务器发送 HTTP 请求。
  2. 服务器等待响应:服务器端会根据 timeout 参数设置阻塞请求,等待新消息的产生。
  3. 返回新消息:若在超时之前有新消息,服务器会以 JSON 格式返回更新数据。
  4. 超时与重试:若请求超时且无新消息,服务器返回空结果,客户端随后再次发送 getUpdates 请求,形成持续的轮询过程。

在使用 TelegramBots 库时,开发者无需手动编写上述交互逻辑,框架已在底层自动处理 getUpdates 的持续调用。开发者只需专注于如何处理接收到的 Update 对象。

入门示例 ​

本节将通过一个简单的示例,展示如何使用 tio-boot 和 TelegramBots 库构建一个基本的 Telegram Bot。该 Bot 将实现一个“回音机”功能,即将用户发送的文本消息原样回传。

环境准备 ​

在开始之前,请确保您具备以下条件:

  • Telegram Bot Token:已通过 BotFather 创建并获取。
  • Java 开发环境:本地已配置好相应的 Java 开发环境(建议使用 JDK 17 及以上版本)。
  • 项目管理工具:推荐使用 Maven 或 Gradle 进行依赖管理。
  • 必要依赖:已导入 telegrambots 相关依赖(包括 telegrambots-meta、telegrambots、telegrambots-spring 等,根据需求选择)。

添加依赖 ​

在您的项目 pom.xml 文件中,添加以下依赖项:

xml
<properties>
  <!-- 项目属性 -->
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <java.version>17</java.version>
  <maven.compiler.source>${java.version}</maven.compiler.source>
  <maven.compiler.target>${java.version}</maven.compiler.target>

  <!-- 版本属性 -->
  <lombok-version>1.18.44</lombok-version>
  <fastjson2.version>2.0.52</fastjson2.version>
  <hotswap-classloader.version>1.2.9</hotswap-classloader.version>

  <!-- 应用程序属性 -->
  <final.name>web-hello</final.name>
  <main.class>nexus.io.telegram.bot.TelegramBotApp</main.class>
</properties>
<dependencies>
  <!-- Logback,用于日志记录 -->
  <dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.4.12</version>
  </dependency>

  <!-- Jackson Core 库,用于 JSON 处理 -->
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.17.2</version>
  </dependency>

  <!-- TelegramBots 客户端库 -->
  <dependency>
    <groupId>org.telegram</groupId>
    <artifactId>telegrambots-client</artifactId>
    <version>8.0.0</version>
  </dependency>

  <!-- TelegramBots 长轮询支持 -->
  <dependency>
    <groupId>org.telegram</groupId>
    <artifactId>telegrambots-longpolling</artifactId>
    <version>8.0.0</version>
  </dependency>
</dependencies>

确保在项目中正确导入上述依赖,以便后续代码能够正常编译和运行。

核心代码说明 ​

本示例包括以下核心类:

  1. MyAmazingBot:实现 LongPollingSingleThreadUpdateConsumer 接口,负责处理接收到的 Update。
  2. TelegramClientCan:封装 TelegramClient 客户端,用于发送消息。
  3. TelegramBotConfig:负责 Bot 的注册和初始化配置。

MyAmazingBot 类 ​

MyAmazingBot 类是 Bot 的核心,实现了 LongPollingSingleThreadUpdateConsumer 接口,用于接收和处理 Telegram 服务器推送的更新。

java
import org.telegram.telegrambots.longpolling.util.LongPollingSingleThreadUpdateConsumer;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.objects.Update;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.litongjava.telegram.can.TelegramClientCan;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MyAmazingBot implements LongPollingSingleThreadUpdateConsumer {

  @Override
  public void consume(Update update) {
    // 将收到的Update对象转换为JSON字符串以便调试输出
    try {
      String json = new ObjectMapper().writeValueAsString(update);
      log.info("Received Update JSON: {}", json);
    } catch (JsonProcessingException e) {
      log.error("Failed to convert Update to JSON", e);
    }

    // 判断是否是文本消息
    if (update.hasMessage() && update.getMessage().hasText()) {
      String receivedText = update.getMessage().getText();
      Long chatId = update.getMessage().getChatId();
      log.info("Received text message: {}", receivedText);

      // 创建回发消息对象,将收到的文本原样发送回去
      SendMessage sendMessage = new SendMessage(chatId.toString(), receivedText);

      // 使用 TelegramClient 发送消息
      TelegramClientCan.execute(sendMessage);
    }
  }
}

说明:

  • consume(Update update) 方法是接口 LongPollingSingleThreadUpdateConsumer 的实现,当有新的更新到来时,框架会自动调用此方法。
  • 方法内部首先将 Update 对象转换为 JSON 字符串,便于调试和日志记录。
  • 接着检查 Update 是否包含文本消息,如果是,则提取消息内容和聊天 ID。
  • 创建 SendMessage 对象,将收到的文本原样回传给用户,实现“回音机”功能。
  • 最后,通过 TelegramClientCan.execute(sendMessage) 方法发送消息。

TelegramClientCan 类 ​

TelegramClientCan 类封装了 TelegramClient,用于在项目中任何位置发送消息。

java
package nexus.io.telegram.bots.can;

import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.objects.message.Message;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.generics.TelegramClient;

public class TelegramClientCan {

  public static TelegramClient main;

  public static Message execute(SendMessage sendMessage) {
    try {
      // 通过 TelegramClient 执行发送消息请求
      Message message = main.execute(sendMessage);
      return message;
    } catch (TelegramApiException e) {
      throw new RuntimeException("Failed to send message:", e);
    }
  }
}

说明:

  • TelegramClientCan 使用静态成员变量 main 存储 TelegramClient 实例,方便在项目中任何地方调用。
  • execute 方法封装了发送消息的逻辑,并处理可能出现的异常。

TelegramBotConfig 类 ​

TelegramBotConfig 类负责 Bot 的注册和初始化配置。

java
package nexus.io.gpt.translator.config;

import org.telegram.telegrambots.client.okhttp.OkHttpTelegramClient;
import org.telegram.telegrambots.longpolling.TelegramBotsLongPollingApplication;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.generics.TelegramClient;

import nexus.io.annotation.AConfiguration;
import nexus.io.annotation.Initialization;
import nexus.io.gpt.translator.bots.MyAmazingBot;
import com.litongjava.telegram.can.TelegramClientCan;
import nexus.io.tio.boot.server.TioBootServer;
import nexus.io.tio.utils.environment.EnvUtils;

@AConfiguration
public class TelegramBotConfig {

  @Initialization
  public void config() {
    // 从环境变量或配置文件中读取 Bot Token
    String botAuthToken = EnvUtils.getStr("telegram.bot.auth.token");

    // 创建 TelegramBotsLongPollingApplication 实例,用于管理长轮询 Bot 的注册与启动
    TelegramBotsLongPollingApplication botsApplication = new TelegramBotsLongPollingApplication();

    try {
      // 注册自定义 Bot
      botsApplication.registerBot(botAuthToken, new MyAmazingBot());
    } catch (TelegramApiException e) {
      throw new RuntimeException("Failed to register bot:", e);
    }

    // 创建 TelegramClient 实例(使用 OkHttp 实现)
    TelegramClient telegramClient = new OkHttpTelegramClient(botAuthToken);
    TelegramClientCan.main = telegramClient;

    // 在应用关闭时调用 botsApplication 的 close 方法,确保资源正常释放
    HookCan.me().addDestroyMethod(() -> {
      try {
        botsApplication.close();
      } catch (Exception e) {
        throw new RuntimeException("Failed to close botsApplication:", e);
      }
    });
  }
}

说明:

  • 使用注解 @AConfiguration 和 @Initialization 标识此类为配置类,并在初始化阶段执行 config() 方法。
  • 从环境变量或配置文件中读取 Telegram Bot 的 Token,确保安全性和灵活性。
  • 创建 TelegramBotsLongPollingApplication 实例,用于管理长轮询 Bot 的注册与启动。
  • 注册自定义的 MyAmazingBot 实例。
  • 使用 OkHttpTelegramClient 创建 TelegramClient 实例,并赋值给 TelegramClientCan.main,以供发送消息时使用。
  • 通过 HookCan.me().addDestroyMethod 注册应用关闭时的资源清理逻辑,确保长轮询进程正常停止。

运行说明 ​

按照以下步骤运行您的 Telegram Bot:

  1. 代码组织:将上述代码保存至项目的相应位置,确保包路径和类名与代码一致。
  2. 配置 Bot Token:在配置文件或环境变量中设置 telegram.bot.auth.token,其值为从 BotFather 获得的实际 Token。例如,在 application.properties 中添加:
    properties
    telegram.bot.auth.token=YOUR_BOT_TOKEN
  3. 依赖导入:确保所有必要的依赖已正确导入,并通过 Maven 或 Gradle 进行项目构建。
  4. 启动应用:运行您的 Java 应用。启动后,应用将自动启动长轮询进程,监听 Telegram 服务器的更新。
  5. 测试 Bot:
    • 打开 Telegram,搜索并找到您的 Bot。
    • 向 Bot 发送一条文本消息。
    • 观察日志输出,您应能看到对应的 Update 信息。
    • Bot 将原样回传您发送的消息,验证回音功能是否正常工作。

常见问题排查 ​

  • Bot 无响应:

    • 确认 Bot Token 是否正确。
    • 检查网络连接是否正常,确保应用能够访问 Telegram 服务器。
    • 查看日志输出,检查是否有异常信息。
  • 消息发送失败:

    • 确认 TelegramClientCan.main 是否已正确初始化。
    • 检查发送消息的格式是否正确,尤其是 chatId 和消息内容。
  • 应用无法启动:

    • 检查依赖是否正确导入,版本是否匹配。
    • 确认配置类 TelegramBotConfig 是否被正确扫描和加载。

总结 ​

通过本文档,您学习了如何使用 tio-boot 框架与 TelegramBots 库的长轮询模式,构建一个基本的 Telegram Bot。具体包括:

  • 长轮询模式的基本原理:理解长轮询如何高效地接收 Telegram 服务器的更新。
  • 环境配置与依赖管理:掌握项目所需的依赖和配置步骤。
  • 核心代码实现:了解各核心类的职责和实现逻辑,包括 MyAmazingBot、TelegramClientCan 和 TelegramBotConfig。
  • 运行与测试:学习如何启动应用并验证 Bot 的基本功能。

在实际开发中,您可以在此基础上进一步扩展 Bot 的功能,例如:

  • 指令解析:实现复杂的消息指令处理,支持多种交互方式。
  • 调用第三方服务:集成外部 API,实现丰富的功能,如天气查询、翻译等。
  • 数据库集成:存储用户数据或消息记录,提升 Bot 的智能和个性化服务能力。

通过不断迭代和优化,您将能够构建出功能强大且用户体验优良的 Telegram Bot,满足多样化的应用场景需求。