使用工具库 telegram-bot-base 开发翻译机器人
Maven 坐标配置
在 Maven 工程中引入所需依赖。以下配置中除日志记录和 JSON 处理依赖外,核心依赖为 telegram-bot-base。请确保在 pom.xml
中添加如下依赖:
<dependency>
<groupId>com.litongjava</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 等配置信息):
GEMINI_API_KEY=
telegram.bot.token=
telegram.bot.webhook=https://xxx.dev/telegram/webhook
TelegramBotConfig 配置
在非生产环境下使用长轮询模式,生产环境则使用 WebHook 模式。下面的 TelegramBotConfig
类展示了如何在 TioBoot 框架中自动加载配置并注册 Bot:
package com.litongjava.manim.config;
import org.telegram.telegrambots.longpolling.TelegramBotsLongPollingApplication;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import com.litongjava.annotation.AConfiguration;
import com.litongjava.annotation.Initialization;
import com.litongjava.hook.HookCan;
import com.litongjava.manim.bots.MyAmazingBot;
import com.litongjava.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 实现)并将其实例赋值给全局变量,方便后续调用发送消息等操作:
package com.litongjava.manim.config;
import org.telegram.telegrambots.client.okhttp.OkHttpTelegramClient;
import org.telegram.telegrambots.meta.generics.TelegramClient;
import com.litongjava.annotation.AConfiguration;
import com.litongjava.annotation.Initialization;
import com.litongjava.telegram.can.TelegramClientCan;
import com.litongjava.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
,用于接收更新并根据指令进行路由分发:
package com.litongjava.manim.bots;
import java.util.List;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.objects.Update;
import com.litongjava.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
并将其返回给用户(适用于私聊和频道消息):
package com.litongjava.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.utils.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);
}
}
发送 Markdown 格式消息
工具库中提供了便捷方法帮助开发者构造支持 Markdown 语法的消息。以下示例展示了如何结合 AOP 实现基于命令的消息路由与回复。
StartService 处理 /start 与 /about 指令
StartService
类主要负责处理 /start
和 /about
指令,构造 Markdown 格式消息并通过 TelegramClient 发送:
package com.litongjava.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
,内容如下:
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
实现,针对私聊消息调用翻译模块:
package com.litongjava.manim.bots;
import java.util.List;
import org.telegram.telegrambots.meta.api.objects.Update;
import com.litongjava.jfinal.aop.Aop;
import com.litongjava.manim.services.BotMessageDispatherService;
import com.litongjava.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
的实现非常简单,仅对接翻译服务:
package com.litongjava.manim.services;
import org.telegram.telegrambots.meta.api.objects.Update;
import com.litongjava.jfinal.aop.Aop;
public class BotMessageDispatherService {
public void index(Update update) {
Aop.get(BotTranslateService.class).index(update);
}
}
BotTranslateService 实现
BotTranslateService
类主要负责:
- 获取消息文本与聊天信息;
- 判断文本包含中文字符则设置源语言为中文、目标语言为英文(否则反之);
- 构造翻译请求对象,调用翻译服务;
- 捕获异常并返回错误提示(若有异常);
- 使用
SendMessageUtils.markdown
方法构造 Markdown 格式消息并回复用户。
package com.litongjava.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 com.litongjava.jfinal.aop.Aop;
import com.litongjava.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 模型)。请确保项目中已实现具体调用逻辑,此处仅展示接口调用过程:
package com.litongjava.manim.services;
import java.util.HashMap;
import java.util.Map;
import com.jfinal.template.Template;
import com.litongjava.gemini.GeminiClient;
import com.litongjava.gemini.GoogleGeminiModels;
import com.litongjava.manim.vo.TranslatorTextVo;
import com.litongjava.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(GoogleGeminiModels.GEMINI_2_0_FLASH_EXP, "user", prompt);
return response;
}
public String translate(String chatId, TranslatorTextVo translatorTextVo) {
// 此处直接调用重载方法实现翻译
return this.translate(translatorTextVo);
}
}
使用 WebHook 模式
在生产环境中,建议采用 WebHook 模式以获得更高的并发性能。下面给出设置和处理 WebHook 的示例:
设置 WebHook 示例
package com.litongjava.manim.services;
import org.junit.Test;
import com.litongjava.model.http.response.ResponseVo;
import com.litongjava.tio.utils.environment.EnvUtils;
import com.litongjava.tio.utils.json.JsonUtils;
import com.litongjava.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 推送的更新,并将其交由业务模块处理:
package com.litongjava.manim.controller;
import org.telegram.telegrambots.meta.api.objects.Update;
import com.litongjava.annotation.RequestPath;
import com.litongjava.jfinal.aop.Aop;
import com.litongjava.manim.services.BotMessageDispatherService;
import com.litongjava.tio.boot.http.TioRequestContext;
import com.litongjava.tio.http.common.HttpRequest;
import com.litongjava.tio.http.common.HttpResponse;
import com.litongjava.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 应用提供有力支持。如需扩展更多功能(如接入其它翻译引擎、支持更多消息类型),可在此基础上进行二次开发。