使用 telegram-Client
telegram-client
是基于 telegram4j-core
开发的库,旨在简化 Telegram 消息的处理。本文将介绍如何使用 telegram-client
来处理消息和命令,包括依赖配置、事件适配器、命令处理以及客户端配置等内容。
添加依赖
首先,在项目的 pom.xml
文件中添加 telegram-client
的依赖:
<dependency>
<groupId>com.litongjava</groupId>
<artifactId>telegram-client</artifactId>
<version>1.0.0</version>
</dependency>
创建消息分发器
消息分发器负责处理收到的消息事件,根据消息内容执行相应的操作并发送回复。
package com.litongjava.telegram.bots.dispatcher;
import org.reactivestreams.Publisher;
import com.litongjava.telegram.dispatcher.TelegramMessageDispatcher;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;
import telegram4j.core.event.domain.message.SendMessageEvent;
import telegram4j.core.object.Message;
import telegram4j.core.object.chat.Chat;
import telegram4j.core.spec.SendMessageSpec;
import telegram4j.core.util.Id;
@Slf4j
public class MyTelegramMessageDispatcher implements TelegramMessageDispatcher {
/**
* 处理 SendMessageEvent,执行翻译并发送回复
*
* @param event 发送消息事件
* @return 翻译后的消息 Publisher
*/
public Publisher<? extends Message> dispatch(SendMessageEvent event) {
// 获取 Chat 对象,如果不存在则从消息中获取
Mono<Chat> chatMono = Mono.justOrEmpty(event.getChat()).switchIfEmpty(event.getMessage().getChat());
// 处理 Chat 和消息发送
return chatMono.flatMap(chat -> processAndSendMessage(chat, event.getMessage()));
}
/**
* 处理消息内容,执行翻译并发送回复
*
* @param chat 聊天对象
* @param message 原始消息对象
* @return 处理后的消息 Publisher
*/
private Mono<Message> processAndSendMessage(Chat chat, Message message) {
String text = message.getContent();
log.info("接收到消息: {}", text);
if (text.equals("/get_chat_id")) {
Id id = chat.getId();
return chat.sendMessage("Chat ID: " + id.asLong());
}
// 构建发送消息规范,这里可以集成翻译功能
SendMessageSpec messageSpec = SendMessageSpec.of("Hi");
// 发送回复消息
return chat.sendMessage(messageSpec);
}
}
实现事件适配器
事件适配器用于监听和处理 Telegram 事件,例如消息发送和回调查询等。在此示例中,我们实现了 MyBotEventAdapter
来处理消息事件,并过滤掉机器人自身发送的消息。
package com.litongjava.telegram.bots.adapter;
import java.util.Optional;
import org.reactivestreams.Publisher;
import com.litongjava.telegram.bots.dispatcher.MyTelegramMessageDispatcher;
import com.litongjava.telegram.dispatcher.TelegramBotEventDispatcher;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;
import telegram4j.core.event.EventAdapter;
import telegram4j.core.event.domain.inline.CallbackQueryEvent;
import telegram4j.core.event.domain.message.SendMessageEvent;
import telegram4j.core.object.MentionablePeer;
import telegram4j.core.object.chat.Chat;
@Slf4j
public class MyBotEventAdapter extends EventAdapter {
private final long botId;
public MyBotEventAdapter(long selfId) {
this.botId = selfId;
}
@Override
public Publisher<?> onSendMessage(SendMessageEvent event) {
Optional<MentionablePeer> optionalAuthor = event.getAuthor();
Optional<Chat> optionalChat = event.getChat();
// 防止机器人处理自己发送的消息
if (optionalAuthor.isEmpty()) {
log.info("消息发送者信息缺失,可能是机器人自身发送的消息。");
return Mono.empty();
}
if (optionalChat.isEmpty()) {
log.info("消息信息缺失,可能是机器人自身发送的消息。");
return Mono.empty();
}
long messageAuthorId = optionalAuthor.get().getId().asLong();
if (botId == messageAuthorId) {
log.info("获取到机器人的自身消息,忽略处理。");
return Mono.empty();
}
// 创建消息分发器并处理事件
MyTelegramMessageDispatcher dispatcher = new MyTelegramMessageDispatcher();
return TelegramBotEventDispatcher.adapt(event, dispatcher);
}
@Override
public Publisher<?> onCallbackQuery(CallbackQueryEvent event) {
return super.onCallbackQuery(event);
}
}
定义命令处理函数
定义具体的命令处理逻辑,例如 /start
和 /about
命令。每个命令对应一个函数类,实现特定的功能。
StartCommandFunction
处理 /start
命令,发送欢迎信息。
package com.litongjava.telegram.bots.command;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;
import telegram4j.core.event.domain.message.SendMessageEvent;
import telegram4j.core.object.Message;
import telegram4j.core.object.chat.Chat;
public class StartCommandFunction {
public Publisher<? extends Message> apply(SendMessageEvent event) {
String welcomeMessage = "🌐 **翻译机器人** 🌐\n\n这个机器人使用 GPT 技术为您提供高质量的文本翻译服务。欢迎使用翻译机器人!\n\n";
Mono<Chat> chat = event.getMessage().getChat();
return chat.flatMap(c -> c.sendMessage(welcomeMessage));
}
}
AboutUsCommandFunction
处理 /about
命令,发送关于机器人的信息。
package com.litongjava.telegram.bots.command;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;
import telegram4j.core.event.domain.message.SendMessageEvent;
import telegram4j.core.object.Message;
import telegram4j.core.object.chat.Chat;
public class AboutUsCommandFunction {
public Publisher<? extends Message> apply(SendMessageEvent event) {
String aboutMessage = "**开发者:** Litong Java\n**版本:** 1.0.0\n\n感谢您使用本机器人!";
Mono<Chat> chat = event.getMessage().getChat();
return chat.flatMap(c -> c.sendMessage(aboutMessage));
}
}
配置 Telegram 客户端
配置类负责初始化 Telegram 客户端,设置命令路由,并确保客户端在服务器关闭时正确断开连接。
package com.litongjava.telegram.bots.config;
import java.nio.file.Path;
import java.time.Duration;
import java.util.function.Function;
import com.litongjava.annotation.AConfiguration;
import com.litongjava.annotation.Initialization;
import com.litongjava.telegram.bots.adapter.MyBotEventAdapter;
import com.litongjava.telegram.bots.command.AboutUsCommandFunction;
import com.litongjava.telegram.bots.command.StartCommandFunction;
import com.litongjava.telegram.command.TelegramClient;
import com.litongjava.telegram.command.TelegramCommandRouter;
import com.litongjava.telegram.config.TelegramBotConfig;
import com.litongjava.tio.boot.server.TioBootServer;
import com.litongjava.tio.utils.environment.EnvUtils;
import lombok.extern.slf4j.Slf4j;
import reactor.util.retry.Retry;
import telegram4j.core.MTProtoBootstrap;
import telegram4j.core.MTProtoTelegramClient;
import telegram4j.core.spec.BotCommandScopeSpec;
import telegram4j.mtproto.store.FileStoreLayout;
import telegram4j.mtproto.store.StoreLayoutImpl;
@Slf4j
@AConfiguration
public class MyTelegramBotConfig {
@Initialization
public void config() {
// 从环境变量获取 Telegram API 配置信息
int apiId = EnvUtils.getInt("telegram.api.id");
String apiHash = EnvUtils.getStr("telegram.api.hash");
String botAuthToken = EnvUtils.getStr("telegram.bot.auth.token");
String botId = botAuthToken.split(":")[0];
// 创建并连接 MTProto Telegram 客户端
MTProtoBootstrap bootstrap = MTProtoTelegramClient.create(apiId, apiHash, botAuthToken);
StoreLayoutImpl storeLayoutImpl = new StoreLayoutImpl(Function.identity());
FileStoreLayout storeLayout = new FileStoreLayout(storeLayoutImpl, Path.of("t4j-bot_" + botId + ".bin"));
bootstrap.setStoreLayout(storeLayout);
MTProtoTelegramClient client = bootstrap.connect().block();
if (client == null) {
log.error("无法连接到 Telegram MTProto 客户端。");
return;
}
log.info("成功连接到 Telegram MTProto 客户端。");
// 删除已有的命令
deleteCommand(client);
// 添加命令路由
TelegramCommandRouter.add("start", "Start using the bot", new StartCommandFunction()::apply);
TelegramCommandRouter.add("about", "About this bot", new AboutUsCommandFunction()::apply);
// 初始化事件适配器
MyBotEventAdapter myBotEventAdapter = new MyBotEventAdapter(apiId);
new TelegramBotConfig().init(client, apiId, apiHash, botAuthToken, myBotEventAdapter);
// 添加客户端到 TelegramClient 管理器
TelegramClient.addClient("translator", client);
// 在服务器关闭时,断开 Telegram 客户端连接
HookCan.me().addDestroyMethod(client::disconnect);
}
/**
* 删除现有的命令,确保命令路由的正确性
*
* @param client MTProto Telegram 客户端
*/
private void deleteCommand(MTProtoTelegramClient client) {
client.resetCommands(BotCommandScopeSpec.of(BotCommandScopeSpec.Type.DEFAULT), "")
.retryWhen(Retry.backoff(3, Duration.ofSeconds(2)))
.doOnSuccess(v -> log.info("成功删除现有命令!"))
.doOnError(e -> log.error("删除命令失败。", e))
.block();
}
}
详细说明
环境变量配置:通过
EnvUtils
从环境变量中获取 Telegram API 的配置信息,包括apiId
、apiHash
和botAuthToken
。创建客户端:使用
MTProtoBootstrap
创建 Telegram 客户端,并设置存储布局。这里使用FileStoreLayout
将客户端数据存储在文件中。连接客户端:调用
bootstrap.connect().block()
连接 Telegram 客户端,并检查连接是否成功。命令管理:
- 删除现有命令:调用
deleteCommand
方法,确保之前设置的命令被清除,避免命令冲突。 - 添加新命令:通过
TelegramCommandRouter
添加/start
和/about
命令,并绑定对应的处理函数。
- 删除现有命令:调用
初始化事件适配器:创建
MyBotEventAdapter
实例,并将其传递给TelegramBotConfig
进行初始化。管理客户端:将创建的客户端添加到
TelegramClient
管理器中,以便在需要时进行管理和使用。断开连接:通过
HookCan.me().addDestroyMethod(client::disconnect)
确保在服务器关闭时,Telegram 客户端能够正确断开连接,释放资源。
总结
本文介绍了如何使用 telegram-client
库来简化 Telegram 机器人的开发过程。通过添加依赖、创建消息分发器、实现事件适配器、定义命令处理函数以及配置 Telegram 客户端,您可以快速搭建一个功能完善的 Telegram 机器人。上述示例代码展示了基本的消息处理和命令响应逻辑,您可以根据需求进行扩展和定制,以实现更复杂的功能。