nb2 插件编写指南(三)
最近要给 bot 加一些常用小功能,算是新东西,就来记录一下
这篇文章的要点:
- 使用 api 来设置入群、退群提醒
- 使用 lolicon 的 api 来编写美(se)图插件
- (附加)与上插件配套,查询本地保存图库图片数量
使用 api 来设置入群、退群提醒
文档:
go-cqhttp notice
nonebot2 groupdecreasenoticeevent
需要先导入包:
from nonebot import on_notice
from nonebot.adapters.cqhttp import GroupIncreaseNoticeEvent,GroupDecreaseNoticeEvent
GroupIncreaseNoticeEvent
检测加群
GroupDecreaseNoticeEvent
检测退群
on_notice()
是响应器,如果有 notice 事件便会响应,一般为群通知,例如:群人数变更,群资料变更
新的响应非常好写:
welcom=on_notice()
对,这就没了,不需要加什么参数,有事件直接响应就行
主体部分改的比较多,但是也很简单
@welcon.handle()
开头还是没变
下面的 event 要改成响应的事件,例如:
加群:
async def welcome(bot: Bot, event: GroupIncreaseNoticeEvent, state: T_State):
退群:
async def welcome(bot: Bot, event: GroupDecreaseNoticeEvent, state: T_State):
这个可以在一起,用一个名称,一会 🌰 可以看到
接下来和其他插件一样,发信息就行了
@新成员可以使用even.get_user_id()
来获取
这些在官方 api 文档中有
可以使用if
来判断是否为指定群,这个可以优化,但是只有一个群的话这样就行了
完整示例
加群:
from nonebot importon_notice
from nonebot.typing import T_State
from nonebot.adapters import Bot, Event
from nonebot.adapters.cqhttp.message import Message
from nonebot.adapters.cqhttp import GroupIncreaseNoticeEvent
welcom=on_notice()
@welcom.handle()
async def welcome(bot: Bot, event: GroupIncreaseNoticeEvent, state: T_State):
user = event.get_user_id()
at_ = "欢迎!:[CQ:at,qq={}]".format(user)
msg = at_ + '大佬加入聊天组'
msg = Message(msg)
print(at_)
if event.group_id == 这里写群号:
await welcom.finish(message=Message(f'{msg}'))
退群和加群一样,改一下 event 就行了
还可以放一起:
from nonebot importon_notice
from nonebot.typing import T_State
from nonebot.adapters import Bot, Event
from nonebot.adapters.cqhttp.message import Message
from nonebot.adapters.cqhttp import GroupIncreaseNoticeEvent,GroupDecreaseNoticeEvent
welcom=on_notice()
@welcom.handle()
async def welcome(bot: Bot, event: GroupIncreaseNoticeEvent, state: T_State):
user = event.get_user_id()
at_ = "欢迎!:[CQ:at,qq={}]".format(user)
msg = at_ + '大佬加入聊天组'
msg = Message(msg)
if event.group_id == 这里写群号:
await welcom.finish(message=Message(f'{msg}'))
@welcom.handle()
async def welcome(bot: Bot, event: GroupDecreaseNoticeEvent, state: T_State):
user = event.get_user_id()
msg = "{}退出了聊天组".format(user)
msg = Message(msg)
if event.group_id == 这里写群号:
await welcom.finish(message=Message(f'{msg}'))
setu 插件编写
使用 lolicon 的 api
lolicon
- 啊,我知道你来找这个的目的只想抄抄抄和冲冲冲((((((
- 那我就不废话写指南了,直接放代码吧
使用的 py 包
from nonebot import on_command
from nonebot.rule import to_me
from nonebot.typing import T_State
from nonebot.adapters import Bot, Event
from nonebot.adapters.cqhttp.message import Message
import _thread
import urllib3
import json
事件响应
st = on_command("stst", aliases={'/来份涩图', '/来张涩图', '/来点色图','/来点二次元', }, priority=1)
图片获取
async def stapi():
# url拼接
url = "https://api.lolicon.app/setu/"
apikey = ""
r18 = "0"
num = "1"
size1200 = "true"
url_str = url + "?apikey=" + apikey + "&r18=" + r18 + "&num=" + num + "&size1200=" + size1200
# 访问网站获取json
r = urllib3.PoolManager().request('GET', url_str)
hjson = json.loads(r.data.decode())
#quota = hjson["quota"]
quota="error"
st_url = hjson["data"][0]["url"]
st_pid = hjson["data"][0]["pid"]
st_painter = hjson["data"][0]["author"]
st_title = hjson["data"][0]["title"]
# 读取图片
path = "./data/images/setu/" + str(st_pid) + st_url[-4:]
img = urllib3.PoolManager().request('GET', st_url)
with open(path, 'wb') as f:
f.write(img.data)
api_return = [
st_url,
quota,
st_pid,
st_painter,
path,
st_title
]
return api_return
其中:
img = urllib3.PoolManager().request('GET', st_url)
with open(path, 'wb') as f:
f.write(img.data)
部分是用了把图片保存到本地的,删掉就不会保存
事件处理&图片发送
@st.handle()
async def handle_first_receive(bot: Bot, event: Event, state: T_State):
await st.send("请稍等,图片正在下载~~\n请不要重复请求")
try:
api_return = await stapi()
try:
# await st.send("测试:返回url\n" + api_return[0] +
# "\n测试:返回图片地址\n" + api_return[4])
cq = "[CQ:image,file=" + str(api_return[0]) + ",id=40000]"
# await st.send("测试:返回cq码\n" + cq)
await st.send(Message(cq +
"\n" + api_return[5] +
"\n画师:" + api_return[3] +
"\npid:" + str(api_return[2]) +
"\n图片地址" + str(api_return[0])))
except:
await st.send("图片发送出错\n" +
"cq:\n" + cq +
"\n-----------------------------------------------" +
"\n" + api_return[5] +
"\n画师:" + api_return[3] +
"\npid:" + str(api_return[2]) +
"\n图片地址" + str(api_return[0]))
except:
await st.send("无法启动线程")
把这几个拼在一起就能直接用了
(附加)本地图库查询
from nonebot import on_command
from nonebot.rule import to_me
from nonebot.typing import T_State
from nonebot.adapters import Bot, Event
from nonebot.adapters.cqhttp.message import Message
import os
HMST = on_command("HMST", aliases={'/图库', }, priority=5)
files = []
@HMST.handle()
async def handle_first_receive(bot: Bot, event: Event, state: T_State):
try:
all_files = os.listdir('这里放图库文件夹地址')
#print(all_files)
#print(len(all_files))
path = r'这里也是图库文件夹地址'
# print(os.listdir(path))
ls = os.listdir(path)
def get_all_file(dir_path):
global files
for filepath in os.listdir(dir_path):
tmp_path = os.path.join(dir_path,filepath)
if os.path.isdir(tmp_path):
get_all_file(tmp_path)
else:
files.append(tmp_path)
return files
def calc_files_size(files_path):
files_size = 0
for f in files_path:
files_size += os.path.getsize(f)
return files_size
files = get_all_file(path)
st=str(round(calc_files_size(files)/1024/1024/1024, 2))+' G'
await HMST.send("本地图库内图片数量:\n"+str(len(all_files))+"\n本地图库大小:\n"+st)
files.clear()
except:
await HMST.send("获取本地图库失败")
files.clear()