使用PHP创建telegram聊天机器人
前言我使用的是ThinkPHP 框架,找了一个组件直接使用的。不过,如果自己写原生的对接,其实也很简单,本文我假设我的机器人名字是 abc_bot
推荐阅读 https://core.telegram.org/bots
组件安装和使用
https://telegram-bot-sdk.readme.io/docs
组件的安装和使用,在上面的手册写的很详细,不再复述,API文档可手册是这个https://telegram-bot-sdk.readme.io/reference。
下面说明几个常用的操作
1.创建机器人
使用浏览器访问 https://t.me/botfather 会自动跳转到 BotFather 的对话框。这个是管理你机器人的命令对话框。与它的对话都要以/ 开头。有些指令。/help,可以看到所有的可用指令
接收消息的设置
在 BotFather 对话框操作
/setprivacy
然后选择一个你的机器人,会弹出对话
'Enable' - your bot will only receive messages that either start with the '/' symbol or mention the bot by username.
'Disable' - your bot will receive all messages that people send to groups.
Current status is: DISABLED
选择 `Enable` 则在群消息中只有 `/abc_bot 消息`的时候,你才能看到消息
选择 `Disable` 则可以看到群里的所有消息。
2. API 操作
2.1 获取所有的消息
注意,在执行这个操作的时候,不能有 $telegram->setWebhook(),因为如果执行过 $telegram->setWebhook(),新数据其实是会直接返回给你指定的 url 的。如果你有开启,则需要执行 $telegram->removeWebhook() 关闭
注意这个操作最多可以获取100条数据,但是有两个参数可以使用
offset--开始获取数据的id,这个对应的是 update_id
limit-获取数据的条数
$key = config('telegram.bot_token');
return $this->get('https://api.telegram.org/bot' . $key . '/getUpdates');
或者
$telegram = new Api($key);
return $telegram->getUpdates();
获取到的参数
message.message_id - 消息ID,回复或者转发的时候可以用到
message.from.id - 发送消息的人的ID
message.chat.id - 所在群的ID,如果是个人发送给你的私信,则是个人ID 回复消息时候可以用到
2.2 发送消息的操作
$this->telegram->sendMessage([
'chat_id' => $chat_id, // 接收消息的人或者群的id-- message.chat.id
'text' => $message, // 消息内容
'parse_mode' => 'HTML', // 格式,这个可以不要
]);
2.3 回复消息的操作
$this->telegram->sendMessage([
'chat_id' => $chant_id, // message.chat,id 这个id必须是消息发布的群,不然不能实现回复
'reply_to_message_id' => $reply_message_id, // message.message_id 聊天中的具体一个消息id
'text' => $text, // 回复内容
]);
2.4 开启网站自动接收消息
网站必须是 https,路由随便你配置,只要跟你网站的匹配即可
$telegram->setWebhook(['url' => 'https://xxx.com/telegram/webhook']);
在开启网站自动接收消息后,执行 $telegram->getUpdates();
然后机器人所在的群,每次有人发消息,都会 post 推送到 `https://xxx.com/telegram/webhook`,你可以做相应的处理
接收的文字是 message.text
如果是图片加文字,则是 message.caption
2.5 关闭网站自动接收消息
网站必须是 https,路由随便你配置,只要跟你网站的匹配即可
$telegram->removeWebhook();
纸飞机安装
1. 安装组件
composer require irazasyed/telegram-bot-sdk ^2.0
2. 添加路由
2.1 'createWebHook' => ['web/telegramController/createWebHook', ['method' => 'get']],//创建群对话
2.2 'removeWebHook' => ['web/telegramController/removeWebHook', ['method' => 'get']],//删除群对话
2.3 'listenWebHook' => ['web/telegramController/listenWebHook', ['method' => 'post']],
2.1 是创建对话的,告诉飞机官网,我要用 2.3 这个路由接收飞机的返回消息
2.2 基本用不到,是删除对话的,告诉纸飞机 我不再接收飞机推送的消息了
2.3 的路由 必须是 https
参考文档 https://telegram-bot-sdk.readme.io/docs
3. 创建机器人
3.1/help
3.2 /newbot
3.3 名字+'_bot' 结尾 比如 'aaa_bot'
3.4 再次输入 3.3 的名字 'aaa_bot'
这时候,生成的 token 是你需要的
3.5 设置,群消息任何一条都接收通知
/setprivacy
然后选中你的机器人
然后选择 DISABLED
附PHP代码:
<?phpnamespace app\web\controller;use app\model\Member;use think\Controller;use Telegram\Bot\Api;use think\Db;use think\Log;use app\utils\CacheUtil;class TelegramController extends Controller{ // 机器人名字 mall_rebate1_bot const TG_TOKEN = 'xxxx'; private $chat_id; //群ID private $message_text;//群消息内容 /** * 错误代码 * @var int */ protected $errorCode; /** * 错误信息 * @var string */ protected $errorMessage = ''; /** * 返回错误代码 * @return int */ public function getErrorCode() { return $this->errorCode; } /** * 返回错误信息 * @return string */ public function getErrorMessage() { return $this->errorMessage; } /** * 创建对话 */ public function createWebHook() { $telegram = new Api(self::TG_TOKEN); return $telegram->setWebhook(['url' => 'https://xxxx/listenWebHook']); } /** * 移除对话 */ public function removeWebHook() { $telegram = new Api(self::TG_TOKEN); return $telegram->removeWebhook(); } /** * 监听对话 */ public function listenWebHook() { if (!$this->checkRequest()) { return false; } // 加彩金的方法 if (in_array($this->chat_id, ['-11', '-22'])) { $response_text = $this->transferIn(); if ($response_text) { return $this->replayMessage($response_text); } return true; } else {// return $this->replayMessage($this->chat_id); } return false; } private function transferIn() { // 使用空格做区分 $arr = array_values(array_filter(explode(" ", $this->message_text))); if (count($arr) != 2) { return '格式有误'; } $username = $arr[0]; $userInfo = Member::getByUsername($username); if (!$userInfo) { return '用户不存在' . $username; } // 业务 return 'success'; } /** * 推送消息 * @param $result * @return bool|\Telegram\Bot\Objects\Message * @throws \Telegram\Bot\Exceptions\TelegramSDKException */ private function replayMessage($result) { $telegram = new Api(self::TG_TOKEN); try { return $telegram->sendMessage([ 'chat_id' => $this->chat_id, // message.chat.id 这个id必须是消息发布的群,不然不能实现回复 'text' => $result, // 回复内容 'parse_mode' => 'HTML', ]); } catch (\Exception $exception) { $this->errorCode = -1; $this->errorMessage = $exception->getMessage(); // 一般来说都是 chat_id 有误 return false; } } /** * 检查请求消息 * @return bool */ private function checkRequest() { $info = file_get_contents('php://input'); $request = []; if (json_decode($info)) { $request = json_decode($info, 1); }// Log::info('222 notify1 start data = ' . json_encode($info)); // 1.检查数据格式 是否有 chat_id 和 caption if (!isset($request['message']['chat']['id'])) { $this->errorCode = -11; $this->errorMessage = 'chat id 不存在'; return false; } if (!isset($request['message']['text'])) { $this->errorCode = -12; $this->errorMessage = 'text不存在'; return false; // 这个不需要输出 不需要处理 } if ($request['message']['from']['is_bot'] == true) { return true;//机器人发送的消息 不需要处理 } // 群ID 也是chat_id $this->chat_id = $request['message']['chat']['id']; $this->message_text = trim($request['message']['text']); // 群消息 // 有中文 表示是聊天信息 preg_match('/^(\p{Han})/u', $this->message_text, $result); if ($result) { $this->errorCode = -3; $this->errorMessage = '中文聊天,不需要处理'; return false; // 这条消息不发送给飞机群 所以是 false } return true; }}