插件介绍

插件仓库: astrbot_plugin_god_meme

在群里发神 QQ号神 @人可以返回一张图片
用法
效果

插件分析

看了插件源码用的是AstrBot,是一个大模型机器人,没有研究过这个框架,找到核心代码部分,先在消息查找QQ号,找到之后获取用户信息,提取其中的QQ号和昵称,调用HTTP API生成图片,把生成的图片发到群里

猫猫模仿

猫猫的自动回复插件已经包含了简单的HTTP API调用,插件中的调用使用的是GET请求,传入QQ号和昵称即可生成,昵称没有可以直接使用的API,于是给猫猫加上了通过传入QQ号生成图片的功能

1
2
/dictadd 我是神 ${image|http://47.105.107.105:8000/meme?qq=${sender}}
/dictadd 这是神 ${image|http://47.105.107.105:8000/meme?qq=${reply_user}}

发送我是神或者回复这是神即可生成图片

插件适配

加载器

复制一份插件模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Plugin(object):
plugin_methods={'register':{'priority':30000,'func':'register','desc':'注册插件'},'enable':{'priority':30000,'func':'enable','desc':'启用插件'},'disable':{'priority':30000,'func':'disable','desc':'禁用插件'},'unregister':{'priority':30000,'func':'unregister','desc':'卸载插件'},'private_message':{'priority':30000,'func':'private_message','desc':'私聊消息处理'},'group_message':{'priority':30000,'func':'group_message','desc':'群消息处理'}}
plugin_commands={}
plugin_auths={'send_private_msg','seng_group_msg'}
auth=''
log=None
bot=None
util=None
dir=None


def register(self,logger,util,bot,dir):
self.log=logger
self.bot=bot
self.util=util
self.dir=dir
self.log.info("Plugin register")

def enable(self,auth):
self.auth=auth
self.log.info("Plugin enable")

def disable(self):
self.log.info("Plugin disable")

def unregister(self):
self.log.info("Plugin unregister")

def private_message(self,time,self_id,sub_type,message_id,user_id,message,raw_message,font,sender):
return False

def group_message(self,time,self_id,sub_type,message_id,group_id,user_id,anonymous,message,raw_message,font,sender):
return False

plugin_name="FengZi的神meme"
plugin_id="tk.mcsog.fengzi_shenmeme"
plugin_version="1.0.0"
plugin_author="f00001111"
plugin_desc="FengZi的神meme插件适配"

由于猫猫群很多,并不是所有群都要使用,加入权限控制代码,由于是适配过来的插件,并不需要经常切换哪些群需要,故使用控制台命令开关,如果没有这个需求不需要加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import os
import json

class Plugin(object):
...
plugin_commands={'shenmeme':'shenmeme_command','help':'shenmeme enable <群号> - 在指定群启用\nshenmeme disable <群号> - 在指定群禁用'}
...
config={'group':[]}

...

def enable(self,auth):
self.auth=auth
try:
with open(os.path.join(self.dir,'config.json'),'r') as f:
self.config=json.loads(f.read())
except:
with open(os.path.join(self.dir,'config.json'),'w') as f:
f.write(json.dumps(self.config))
self.log.info("Plugin enable")

def disable(self):
try:
with open(os.path.join(self.dir,'config.json'),'w') as f:
f.write(json.dumps(self.config))
except:
pass
self.log.info("Plugin disable")

...

def group_message(self,time,self_id,sub_type,message_id,group_id,user_id,anonymous,message,raw_message,font,sender):
if group_id in self.config['group']:
...
return False

def shenmeme_command(self,cmd):
if len(cmd)==2:
if cmd[0]=='enable':
try:
if int(cmd[1]) not in self.config['group']:
self.config['group'].append(int(cmd[1]))
with open(os.path.join(self.dir,'config.json'),'w') as f:
f.write(json.dumps(self.config))
self.log.info('启用成功')
except:
self.log.warning('参数错误')
elif cmd[0]=='disable':
try:
if int(cmd[1]) in self.config['group']:
self.config['group'].remove(int(cmd[1]))
with open(os.path.join(self.dir,'config.json'),'w') as f:
f.write(json.dumps(self.config))
self.log.info('禁用成功')
except:
self.log.warning('参数错误')
else:
self.log.warning('参数错误')
...

接着判断是否为开头且后面是不是QQ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def group_message(self,time,self_id,sub_type,message_id,group_id,user_id,anonymous,message,raw_message,font,sender):
if group_id in self.config['group']:
if raw_message.startswith('神') and len(raw_message)>6:
qq=0
try:
qq=int(raw_message[1:].strip())
except:
qq=0
for m in message:
if m['type']=='at':
try:
qq=int(m['data']['qq'])
except:
qq=0
if qq==0:
return False
...
return False

接着获取用户信息,根据原插件,首先从群里获取信息,接着获取陌生人信息,这里调用了OneBotAPI,需要在权限列表中声明,才能申请权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Plugin(object):
...
plugin_auths={'send_private_msg','send_group_msg','get_group_member_info','get_stranger_info'}
...
def group_message(self,time,self_id,sub_type,message_id,group_id,user_id,anonymous,message,raw_message,font,sender):
...
if qq==0:
return False
nickname=''
status,res=self.util.get_group_member_info(self.auth,group_id,qq,no_cache=True)
if status:
nickname=res.get('nickname','')
if nickname=='':
status,res=self.util.get_stranger_info(self.auth,qq)
if status:
nickname=res.get('nickname','')
if nickname=='':
nickname=str(qq)
...

获取用户信息后,使用HTTP API获取图片,根据OneBot文档,发送图片时可以传入图片路径、Base64URL三种,这里是调用API,故直接传入URL即可,为避免转义问题,手动对昵称进行转义

1
2
3
4
5
6
7
8
9
from urllib.parse import quote
...
def group_message(self,time,self_id,sub_type,message_id,group_id,user_id,anonymous,message,raw_message,font,sender):
...
if nickname=='':
nickname=str(qq)
self.util.send_group_msg(self.auth,group_id,self.util.seg_image('http://47.105.107.105:8000/meme?qq='+str(qq)+'&name='+quote(nickname)))
return True
...

功能基本实现,去掉没有用到的私聊部分即可,完整代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import os
import json
from urllib.parse import quote

class Plugin(object):
plugin_methods={'register':{'priority':30000,'func':'register','desc':'注册插件'},'enable':{'priority':30000,'func':'enable','desc':'启用插件'},'disable':{'priority':30000,'func':'disable','desc':'禁用插件'},'unregister':{'priority':30000,'func':'unregister','desc':'卸载插件'},'group_message':{'priority':30000,'func':'group_message','desc':'群消息处理'}}
plugin_commands={'shenmeme':'shenmeme_command','help':'shenmeme enable <群号> - 在指定群启用\nshenmeme disable <群号> - 在指定群禁用'}
plugin_auths={'send_group_msg','get_group_member_info','get_stranger_info'}
auth=''
log=None
bot=None
util=None
dir=None
config={'group':[]}


def register(self,logger,util,bot,dir):
self.log=logger
self.bot=bot
self.util=util
self.dir=dir
self.log.info("Plugin register")

def enable(self,auth):
self.auth=auth
try:
with open(os.path.join(self.dir,'config.json'),'r') as f:
self.config=json.loads(f.read())
except:
with open(os.path.join(self.dir,'config.json'),'w') as f:
f.write(json.dumps(self.config))
self.log.info("Plugin enable")

def disable(self):
try:
with open(os.path.join(self.dir,'config.json'),'w') as f:
f.write(json.dumps(self.config))
except:
pass
self.log.info("Plugin disable")

def unregister(self):
self.log.info("Plugin unregister")

def group_message(self,time,self_id,sub_type,message_id,group_id,user_id,anonymous,message,raw_message,font,sender):
if group_id in self.config['group']:
if raw_message.startswith('神') and len(raw_message)>6:
qq=0
try:
qq=int(raw_message[1:].strip())
except:
qq=0
for m in message:
if m['type']=='at':
try:
qq=int(m['data']['qq'])
except:
qq=0
if qq==0:
return False
nickname=''
status,res=self.util.get_group_member_info(self.auth,group_id,qq,no_cache=True)
if status:
nickname=res.get('nickname','')
if nickname=='':
status,res=self.util.get_stranger_info(self.auth,qq)
if status:
nickname=res.get('nickname','')
if nickname=='':
nickname=str(qq)
self.util.send_group_msg(self.auth,group_id,self.util.seg_image('http://47.105.107.105:8000/meme?qq='+str(qq)+'&name='+quote(nickname)))
return True
return False

def shenmeme_command(self,cmd):
if len(cmd)==2:
if cmd[0]=='enable':
try:
if int(cmd[1]) not in self.config['group']:
self.config['group'].append(int(cmd[1]))
with open(os.path.join(self.dir,'config.json'),'w') as f:
f.write(json.dumps(self.config))
self.log.info('启用成功')
except:
self.log.warning('参数错误')
elif cmd[0]=='disable':
try:
if int(cmd[1]) in self.config['group']:
self.config['group'].remove(int(cmd[1]))
with open(os.path.join(self.dir,'config.json'),'w') as f:
f.write(json.dumps(self.config))
self.log.info('禁用成功')
except:
self.log.warning('参数错误')
else:
self.log.warning('参数错误')

plugin_name="FengZi的神meme"
plugin_id="tk.mcsog.fengzi_shenmeme"
plugin_version="1.0.0"
plugin_author="f00001111"
plugin_desc="FengZi的神meme插件适配"

插件使用

将代码保存到文件,放入加载器的plugins目录,启动或重启加载器即可加载,在加载器命令行输入shenmeme enable 群号即可开启对应群功能,输入shenmeme disable 群号即可关闭对应群功能,群内发送神 QQ号神@人即可获得突图片