QQ 群机器人 Beta
在 QQ 开放平台 完成主体入驻,即可创建可在 QQ 群聊里使用的 QQ 群机器人。
在公网下使用
QQ 群聊适配器默认在本地启动资源服务让腾讯服务器能够访问媒体资源,需要在公网下使用。如果无法在公网下部署,请参考自定义资源服务。
python
from amiyabot.adapters.tencent.qqGroup import qq_group
client_secret = '******' # 密钥
bot = AmiyaBot(appid='******', token='******', adapter=qq_group(client_secret))
qq_group
参数
参数名 | 类型 | 释义 | 默认值 |
---|---|---|---|
client_secret | str | 机器人密钥 | |
default_chain_builder | 默认消息构建器 | None | |
default_chain_builder_options | 默认消息构建器参数 | QQGroupChainBuilderOptions() | |
shard_index | int | 分片下标,从 0 开始 | 0 |
shards | int | 分片总数 | 1 |
- 在机器人启动时,资源服务也会一同启动。
- 默认的资源服务是端口单例的,实例化多个 QQ 群聊适配器 AmiyaBot 或使用 多账号 时,同一个端口的资源服务会相互共享。
事件分片
考虑到开发者事件接收时可以实现负载均衡,QQ 提供了分片逻辑,事件通知会落在不同的分片上,可参考官方文档 分片连接LoadBalance 了解分片机制。
python
bot1 = AmiyaBot(
appid='...',
token='...',
adapter=qq_group(client_secret='...', shard_index=0, shards=2),
)
bot2 = AmiyaBot(
appid='...',
token='...',
adapter=qq_group(client_secret='...', shard_index=1, shards=2),
)
注意
每个分片的启动应当按顺序缓慢进行,切勿同时启动,以免 gateway 返回的信息一致造成连接失败。
python
# 仅作示意,实际上每个分片应当是独立的服务。
def start():
asyncio.create_task(bot1.start())
time.sleep(2)
asyncio.create_task(bot2.start())
修改资源服务配置
引入 QQGroupChainBuilderOptions
修改默认的资源服务配置。
参数名 | 类型 | 释义 | 默认值 |
---|---|---|---|
host | str | 资源服务监听地址 | 0.0.0.0 |
port | int | 资源服务监听端口 | 8086 |
resource_path | str | 临时文件存放目录 | ./resource |
http_server_options | dict | HttpServer **kwargs |
python
from amiyabot.adapters.tencent.qqGroup import qq_group
from amiyabot.adapters.tencent.qqGroup.builder import QQGroupChainBuilderOptions
bot = AmiyaBot(
appid='******',
token='******',
adapter=qq_group(
client_secret='******',
default_chain_builder_options=QQGroupChainBuilderOptions(
'0.0.0.0',
8086,
'./resource',
),
),
)
自定义资源服务
非公网部署下的资源服务难题解决途径非常多,这里列举两个比较常见的解决办法。
使用内网穿透
使用一些内网穿透工具代理本地地址 http://127.0.0.1:8086(视配置而定)后,通常会得到一个新的地址。继承 QQGroupChainBuilder
并覆盖 domain 方法,即可使用内网穿透让腾讯服务器访问资源。
示例:
http://3913rc56vl17.vicp.fun:40229/resource
红色高亮部分即为内网穿透地址,/resource
为固定的路由值。
python
from amiyabot.adapters.tencent.qqGroup import qq_group, QQGroupChainBuilder, QQGroupChainBuilderOptions
class PenetrationChainBuilder(QQGroupChainBuilder):
@property
def domain(self):
return 'http://3913rc56vl17.vicp.fun:40229/resource'
bot = AmiyaBot(
...,
adapter=qq_group(
...,
default_chain_builder=PenetrationChainBuilder(
QQGroupChainBuilderOptions(),
),
),
)
继承 ChainBuilder 并实现相关方法使用第三方托管服务。
多数情况下我们推荐使用第三方托管服务来搭建资源服务,如 腾讯云COS 或 阿里云OSS 等。通过自定义默认的 ChainBuilder
,来实现上传文件到托管服务以及返回生成的 url。
python
from typing import Union
from graiax import silkcoder
from amiyabot import ChainBuilder
class ThirdPartyChainBuilder(ChainBuilder):
@classmethod
async def get_image(cls, image: Union[str, bytes]) -> Union[str, bytes]:
# 上传图片到第三方托管服务
...
return url # 返回访问资源的 URL
@classmethod
async def get_voice(cls, voice_file: str) -> str:
# 上传语音文件到第三方托管服务,语音文件必须是 silk 格式
voice: bytes = await silkcoder.async_encode(voice_file, ios_adaptive=True)
...
return url # 返回访问资源的 URL
@classmethod
async def get_video(cls, video_file: str) -> str:
# 上传视频文件到第三方托管服务
...
return url # 返回访问资源的 URL
bot = AmiyaBot(
...,
adapter=qq_group(
...,
default_chain_builder=ThirdPartyChainBuilder(),
),
)