【Nanobot】README09_LEVEL4 添加新聊天渠道

【Nanobot】README09_LEVEL4 添加新聊天渠道

源码地址:https://github.com/HKUDS/nanobot


🎯 目标

指导如何为 nanobot 添加新的聊天渠道(如 Signal、Matrix、Line 等)。


📋 添加新 Channel 的步骤

步骤 1:创建 Channel 类

文件 :nanobot/channels/signal.py

python 复制代码
from nanobot.channels.base import BaseChannel
from nanobot.bus.events import InboundMessage, OutboundMessage
from nanobot.bus.queue import MessageBus
from typing import Any

class SignalChannel(BaseChannel):
    """
    Signal 消息渠道实现。

    特性:
    1. 接收 Signal 消息
    2. 发送消息到 Signal
    3. 支持流式输出(可选)
    """

    name = "signal"
    display_name = "Signal"

    def __init__(self, config: Any, bus: MessageBus):
        super().__init__(config, bus)

        # 初始化 Signal 客户端
        import signalbot

        self.bot = signalbot.Bot(config.phone_number)
        self._running = False

    async def start(self) -> None:
        """启动 Signal Bot。"""
        self._running = True

        # 注册消息处理器
        @self.bot.handler()
        async def on_message(message):
            await self._handle_message(
                sender_id=str(message.source),
                chat_id=str(message.chat_id),
                content=message.text,
                media=message.attachments or [],
            )

        # 启动 Bot
        await self.bot.start()

    async def stop(self) -> None:
        """停止 Signal Bot。"""
        self._running = False
        await self.bot.stop()

    async def send(self, msg: OutboundMessage) -> None:
        """发送消息到 Signal。"""
        await self.bot.send_message(
            chat_id=msg.chat_id,
            text=msg.content,
            quote_reply_to=msg.reply_to,
        )

步骤 2:实现流式输出(可选)

如果 Channel 支持编辑消息(如 Telegram),可以实现流式输出:

python 复制代码
async def send_delta(
    self,
    chat_id: str,
    delta: str,
    metadata: dict[str, Any] | None = None,
) -> None:
    """
    交付流式文本块。

    实现:
    1. 提取 stream_id
    2. 第一条消息 → 发送新消息
    3. 后续消息 → 编辑已有消息
    4. _stream_end → 清理缓冲区
    """
    stream_id = metadata.get("_stream_id") if metadata else None
    if not stream_id:
        return

    if metadata.get("_stream_delta"):
        # 增量内容
        if stream_id not in self._edit_buffers:
            # 发送第一条消息
            sent_msg = await self.bot.send_message(
                chat_id=chat_id,
                text=delta,
            )
            self._edit_buffers[stream_id] = sent_msg
        else:
            # 编辑已有消息
            old_msg = self._edit_buffers[stream_id]
            new_content = old_msg.text + delta
            await old_msg.edit(text=new_content)

    elif metadata.get("_stream_end"):
        # 流式结束
        if stream_id in self._edit_buffers:
            del self._edit_buffers[stream_id]

步骤 3:添加配置字段

文件 :nanobot/config/schema.py

在 ChannelsConfig 中添加字段:

python 复制代码
class ChannelsConfig(Base):
    telegram: TelegramConfig | None = None
    discord: DiscordConfig | None = None
    signal: SignalConfig | None = None  # 新增

class SignalConfig(Base):
    enabled: bool = False
    phone_number: str = ""
    allow_from: list[str] = ["*"]  # 访问控制列表

步骤 4:配置新 Channel

文件 :~/.nanobot/config.json

json 复制代码
{
  "channels": {
    "signal": {
      "enabled": true,
      "phoneNumber": "+1234567890",
      "allowFrom": ["*"]
    }
  }
}

步骤 5:测试新 Channel

bash 复制代码
# 启动 gateway
nanobot gateway

# 在 Signal 中发送消息给 Bot
# 应该收到回复

🔧 高级:插件化 Channel

如果希望将 Channel 作为独立插件发布(不修改核心代码),可以使用 entry_points。

项目结构

复制代码
nanobot-signal/
├── nanobot_signal/
│   └── __init__.py
└── pyproject.toml

pyproject.toml

toml 复制代码
[project]
name = "nanobot-signal"
version = "0.1.0"

[project.entry-points."nanobot.channels"]
signal = "nanobot_signal:SignalChannel"

[project.dependencies]
nanobot-ai = ">=0.1.0"
signalbot = "*"

nanobot_signal/__init__.py

python 复制代码
from nanobot.channels.base import BaseChannel
from nanobot.bus.queue import MessageBus
from typing import Any

