Skip to content

使用工具库 telegram-bot-base 开发翻译机器人 ​


Maven 坐标配置 ​

在 Maven 工程中引入所需依赖。以下配置中除日志记录和 JSON 处理依赖外,核心依赖为 telegram-bot-base。请确保在 pom.xml 中添加如下依赖:

xml
<dependency>
  <groupId>nexus.io</groupId>
  <artifactId>tio-boot-admin</artifactId>
  <version>1.0.0</version>
</dependency>
<dependency>
  <groupId>com.litongjava</groupId>
  <artifactId>telegram-bot-base</artifactId>
  <version>1.0.0</version>
</dependency>
<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>

说明
其中 telegram-bot-base 是对 telegram-bots 的常用操作进行封装的工具库,用以降低开发难度。


环境配置与整合 TioBoot ​

.env 配置文件 ​

在项目根目录下创建一个 .env 文件,内容如下(请根据实际情况填写 API KEY 与 Bot Token 等配置信息):

dotenv
GEMINI_API_KEY=
telegram.bot.token=
telegram.bot.webhook=https://xxx.dev/telegram/webhook

TelegramBotConfig 配置 ​

在非生产环境下使用长轮询模式,生产环境则使用 WebHook 模式。下面的 TelegramBotConfig 类展示了如何在 TioBoot 框架中自动加载配置并注册 Bot:

java
import org.telegram.telegrambots.longpolling.TelegramBotsLongPollingApplication;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;


import nexus.io.annotation.AConfiguration;
import nexus.io.annotation.Initialization;
import nexus.io.hook.HookCan;
import nexus.io.tio.utils.environment.EnvUtils;

@AConfiguration
public class TelegramBotConfig {

  @Initialization
  public void config() {
    // 非生产环境下采用长轮询模式,生产环境下使用 WebHook 模式
    if (!EnvUtils.isProd()) {
      String botAuthToken = EnvUtils.getStr("telegram.bot.token");
      TelegramBotsLongPollingApplication botsApplication = new TelegramBotsLongPollingApplication();

      try {
        // 注册自定义 Bot
        MyAmazingBot updatesConsumer = new MyAmazingBot();
        botsApplication.registerBot(botAuthToken, updatesConsumer);
      } catch (TelegramApiException e) {
        e.printStackTrace();
      }

      // 应用关闭时注销 Bot 并关闭应用
      HookCan.me().addDestroyMethod(() -> {
        try {
          botsApplication.unregisterBot(botAuthToken);
          botsApplication.close();
        } catch (Exception e) {
          e.printStackTrace();
        }
      });
    }
  }
}

TelegramClientConfig 配置 ​

该类用于初始化 Telegram Client(此处使用 OkHttp 实现)并将其实例赋值给全局变量,方便后续调用发送消息等操作:

java
import org.telegram.telegrambots.client.okhttp.OkHttpTelegramClient;
import org.telegram.telegrambots.meta.generics.TelegramClient;
import nexus.io.annotation.AConfiguration;
import nexus.io.annotation.Initialization;
import com.litongjava.telegram.can.TelegramClientCan;
import nexus.io.tio.utils.environment.EnvUtils;

@AConfiguration
public class TelegramClientConfig {

  @Initialization
  public void config() {
    String botAuthToken = EnvUtils.getStr("telegram.bot.token");
    TelegramClient telegramClient = new OkHttpTelegramClient(botAuthToken);
    TelegramClientCan.main = telegramClient;
  }
}

核心 Bot 逻辑实现 ​

MyAmazingBot 示例 ​

下面展示了一个简单的 Bot 示例类 MyAmazingBot,此类继承自 LongPollingMultiThreadUpdateConsumer,用于接收更新并根据指令进行路由分发:

java
import java.util.List;

import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.objects.Update;

import nexus.io.jfinal.aop.Aop;
import com.litongjava.telegram.bot.service.GetChatIdService;
import com.litongjava.telegram.can.TelegramClientCan;
import com.litongjava.telegram.utils.LongPollingMultiThreadUpdateConsumer;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MyAmazingBot extends LongPollingMultiThreadUpdateConsumer {
  @Override
  public void consume(Update update) {
    if (update.hasMessage() && update.getMessage().hasText()) {
      String receivedText = update.getMessage().getText();
      Long chatId = update.getMessage().getChatId();
      log.info("Received text message: {}", receivedText);

      // 根据指令进行路由分发
      if ("/get_chat_id".equals(receivedText)) {
        Aop.get(GetChatIdService.class).index(update);
      } else if ("/start".equals(receivedText)) {
        Aop.get(StartService.class).index(update);
      } else if ("/about".equals(receivedText)) {
        Aop.get(StartService.class).about(update);
      } else {
        // 默认将接收到的文本原样回发
        SendMessage sendMessage = new SendMessage(chatId.toString(), receivedText);
        TelegramClientCan.execute(sendMessage);
      }
    }
  }

  @Override
  public void consumeGroup(List<Update> updates) {
    for (Update update : updates) {
      this.consume(update);
    }
  }
}

