Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support adapter qq #20

Merged
merged 3 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ async def handle(user_info: UserInfo = BotUserInfo()): # 获取Bot用户信息
- [x] Discord
- [x] DoDo
- [x] Satori
- [x] QQ

### 鸣谢

Expand Down
1 change: 1 addition & 0 deletions nonebot_plugin_userinfo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@
"~discord",
"~dodo",
"~satori",
"~qq",
},
)
1 change: 1 addition & 0 deletions nonebot_plugin_userinfo/adapters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from . import kaiheila as kaiheila
from . import onebot_v11 as onebot_v11
from . import onebot_v12 as onebot_v12
from . import qq as qq
from . import red as red
from . import satori as satori
from . import telegram as telegram
63 changes: 63 additions & 0 deletions nonebot_plugin_userinfo/adapters/qq.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from typing import Optional

from nonebot.exception import ActionFailed
from nonebot.log import logger

from ..getter import UserInfoGetter, register_user_info_getter
from ..image_source import ImageUrl, QQAvatarOpenId
from ..user_info import UserInfo

try:
from nonebot.adapters.qq import (
Bot,
C2CMessageCreateEvent,
Event,
GroupAtMessageCreateEvent,
GuildMessageEvent,
)

@register_user_info_getter(Bot, Event)
class Getter(UserInfoGetter[Bot, Event]):
async def _get_info(self, user_id: str) -> Optional[UserInfo]:
user = None

if self.bot.self_id == user_id:
try:
user = await self.bot.me()
except ActionFailed as e:
logger.warning(f"Error calling me: {e}")

if not user and isinstance(self.event, GuildMessageEvent):
if self.event.author.id == user_id:
user = self.event.author
else:
guild_id = self.event.guild_id
try:
member = await self.bot.get_member(
guild_id=guild_id, user_id=user_id
)
if member:
user = member.user
except ActionFailed as e:
logger.warning(f"Error calling get_member: {e}")

if user:
return UserInfo(
user_id=user.id,
user_name=user.username or "",
user_avatar=ImageUrl(url=user.avatar) if user.avatar else None,
)

if isinstance(
self.event, (C2CMessageCreateEvent, GroupAtMessageCreateEvent)
):
return UserInfo(
user_id=user_id,
user_name="",
user_avatar=QQAvatarOpenId(
appid=self.bot.bot_info.id, user_openid=user_id
),
)

except ImportError:
pass
9 changes: 9 additions & 0 deletions nonebot_plugin_userinfo/image_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@
return data


class QQAvatarOpenId(ImageSource):
appid: str
user_openid: str

async def get_image(self) -> bytes:
url = f"https://q.qlogo.cn/qqapp/{self.appid}/{self.user_openid}/100"
return await download_url(url)

Check warning on line 73 in nonebot_plugin_userinfo/image_source.py

View check run for this annotation

Codecov / codecov/patch

nonebot_plugin_userinfo/image_source.py#L72-L73

Added lines #L72 - L73 were not covered by tests


class TelegramFile(ImageSource):
token: str
file_path: str
Expand Down
77 changes: 43 additions & 34 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ nonebot-adapter-kaiheila = "^0.3.1"
nonebot-adapter-telegram = { git = "https://github.com/nonebot/adapter-telegram.git" }
nonebot-adapter-feishu = "^2.4.0"
nonebot-adapter-red = "^0.9.0"
nonebot-adapter-discord = { git = "https://github.com/nonebot/adapter-discord.git" }
nonebot-adapter-discord = "^0.1.4"
nonebot-adapter-dodo = "^0.2.0"
nonebot-adapter-satori = "^0.9.3"
nonebot-adapter-qq = "^1.4.1"

[tool.pytest.ini_options]
asyncio_mode = "auto"
Expand Down
4 changes: 3 additions & 1 deletion tests/plugins/echo.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,7 @@ async def _(bot: Bot, event: Event, arg: Message = CommandArg()):


@bot_user_info_cmd.handle()
async def _(user_info: Optional[UserInfo] = BotUserInfo(use_cache=False)): # 获取Bot用户信息
async def _(
user_info: Optional[UserInfo] = BotUserInfo(use_cache=False),
): # 获取Bot用户信息
await bot_user_info_cmd.send("", user_info=user_info)
107 changes: 107 additions & 0 deletions tests/test_qq.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
from datetime import datetime

from nonebot.adapters.qq import (
Bot,
EventType,
GroupAtMessageCreateEvent,
MessageCreateEvent,
)
from nonebot.adapters.qq.config import BotInfo
from nonebot.adapters.qq.models import GroupMemberAuthor, Member, User
from nonebug import App


def _fake_message_create_event(msg: str) -> MessageCreateEvent:
return MessageCreateEvent(
id="id",
__type__=EventType.MESSAGE_CREATE,
channel_id="6677",
guild_id="5566",
author=User(id="3344", username="MyUser", avatar="http://xxx.jpg"),
content=msg,
)


def _fake_group_at_message_create_event(msg: str) -> GroupAtMessageCreateEvent:
return GroupAtMessageCreateEvent(
id="id",
content=msg,
timestamp="1234567890",
__type__=EventType.GROUP_AT_MESSAGE_CREATE,
author=GroupMemberAuthor(
id="id",
member_openid="3F21411B784D403E811E68BF3E2944D8",
),
group_openid="19303D3617EF432999F24342F99AEC65",
)


async def test_message_event(app: App):
from nonebot_plugin_userinfo import UserInfo
from nonebot_plugin_userinfo.image_source import ImageUrl, QQAvatarOpenId

async with app.test_matcher() as ctx:
bot = ctx.create_bot(
base=Bot, self_id="2233", bot_info=BotInfo(id="2233", token="", secret="")
)

user_info = UserInfo(
user_id="3344",
user_name="MyUser",
user_displayname=None,
user_remark=None,
user_avatar=ImageUrl(url="http://xxx.jpg"),
user_gender="unknown",
)
event = _fake_message_create_event("/user_info")
ctx.receive_event(bot, event)
ctx.should_call_send(event, "", True, user_info=user_info)

user_info = UserInfo(
user_id="1234",
user_name="member",
user_displayname=None,
user_remark=None,
user_avatar=ImageUrl(url="http://xxx.jpg"),
user_gender="unknown",
)
event = _fake_message_create_event("/user_info 1234")
ctx.receive_event(bot, event)
ctx.should_call_api(
"get_member",
{"guild_id": "5566", "user_id": "1234"},
Member(
user=User(id="1234", username="member", avatar="http://xxx.jpg"),
joined_at=datetime.now(),
),
)
ctx.should_call_send(event, "", True, user_info=user_info)

user_info = UserInfo(
user_id="2233",
user_name="Bot",
user_displayname=None,
user_remark=None,
user_avatar=ImageUrl(url="http://xxx.jpg"),
user_gender="unknown",
)
event = _fake_message_create_event("/bot_user_info")
ctx.receive_event(bot, event)
ctx.should_call_api(
"me", {}, User(id="2233", username="Bot", avatar="http://xxx.jpg")
)
ctx.should_call_send(event, "", True, user_info=user_info)

user_info = UserInfo(
user_id="3F21411B784D403E811E68BF3E2944D8",
user_name="",
user_displayname=None,
user_remark=None,
user_avatar=QQAvatarOpenId(
appid="2233", user_openid="3F21411B784D403E811E68BF3E2944D8"
),
user_gender="unknown",
)
event = _fake_group_at_message_create_event("/user_info")
ctx.receive_event(bot, event)
ctx.should_call_send(event, "", True, user_info=user_info)
Loading