【Nanobot】README09_LEVEL4 添加新聊天渠道
🎯 目标
指导如何为 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 个分析单元已完成!
生成的文档列表:
- ✅ README01_LEVEL1_项目架构与目录说明.md
- ✅ README02_LEVEL2_Agent核心循环设计.md
- ✅ README03_LEVEL2_工具系统架构.md
- ✅ README04_LEVEL2_提供商系统设计.md
- ✅ README05_LEVEL2_渠道系统设计.md
- ✅ README06_LEVEL3_消息流转深度追踪.md
- ✅ README07_LEVEL3_会话管理与记忆.md
- ✅ README08_LEVEL4_添加新LLM提供商.md
- ✅ README09_LEVEL4_添加新聊天渠道.md
文档位置 :.aitalk/ 目录
建议阅读顺序:README01 → README02 → ... → README09