使用PHP创建telegram聊天机器人

2024-10-06 57 0

前言我使用的是ThinkPHP 框架,找了一个组件直接使用的。不过,如果自己写原生的对接,其实也很简单,本文我假设我的机器人名字是 abc_bot

推荐阅读 https://core.telegram.org/bots

组件安装和使用

https://telegram-bot-sdk.readme.io/docs

组件的安装和使用,在上面的手册写的很详细,不再复述,API文档可手册是这个https://telegram-bot-sdk.readme.io/reference。

下面说明几个常用的操作

1.创建机器人

20241006104117428

使用浏览器访问 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;
    }}

 

    相关文章

    深入探讨文件服务器的定义、特点,以及与传统服务器的不同之处
    Thinkphp8安装topthink/think-captcha验证码的和使用方法
    PHP telegram电报机器人 消息回声机器人
    php 取当月有多少天 然后返回整数的方法
    php计算两个日期之间相隔的天数
    在 ThinkPHP8 中,选择使用 findOrEmpty() 还是 find() 取决于你对结果处理的需求

    发布评论