Nonebot2插件:不是那么正大光明的查看闪照和反撤回

这篇好像不是很适合直接放出来,适合自己对着文档源码阅读啥的

不过当成留档了就不管了

广告 长期招租,总之给404大佬打广告(720053992)
其实针对QQ这些事情已经有个很好用的QN插件,这个大概是给bot加点自己的功能吧

0.准备

啥都不想要,读读文档和其他的就行

好像新版的手机QQ突然不支持发闪照了,奇怪

一些碎碎念 因为自己学习了代码编写插件获取了闪照和撤回消息而被群友所讨厌甚至踢出只能算是自找的吧
毕竟推出闪照和撤回这种功能就有很多人是不希望自己发的东西被看到的
之前pc用了反撤回结果回复了撤回的消息当场被指责的情况也发生了不少
总之就这样吧,希望看了用了的人没事

1.实现

1. 闪照

这个官方商店里有实现,那个可以一键控制和全局关闭闪照消息获取

总之,闪照的CQ码格式与普通的图片一样,不过在type处加了个type=flash ,但奇怪的是go-cqhttp返回的json格式是

{'text':
     '[CQ:image,file=图片的md5码.image,url=,type=flash,subType=0]'
}

而不是图片的返回{'image':一些参数balabala},怪

同样使用 on_message() 作为响应器,并且过滤非闪照类型的消息(感觉直接用 on_regex() 会不会好点)

代码比较短
import nonebot
from nonebot.rule import *
from nonebot import *
from nonebot.plugin import on_keyword
from nonebot.adapters.onebot.v11 import Bot, Event, MessageEvent, GroupMessageEvent
from nonebot.adapters.onebot.v11.message import Message
import re


async def handle_rule(bot: Bot, event: Event) -> bool:
    msg = event.get_message()
    image_file = ''
    for i in event.get_message():
        if i.type=='text' and "type=flash" in i.data['text']: #如果出现了闪照格式的消息
            try:
                image_file = re.search('(?<=file=).*?(?=\.image)', str(i.data['text'])).group() # 正则匹配获取闪照的md5码 
            except:
                image_file = ''
    if image_file:
        return True
    return False


flash_back = on_message(rule=handle_rule, priority=50)


@flash_back.handle()
async def flash_back_handle(bot: Bot, event: Event):
    try:
        whatever, group_id, user_id = event.get_session_id().split('_')  # 获取当前群聊id,发起人id,返回的格式为group_groupid_userid
    except:  # 如果上面报错了,意味着发起的是私聊,返回格式为userid
        group_id = None
        user_id = event.get_session_id()
    image_file = ""
    for i in event.get_message():
        image_file = re.search('(?<=file=).*?(?=\.image)', str(i.data['text'])).group() # 同上,获取图片的md5码值
    url1 = f"https://gchat.qpic.cn/gchatpic_new/iamsb/2-2-{str(image_file).upper()}/0?term=3"
    '''
    QQ图像缓存地址为https://gchat.qpic.cn/gchatpic_new/任意字符/任意字符-任意字符-图片md5码(需要大写)/0?term=3(后面这个?请求貌似不需要)
    只需要注意MD5码一定要大写放进去
    '''
    if isinstance(event, GroupMessageEvent):
        await bot.call_api('send_group_msg', **{'group_id': "你设置的闪照接收群聊", 
                                                "message": f"群聊({group_id})中({user_id})发送了一张闪照[CQ:image,file={url1},id=40000]"})
    else:
        await bot.call_api('send_group_msg', **{'group_id': "同上",
                                                "message": f"好友({user_id})发送了一张闪照[CQ:image,file={url1},id=40000]"})
    await flash_back.finish()

示例不放了,大概就这么个意思

按照官方商店里的插件还加了一些参数控制群聊开启关闭,不过既然是获取闪照没必要在发闪照的群里直接怼回去吧......大概

只能说善用吧(官方插件都有了啊喂)

2.查看撤回信息

这个也没啥好说的,事件类型里专门有一种 Group/FriendRecallNoticeEvent 接收群消息撤回事件,然后可以获取消息id,最后再用go-cqhttp提供的获取消息api get_msg(message_id) 就好了

同时撤回是通知事件,所以要用 on_notice()

代码也挺短
import nonebot
from nonebot.rule import *
from nonebot import *
from nonebot.plugin import on_keyword
from nonebot.adapters.onebot.v11 import Bot, Event, GroupRecallNoticeEvent, FriendRecallNoticeEvent
from nonebot.adapters.onebot.v11.message import Message


async def handle_rule(bot: Bot, event: Event) -> bool:
    if isinstance(event, GroupRecallNoticeEvent) or isinstance(event, FriendRecallNoticeEvent): # 预先判断下消息类型不然老是响应
        return True
    return False


message_back = on_notice(rule=handle_rule, priority=50)


@message_back.handle()
async def message_back_handle(bot: Bot, Gevent: GroupRecallNoticeEvent): # 好像这里面定义的event类型只能放一种,不知道。分别处理群聊撤回和好友撤回
    msg = await bot.call_api('get_msg', **{"message_id": Gevent.message_id}) # 获取撤回的消息id
    mesg = msg['message']
    await bot.call_api('send_group_msg', **{"group_id": "你干这种坏事的群聊",
                                            "message": f"群聊{Gevent.group_id}中{Gevent.user_id}撤回了一条消息:\n{mesg}"})
    await message_back.finish()


@message_back.handle()
async def message_back_handle(bot: Bot, Fevent: FriendRecallNoticeEvent):
    msg = await bot.call_api('get_msg', **{"message_id": Fevent.message_id})
    mesg = msg['message']
    await bot.call_api('send_group_msg', **{"group_id": "同上",
                                            "message": f"好友{Fevent.user_id}撤回了一条消息:\n{mesg}"})
    await message_back.finish()

示例,没有,自己试试就好

最后测试好像就不能返回语音消息,非自行存储的表情包(即QQ商店里的那些),还有分享啥的都不行
(一般就是用来看撤回了啥文字和图片消息吧)

3.总之

这功能说好不好都挺.....毕竟都是工具咋用还是看自己吧...

update

上面两个插件混起来用会发生奇妙的化学反应(

比如某个人发了闪照,并且撤回了自己发的闪照,那么撤回群聊里就会发送闪照,紧接着闪照群聊里就会发这个闪照

然后就是为了自己撤回的消息/闪照也不会被读取,在rule或者进入事件后的时候加一个判断 user_id 是否为机器人就好了

posted @ 2022-05-25 23:30  FPICZEIT  阅读(1002)  评论(0编辑  收藏  举报