必备的开发文档
Bots: An introduction for developers (telegram.org)
Telegram Bot 使用文档 - KainHuck - 博客园 (cnblogs.com)
创建机器人
这个步骤网上有很多方案,直接采用即可(通过botfather创建)
开发机器人
github上有很多专门用于开发机器人的库,如grammY、telegramsjs、node-telegram-bot-api等,在尝试了多个库之后我最终采用node-telegram-bot-api进行开发,其他库像grammY由于版本更新,目前的开发文档有很多部分是过时的(因为这个情况我被卡了很久)
如果你想使用其他语言的库,请移步 core.telegram.org/bots/sample…
选择部署方式(长轮询和设置webhook)
你的 bot 可以主动拉取信息(长轮询),或者是由 Telegram 服务器主动推送过来(webhook)。
长轮询:主动的给 Telegram 服务器发送了一个请求,来询问是否有新的 update。不需要域名不需要配置,添加telegram的jar包,继承TelegramLongPollingBot重写它的onUpdateReceived方法,在项目启动是开启telegram机器监听,即可接收到你的Telegram bot接收到的消息,让机器人主动向聊天框发送消息用内置的execute方法即可。
webhook:为 Telegram 提供一个可以从公共互联网上访问的 URL(需要有域名的接口)。 无论何时,只要有新的信息发送到你的 bot,Telegram服务器将主动把消息内容封装成Update对象请求到你的url地址,发送消息需要使用官方文档的sendMessage方法。
详细的区别请查看:长轮询 vs. Webhook | grammY
下面采用长轮询的方式部署机器人
使用node-telegram-bot-api实现自动回复(Node.js)
github搜索node-telegram-bot-api,查看README文档使用快速入门方案
npm i node-telegram-bot-api
# 使用TypeScript开发时需要用到的类型声明
npm install --save-dev @types/node-telegram-bot-api
# 快速入门(创建index.ts编写以下代码)
const TelegramBot = require('node-telegram-bot-api');
// replace the value below with the Telegram token you receive from @BotFather
const token = 'YOUR_TELEGRAM_BOT_TOKEN';
// Create a bot that uses 'polling' to fetch new updates
const bot = new TelegramBot(token, {polling: true});
// Matches "/echo [whatever]"
bot.onText(/\/echo (.+)/, (msg, match) => {
// 'msg' is the received Message from Telegram
// 'match' is the result of executing the regexp above on the text content
// of the message
const chatId = msg.chat.id;
const resp = match[1]; // the captured "whatever"
// send back the matched "whatever" to the chat
bot.sendMessage(chatId, resp);
});
// Listen for any kind of message. There are different kinds of
// messages.
bot.on('message', (msg) => {
const chatId = msg.chat.id;
// send a message to the chat acknowledging receipt of their message
bot.sendMessage(chatId, 'Received your message');
});
注意需要把token换成自己机器人的token
原本以为这部分可以顺利完成,结果运行node .\index.ts后卡住,控制台与tg聊天框均没有反应,通过查找与询问发现tg被国内墙了,虽然已经使用🪜可以使用tg,但是程序并没法发送请求到api.telegram.org服务器,所以需要在程序中使用代理服务,这里以使用V2rayN为例,首先在V2rayN的参数设置中设定好本地socks监听端口(一般默认为10808),然后修改程序添加代理服务
const { SocksProxyAgent } = require('socks-proxy-agent');
// 使用 socks 代理
const agent = new SocksProxyAgent('socks://127.0.0.1:10808');
const token = 'YOUR_TELEGRAM_BOT_TOKEN'; // 检查你的 token 是否正确
const bot = new TelegramBot(token, {
polling: true, // 启用 polling
request: {
agent, // 使用代理进行请求
},
});
bot.onText(/\/ping/, (msg) => {
const chatId = msg.chat.id;
bot.sendMessage(chatId, 'pong');
});
// 启动 bot
bot.on('polling_error', (error) => console.log('Polling error:', error)); // 打印错误
注意,在使用代理服务时我原先在bot配置里加入了testEnvironment: true参数,导致运行时程序以为我在模拟环境中测试,并没有与实际的telegarm API服务器通信,从而报错error: [polling_error] {"code":"ETELEGRAM","message":"ETELEGRAM: 401 Unauthorized"}
踩过各种坑之后运行node .\index.ts终于成功了
使用telegrambots实现自动回复(Java)
考虑到java更适合本人的技术栈,下面介绍如何使用java来开发机器人
首先在core.telegram.org/bots/sample…选一个合适的库,这里使用TelegramBots
新建项目导入依赖(可以去maven repository选一个适合的版本)
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots</artifactId>
<version>6.9.0</version>
</dependency>
在启动类中配置代理服务并注册
package com.example.telegram_bot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.telegram.telegrambots.bots.DefaultBotOptions;
import org.telegram.telegrambots.meta.TelegramBotsApi;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.updatesreceivers.DefaultBotSession;
@SpringBootApplication
public class TelegramBotApplication {
public static void main(String[] args) {
// SpringApplication.run(TelegramBotApplication.class, args);
/*
* 配置代理服务,同Node.js的配置,开启telegram机器监听
*/
DefaultBotOptions botOptions = new DefaultBotOptions();
botOptions.setProxyHost("127.0.0.1");
botOptions.setProxyPort(10808);
botOptions.setProxyType(DefaultBotOptions.ProxyType.SOCKS5);
DefaultBotSession defaultBotSession = new DefaultBotSession();
defaultBotSession.setOptions(botOptions);
try {
TelegramBotsApi telegramBotsApi = new TelegramBotsApi(defaultBotSession.getClass());
ExecBot bot = new ExecBot(botOptions);
telegramBotsApi.registerBot(bot);
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
}
创建机器人类
package com.example.telegram_bot;
import org.springframework.stereotype.Component;
import org.telegram.telegrambots.bots.DefaultBotOptions;
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.objects.Message;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
/**
* 长轮询方式部署机器人
*/
@Component
public class ExecBot extends TelegramLongPollingBot {
// 填你自己的token和username
private String botToken = "YOUR_TOKEN";
private String botName = "YOUR_BOT_NAME";// newbot时你的第二个名字
public ExecBot() {
this(new DefaultBotOptions());
}
// 通过 DefaultBotOptions 允许你指定代理服务器等配置。super(options) 将这个配置传给父类 TelegramLongPollingBot 进行处理
public ExecBot(DefaultBotOptions options) {
super(options);
}
@Override
public String getBotToken() {
return botToken;
}
@Override
public String getBotUsername() {
return botName;
}
// 当 Telegram 服务器发送一个更新(如用户消息)时,这个方法会被触发 update 是包含更新信息的对象
@Override
public void onUpdateReceived(Update update) {
// 检查更新是否包含消息(update.hasMessage()),如果有消息,则提取消息内容和发送者的 chatId
if (update.hasMessage()) {
Message message = update.getMessage();
Long chatId = message.getChatId();
// 拿到用户输入的消息 text
String text = message.getText().trim();
String firstName = message.getChat().getFirstName();
String type = message.getChat().getType();
String title = message.getChat().getTitle();
// todo 拿到text 也就是用户输入的内容,进行自己的逻辑判断回复各种消息
sendMsg("你好", chatId);
}
}
// 回复消息
public void sendMsg(String text, Long chatId) {
// 使用 SendMessage 对象构建回复消息
SendMessage response = new SendMessage();
// 设置要发送消息的聊天对象、发送内容、消息内容支持 HTML 格式的解析
response.setChatId(String.valueOf(chatId));
response.setText(text);
response.setParseMode("html");
try {
// 执行发送消息
execute(response);
} catch (TelegramApiException e) {
e.getMessage();
}
}
}
运行成功