利用工具库获取 chat_id ​

以下代码示例展示了如何通过工具库提取更新中的 chat_id 并将其返回给用户(适用于私聊和频道消息):

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

import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.api.objects.chat.Chat;
import com.litongjava.telegram.can.TelegramClientCan;

public class GetChatIdService {

  public void index(Update update) {
    Chat chat = null;
    if (update.hasMessage()) {
      chat = update.getMessage().getChat();
    } else if (update.hasChannelPost()) {
      chat = update.getChannelPost().getChat();
    }

    // 获取 chat_id(数据已脱敏)
    Long chatId = chat.getId();

    // 以消息形式返回 chat_id
    SendMessage sendMessage = new SendMessage(chatId.toString(), chatId.toString());
    TelegramClientCan.execute(sendMessage);
  }
}

GetChatIdService 已经内置到了telegram-base库中 ​

发送 Markdown 格式消息 ​

工具库中提供了便捷方法帮助开发者构造支持 Markdown 语法的消息。以下示例展示了如何结合 AOP 实现基于命令的消息路由与回复。

StartService 处理 /start 与 /about 指令 ​

StartService 类主要负责处理 /start 和 /about 指令,构造 Markdown 格式消息并通过 TelegramClient 发送:

java
package nexus.io.manim.services;

import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.objects.Update;
import com.litongjava.telegram.can.TelegramClientCan;
import com.litongjava.telegram.utils.SendMessageUtils;

public class StartService {

  public void index(Update update) {
    Long chatId = update.getMessage().getChatId();
    String welcomeMessage = "🌐 **教学机器人** 🌐\n\n" +
                            "这个机器人使用 AI 技术为您提供高质量的视频生成服务。欢迎使用教学机器人!\n\n";
    // 通过工具库生成 Markdown 格式消息
    SendMessage markdown = SendMessageUtils.markdown(chatId, welcomeMessage);
    TelegramClientCan.execute(markdown);
  }

  public void about(Update update) {
    Long chatId = update.getMessage().getChatId();
    String aboutMessage = "**开发者:** Litong Java\n" +
                          "**版本:** 1.0.0\n\n" +
                          "感谢您使用本机器人!";
    SendMessage markdown = SendMessageUtils.markdown(chatId, aboutMessage);
    TelegramClientCan.execute(markdown);
  }
}

亮点说明

  • 利用 SendMessageUtils.markdown 方法快速构造支持 Markdown 格式的消息。
  • 使用 AOP 框架调用 GetChatIdService 与 StartService,实现业务逻辑模块化,降低耦合度。

开发翻译机器人 ​

本节展示如何开发一个支持文本翻译功能的 Telegram Bot,其主要逻辑包括:

  • 当接收到非预定义指令的文本消息时(仅针对私聊生效);
  • 根据文本内容判断语言方向(例如:若包含中文,则视为中译英;否则英译中);
  • 调用翻译服务,并将翻译结果以 Markdown 格式返回给用户。

翻译提示模板 ​

在项目中创建一个提示模板文件 translator_prompt.txt,内容如下:

txt
You are a helpful translator.
- Please translate the following #(src_lang) into #(dst_lang).
- Preserve the format of the source content during translation.
- Do not provide any explanations or text apart from the translation.
- Only output the translated text

text:#(source_text)

translated text:

私聊消息路由实现 ​

针对私聊消息,Bot 对非预定义指令的文本转发给翻译服务。下面是修改后的 MyAmazingBot 实现,针对私聊消息调用翻译模块:

java
package nexus.io.manim.bots;