class SignalChannel(BaseChannel):
    name = "signal"
    display_name = "Signal"

    def __init__(self, config: Any, bus: MessageBus):
        super().__init__(config, bus)
        # ... 实现代码 ...

安装和使用

bash 复制代码
# 安装插件
pip install nanobot-signal

# 配置(不需要修改核心代码)
cat > ~/.nanobot/config.json << EOF
{
  "channels": {
    "signal": {
      "enabled": true
    }
  }
}
EOF

# 启动
nanobot gateway

📝 检查清单

  • 实现 BaseChannel 接口
    • start() - 启动监听
    • send() - 发送消息
    • stop() - 停止监听
  • 处理消息
    • 接收消息并调用 _handle_message()
    • 支持媒体文件(图片、文档等)
    • 支持音频转录(可选)
  • 实现流式输出(可选)
    • send_delta() - 增量更新
    • 消息编辑缓冲区
  • 添加配置字段
    • 在 schema.py 中添加配置类
    • 在 config.json 中启用
  • 测试
    • 基本对话功能
    • 工具调用
    • 流式输出(如果支持)
    • 访问控制(allow_from)

🎯 完整示例:添加 Email Channel

Email Channel 已经内置,参考实现:

文件 :nanobot/channels/email.py

python 复制代码
class EmailChannel(BaseChannel):
    """电子邮件渠道。"""

    name = "email"
    display_name = "Email"

    async def start(self):
        """启动 IMAP 监听。"""
        import imaplib

        self.imap = imaplib.IMAP4_SSL(self.config.imap_server)
        self.imap.login(self.config.email, self.config.password)
        self.imap.select("INBOX")

        while self._running:
            # 轮询新邮件
            await self._check_new_emails()
            await asyncio.sleep(30)

    async def send(self, msg: OutboundMessage):
        """发送邮件。"""
        import smtplib
        from email.message import EmailMessage

        email = EmailMessage()
        email["From"] = self.config.email
        email["To"] = msg.chat_id
        email.set_content(msg.content)

        with smtplib.SMTP_SSL(self.config.smtp_server) as smtp:
            smtp.login(self.config.email, self.config.password)
            smtp.send_message(email)

📚 相关文件

  • nanobot/channels/base.py - BaseChannel 抽象基类
  • nanobot/channels/telegram.py - Telegram 实现示例
  • nanobot/channels/discord.py - Discord 实现示例
  • nanobot/config/schema.py - 配置模式

🎉 完成分析

全部 9 个分析单元已完成!

生成的文档列表:

  1. ✅ README01_LEVEL1_项目架构与目录说明.md
  2. ✅ README02_LEVEL2_Agent核心循环设计.md
  3. ✅ README03_LEVEL2_工具系统架构.md
  4. ✅ README04_LEVEL2_提供商系统设计.md
  5. ✅ README05_LEVEL2_渠道系统设计.md
  6. ✅ README06_LEVEL3_消息流转深度追踪.md
  7. ✅ README07_LEVEL3_会话管理与记忆.md
  8. ✅ README08_LEVEL4_添加新LLM提供商.md
  9. ✅ README09_LEVEL4_添加新聊天渠道.md

文档位置 :.aitalk/ 目录

建议阅读顺序:README01 → README02 → ... → README09

相关推荐
FRing032 小时前
vue2干货总结2(v-bind、v-for、v-model、指令修饰符、v-bind操作class和style)
开发语言·前端·vue.js·vue2
by209993 小时前
C++ 智能指针的所有权与使用
开发语言·c++·经验分享
Lynne3093 小时前
EtherCAT网络中,多个节点如何配置才能互不干扰?
网络·网络配置·ethercat·工业网络
砚底藏山河3 小时前
python量化自定义周期 K 线合成
java·开发语言·数据库·python·金融
视觉小萌新3 小时前
AI Class 3 · Chapter 1:变量、字符串、list/dict、if/for(python学习-小白版-有经验可跳过)
python·学习·list
Yang96113 小时前
实验室里的多面手:鼎讯信通TM-150信号发生器技术拆解与实测思考
网络
IT召唤狮3 小时前
开源企业级零信任项目Pangolin,零信任能挡住PHP核弹漏洞吗?
开发语言·开源·php
知已难寻3 小时前
03 · OpenStack的计算管理 Nova
运维·服务器·开发语言·云原生·云计算·openstack·开源软件
Rover Ramble3 小时前
C++ 用互斥锁实现读写锁
开发语言·c++
薛定谔的猫-菜鸟程序员4 小时前
软件架构设计师开发资料大全(从入门到精通)
后端·python·系统架构·flask·架构设计师