企微智能机器人SDK支持一个进程管理多个企微机器人

AI摘要
本文介绍了一款名为WeComAiBot的企业微信AI机器人PHP SDK新发布的多机器人实例管理功能。该功能允许在单个进程中运行多个完全隔离的机器人实例,通过共享事件循环和消息处理逻辑,同时为每个机器人提供独立的连接、认证、队列和状态管理,从而简化了多机器人场景下的部署、运维和资源管理。文章详细阐述了其核心设计、隔离机制、优势以及与Laravel框架的集成方式,属于技术性的开源项目知识分享。

背景

企业微信官方 AI 机器人 SDK(@wecom/aibot-node-sdk)的设计是:一个 WSClient 实例 = 一个机器人。要跑多个机器人?起多个进程。

这在小规模场景下没问题,但当你的企业有销售部、客服部、运维部各一个机器人,甚至每个业务线都有自己的 bot 时,管理成本就上来了——多个进程、多份配置、多套监控、多次部署。

我们的开源项目 WeComAiBot(企业微信 AI 机器人 PHP SDK)刚刚发布了多机器人实例管理功能,据我们所知,这是目前第一个在 SDK 层面原生支持单进程多 bot 的实现。

一句话:一个进程,多个 bot,完全隔离


$manager = new  BotManager([

['bot_id' => 'sales-bot', 'secret' => 'xxx'],

['bot_id' => 'support-bot', 'secret' => 'yyy'],

['bot_id' => 'ops-bot', 'secret' => 'zzz'],

]);

$manager->start(); // 一个进程,三个 bot 同时在线

每个 bot 拥有独立的 WebSocket 连接、心跳定时器、断线重连和发送队列。一个 bot 掉线不影响其他 bot,一个 bot 认证失败不阻塞其他 bot。

核心设计:共享 Handler + botId 隔离

多 bot 场景下最常见的需求是:多个机器人共享一套消息处理逻辑,但需要知道消息是哪个 bot 收到的。

我们的做法是在 MessageEvent 对象上注入 botId 字段:


// 一个 handler 服务所有 bot

$sharedHandler = function (Message  $message, Reply  $reply) {

$botId = $message->botId;

// 根据 botId 走不同的处理逻辑

match (true) {

str_contains($botId, 'sales') =>  $reply->text("【销售】{$message->text}"),

str_contains($botId, 'support') =>  $reply->text("【客服】{$message->text}"),

default  =>  $reply->text("收到: {$message->text}"),

};

};

// 所有 bot 注册同一个 handler

foreach ($manager->getAllBots() as $bot) {

$bot->onMessage($sharedHandler);

}

当然,你也可以为每个 bot 注册专属的 handler:


$manager->getBot('sales-bot')->onText(function (Message  $msg, Reply  $reply) {

// 只有销售 bot 收到文本消息时触发

$reply->text("请问您需要什么产品?");

});

两种方式可以混用,灵活组合。

隔离保证

有人会问:消息会不会串?Bot A 的消息会不会跑到 Bot B 的 handler 里?

不会。 隔离是多层的:

| 层级 | 隔离方式 |

|——|———-|

| WebSocket 连接 | 每个 bot 独立的 AsyncTcpConnection |

| 认证 | 各自的 bot_id + secret,服务端按连接推送 |

| 消息分发 | 每个 WeComBot 实例有独立的 handler 列表 |

| 回复通道 | Reply 绑定对应 bot 的连接,不会发错 |

| 发送队列 | 独立的串行队列,互不阻塞 |

| 心跳 / 重连 | 独立的定时器,互不干扰 |

| 消息去重 | 独立的 processedMsgIds 缓存 |

企微服务端的行为保证了传输层的隔离——它只会把属于 Bot A 的消息推送到 Bot A 的 WebSocket 连接。botId 字段是 SDK 层面的额外标识,让你在共享 handler 中也能轻松区分来源。

为什么不起多个进程?

当然可以。但单进程多 bot 有几个实际优势:

1. 运维简单

一个 Supervisor 配置、一个进程、一份日志。不用为每个 bot 写一套部署脚本。

2. 资源更省

多个 bot 共享一个 Workerman 事件循环,不需要额外的进程开销。对于消息量不大的场景(绝大多数企业内部机器人),单进程绑绑有余。

3. 跨 bot 协作更容易

在同一个进程内,bot 之间可以直接共享状态,不需要走 IPC 或消息队列。比如:


$manager->getBot('ops-bot')->onMessage(function (Message  $msg, Reply  $reply) use ($manager) {

// 运维 bot 收到告警,转发给销售 bot 的用户

$manager->getBot('sales-bot')->pushToUser('zhangsan', "运维告警: {$msg->text}");

$reply->text('已转发给销售团队');

});

Laravel 集成

配置文件里写个数组就行,不用改一行代码:


// config/wecomaibot.php

'bots' => [

[

'bot_id' => 'sales-bot',

'secret' => 'xxx',

'handler' => \App\Bots\SalesHandler::class,

],

[

'bot_id' => 'support-bot',

'secret' => 'yyy',

'handler' => \App\Bots\SupportHandler::class,

],

],

php  artisan  wecom:serve

# 输出:

# 正在连接企业微信(2 个机器人)...

# [sales-bot] 已上线,等待消息...

# [support-bot] 已上线,等待消息...

Artisan 命令自动检测配置模式:有 bots 数组就走多 bot,没有就走单 bot。已有的单 bot 项目零改动升级。

每个 bot 的 handler 类独立,也可以多个 bot 指向同一个 handler 类——handler 中通过 $message->botId 区分来源即可。

BotManager API 一览


// 构造时批量注册

$manager = new  BotManager([

['bot_id' => '...', 'secret' => '...'],

['bot_id' => '...', 'secret' => '...'],

]);

// 也可以逐个添加

$bot = $manager->addBot(['bot_id' => '...', 'secret' => '...']);

// 操作

$manager->getBot('bot-id'); // 获取机器人实例(按 bot_id)

$manager->getAllBots(); // 获取全部

$manager->removeBot('bot-id'); // 移除(自动断开连接)

$manager->start(); // 启动(阻塞)

日志自动带前缀,多 bot 日志不混淆:


[sales-bot] WebSocket connected, sending auth...

[sales-bot] Authenticated successfully

[support-bot] WebSocket connected, sending auth...

[support-bot] Authenticated successfully

安装


composer  require  bangbangda/wecomaibot

PHP >= 8.1,不需要 Swoole,不需要任何额外扩展。

链接


欢迎 Star、Issue、PR。有问题直接在 GitHub 提 Issue。

官方不做的事,社区来做。这就是开源的意义。

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!