import java.util.List;
import org.telegram.telegrambots.meta.api.objects.Update;
import nexus.io.jfinal.aop.Aop;
import nexus.io.manim.services.BotMessageDispatherService;
import nexus.io.manim.services.StartService;
import com.litongjava.telegram.bot.service.GetChatIdService;
import com.litongjava.telegram.utils.ChatType;
import com.litongjava.telegram.utils.LongPollingMultiThreadUpdateConsumer;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MyAmazingBot extends LongPollingMultiThreadUpdateConsumer {
  @Override
  public void consume(Update update) {
    if (update.hasMessage() && update.getMessage().hasText()) {
      String receivedText = update.getMessage().getText();
      log.info("Received text message: {}", receivedText);

      // 根据指令进行路由分发
      if ("/get_chat_id".equals(receivedText)) {
        Aop.get(GetChatIdService.class).index(update);
      } else if ("/start".equals(receivedText)) {
        Aop.get(StartService.class).index(update);
      } else if ("/about".equals(receivedText)) {
        Aop.get(StartService.class).about(update);
      } else {
        // 当消息来源为私聊时,调用翻译服务处理文本
        if (update.getMessage().getChat().getType().equals(ChatType.chat_private)) {
          Aop.get(BotMessageDispatherService.class).index(update);
        }
      }
    }
  }

  @Override
  public void consumeGroup(List<Update> updates) {
    for (Update update : updates) {
      this.consume(update);
    }
  }
}

BotMessageDispatherService 的实现非常简单,仅对接翻译服务:

java
package nexus.io.manim.services;

import org.telegram.telegrambots.meta.api.objects.Update;
import nexus.io.jfinal.aop.Aop;

public class BotMessageDispatherService {

  public void index(Update update) {
    Aop.get(BotTranslateService.class).index(update);
  }
}

BotTranslateService 实现 ​

BotTranslateService 类主要负责:

  1. 获取消息文本与聊天信息;
  2. 判断文本包含中文字符则设置源语言为中文、目标语言为英文(否则反之);
  3. 构造翻译请求对象,调用翻译服务;
  4. 捕获异常并返回错误提示(若有异常);
  5. 使用 SendMessageUtils.markdown 方法构造 Markdown 格式消息并回复用户。
java
package nexus.io.manim.services;

import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.api.objects.chat.Chat;
import nexus.io.jfinal.aop.Aop;
import nexus.io.manim.vo.TranslatorTextVo;
import com.litongjava.telegram.can.TelegramClientCan;
import com.litongjava.telegram.utils.SendMessageUtils;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class BotTranslateService {

  public void index(Update update) {
    String text = update.getMessage().getText();
    Chat chat = update.getMessage().getChat();
    Long chatId = chat.getId();

    // 根据文本判断语言方向:包含中文则为中译英,否则为英译中
    String srcLang;
    String destLang;
    if (containsChinese(text)) {
      srcLang = "Chinese";
      destLang = "English";
    } else {
      srcLang = "English";
      destLang = "Chinese";
    }

    // 构造翻译请求对象
    TranslatorTextVo translatorTextVo = new TranslatorTextVo();
    translatorTextVo.setSrcText(text);
    translatorTextVo.setSrcLang(srcLang);
    translatorTextVo.setDestLang(destLang);

    String responseText;
    try {
      // 调用翻译服务获取翻译结果
      responseText = Aop.get(TranslatorService.class).translate(chatId.toString(), translatorTextVo);
    } catch (Exception e) {
      log.error("Exception", e);
      responseText = "Exception: " + e.getMessage();
    }

    // 构造 Markdown 格式消息发送翻译结果回用户
    SendMessage markdown = SendMessageUtils.markdown(chatId, responseText);
    TelegramClientCan.execute(markdown);
  }

  /**
   * 判断输入文本中是否包含中文字符
   *
   * @param text 输入的文本内容
   * @return 若包含中文字符返回 true,否则返回 false
   */
  private boolean containsChinese(String text) {
    if (text == null || text.isEmpty()) {
      return false;
    }
    // 正则表达式匹配中文字符范围
    return text.matches(".*[\\u4e00-\\u9fa5]+.*");
  }
}

翻译服务实现 ​

TranslatorService 类利用预定义的翻译提示模板调用翻译引擎(本示例中使用 Gemini 模型)。请确保项目中已实现具体调用逻辑,此处仅展示接口调用过程:

java
package nexus.io.manim.services;

import java.util.HashMap;
import java.util.Map;
import com.jfinal.template.Template;
import nexus.io.gemini.GeminiClient;
import nexus.io.gemini.GoogleModels;
import nexus.io.manim.vo.TranslatorTextVo;
import nexus.io.template.PromptEngine;

public class TranslatorService {

  public String translate(TranslatorTextVo translatorTextVo) {
    String srcLang = translatorTextVo.getSrcLang();
    String destLang = translatorTextVo.getDestLang();
    String srcText = translatorTextVo.getSrcText();

    Template template = PromptEngine.getTemplate("translator_prompt.txt");
    Map<String, String> values = new HashMap<>();

    values.put("src_lang", srcLang);
    values.put("dst_lang", destLang);
    values.put("source_text", srcText);

    String prompt = template.renderToString(values);
    String response = GeminiClient.chatWithModel(GoogleModels.GEMINI_2_0_FLASH_EXP, "user", prompt);
    return response;
  }

  public String translate(String chatId, TranslatorTextVo translatorTextVo) {
    // 此处直接调用重载方法实现翻译
    return this.translate(translatorTextVo);
  }
}

使用 WebHook 模式 ​

在生产环境中,建议采用 WebHook 模式以获得更高的并发性能。下面给出设置和处理 WebHook 的示例:

设置 WebHook 示例 ​

java
package nexus.io.manim.services;

import org.junit.Test;
import nexus.io.model.http.response.ResponseVo;
import nexus.io.tio.utils.environment.EnvUtils;
import nexus.io.tio.utils.json.JsonUtils;
import nexus.io.tio.utils.telegram.TelegramBot;

public class TelegramBotWebHookTest {

  @Test
  public void test() {
    EnvUtils.load();
    String token = EnvUtils.getStr("telegram.bot.token");
    String webHook = EnvUtils.getStr("telegram.bot.webhook");
    System.out.println(token);
    System.out.println(webHook);
    TelegramBot telegramBot = new TelegramBot("main", token);

    // 设置 WebHook
    ResponseVo setWebhook = telegramBot.setWebhook(webHook);
    System.out.println("Set WebHook Response: " + JsonUtils.toJson(setWebhook));

    // 获取 WebHook 信息
    ResponseVo webhookInfo = telegramBot.getWebhookInfo();
    System.out.println("Webhook Info: " + JsonUtils.toJson(webhookInfo));

    // 如有需要,可删除 WebHook
    // ResponseVo deleteWebhook = telegramBot.deleteWebhook();
    // System.out.println("Delete WebHook Response: " + JsonUtils.toJson(deleteWebhook));
  }
}

WebHook 控制器实现 ​

下面的控制器接收由 Telegram 推送的更新,并将其交由业务模块处理:

java
package nexus.io.manim.controller;

import org.telegram.telegrambots.meta.api.objects.Update;
import nexus.io.annotation.RequestPath;
import nexus.io.jfinal.aop.Aop;
import nexus.io.manim.services.BotMessageDispatherService;
import nexus.io.tio.boot.http.TioRequestContext;
import nexus.io.tio.http.common.HttpRequest;
import nexus.io.tio.http.common.HttpResponse;
import nexus.io.tio.utils.json.JacksonUtils;

@RequestPath("/telegram")
public class TelegramWebhookController {

  @RequestPath("/webhook")
  public HttpResponse handleTelegramWebhook(HttpRequest request) {
    String bodyString = request.getBodyString();
    Update update = JacksonUtils.parse(bodyString, Update.class);
    Aop.get(BotMessageDispatherService.class).index(update);
    return TioRequestContext.getResponse();
  }
}

总结 ​

本文档详细介绍了如何利用 telegram-bot-base 工具库及 TioBoot 架构快速开发 Telegram Bot 应用。主要内容包括:

  • Maven 坐标配置:如何引入所需依赖。
  • 环境配置与 Bot 初始化:通过 .env 配置文件和相应的配置类(如 TelegramBotConfig、TelegramClientConfig)实现环境加载与 Bot 注册。
  • 消息处理:演示了如何获取聊天 ID、发送 Markdown 格式消息,以及根据指令(如 /start、/about)分发业务逻辑。
  • 翻译机器人开发:基于私聊消息的语言识别与翻译调用,实现智能翻译并以 Markdown 格式回复用户。
  • WebHook 模式:介绍了 WebHook 的设置、获取信息及控制器实现,适用于生产环境使用。

希望本指南能够为您构建高效、可靠的 Telegram Bot 应用提供有力支持。如需扩展更多功能(如接入其它翻译引擎、支持更多消息类型),可在此基础上进行二次开发。