Compare commits

...
8 Commits
Author SHA1 Message Date
Wbucket 87551ee358 fix : 忘记存储群组了QAQ 2026-09-30 23:00:53 +08:00
Wbucket 99acbf6cc9 fix : 全量覆盖@消息(十分蹩脚的方式) 2026-09-30 22:09:26 +08:00
Wbucket 9e46704d63 feat : 群组记录存储 && .gitingore 2026-09-30 22:08:14 +08:00
Wbucket 9cb81deab4 feat : mcwatcher 广播 2026-09-30 21:18:03 +08:00
Wbucket 3d5ee01873 feat : 全局消息监听 2026-09-30 18:39:25 +08:00
Wbucket 5db01d429d fix : 移除dev 2026-09-30 16:23:55 +08:00
Wbucket cac4856f2f fix : 暂时添加dev变量 2026-09-30 13:28:33 +08:00
Wbucket f7ad06c085 feat : 入群消息和自定事件触发接口 2026-09-30 13:21:45 +08:00
3 changed files with 253 additions and 123 deletions
+4
View File
@@ -173,3 +173,7 @@ cython_debug/
# PyPI configuration file # PyPI configuration file
.pypirc .pypirc
.*
state.json
botpy.log*
joined_group.cfg
+120 -16
View File
@@ -1,9 +1,14 @@
from typing import Any, List from typing import Any, List
import group
import botpy from botpy.connection import ConnectionSession
from botpy.message import (Message) from botpy.message import (Message,GroupMessage)
from botpy import logger from botpy.flags import (Flag,fill_with_flags)
from botpy import( logger,Intents,Client)
from botpy.gateway import (BotWebSocket)
from botpy.types.gateway import MessagePayload
import queue import queue
from botpy.types.session import Session
from dotenv import load_dotenv from dotenv import load_dotenv
import os import os
import types import types
@@ -13,9 +18,33 @@ from threading import Thread
import asyncio import asyncio
#环境配置 #环境配置
class djtuWebsocket (botpy.Client) : class Intents_ex(Intents):
def __init__(self, **kwargs: bool) -> None:
arg_tmp = dict[str,bool]()
arg_ex = dict[str,bool]()
for key, value in kwargs.items():
if key in ['member_event']:
arg_ex[key] = value
else:
arg_tmp[key] = value
super().__init__(**arg_tmp)
for key , value in arg_ex.items() :
setattr(self, key, value)
@Flag
def member_event(self):
return 1 << 24
class BotWebsocket_ex(BotWebSocket):
def __init__(self, session: Session, _connection: ConnectionSession):
super().__init__(session, _connection)
self._parser['group_member_add'] = lambda aaw:self._connection.dispatch("group_member_add",aaw)
self._parser['group_message_create'] = lambda aaw:self._connection.dispatch("group_message_create",aaw)
class djtuWebsocket (Client) :
def __init__( def __init__(
self, intents: botpy.Intents, self, intents: Intents,
timeout: int = 5, timeout: int = 5,
is_sandbox=False, is_sandbox=False,
log_config: str | dict | None = None, log_config: str | dict | None = None,
@@ -26,14 +55,58 @@ class djtuWebsocket (botpy.Client) :
self.q = queue.Queue() self.q = queue.Queue()
super().__init__(intents, timeout, is_sandbox, log_config, log_format, log_level, bot_log, ext_handlers) super().__init__(intents, timeout, is_sandbox, log_config, log_format, log_level, bot_log, ext_handlers)
async def bot_connect(self, session):
"""
newConnect 启动一个新的连接,如果连接在监听过程中报错了,或者被远端关闭了链接,需要识别关闭的原因,能否继续 resume
如果能够 resume,则往 sessionChan 中放入带有 sessionID 的 session
如果不能,则清理掉 sessionID,将 session 放入 sessionChan 中
session 的启动,交给 start 中的 for 循环执行,session 不自己递归进行重连,避免递归深度过深
param session: session对象
"""
logger.info("[botpy] 会话启动中...")
client = BotWebsocket_ex(session, self._connection)
try:
await client.ws_connect()
except (Exception, KeyboardInterrupt, SystemExit) as e:
await client.on_error(e)
async def on_group_at_message_create(self, message: Message): async def on_group_at_message_create(self, message: Message):
await self.parseCommand(message) await self.parseCommand(message)
async def on_group_message_create(self,message:Message): async def on_group_message_create(self,message):
# 检验是否有自身@消息
try:
msg = message['d']
mention = msg['mentions']
for m in mention :
if m['is_you'] == True:
return await self.parseCommand(GroupMessage(self.api,msg['id'],MessagePayload(message['d'])))
except:
'没有@消息欸'
await self.parseGlobalMessage(message) return await self.parseGlobalMessage(message)
async def on_group_member_add(self,payload):
# await message.reply(content="awdwa")
openid = 'null'
memberid = 'null'
eid ='null'
try :
eid = payload['id']
data = payload['d']
openid = data['group_openid']
memberid = data['member_openid']
except:
logger.warning("data解析失败")
return
logger.info("入群信息:"+' 群: '+openid+" openid: "+memberid)
await self.api.post_group_message(openid,event_id=eid,content='欢迎加入大海啸!\n入服教程请看链接:\nhttps://starptr.top')
# 触发概率不大所以可以直接提取关键字 # 触发概率不大所以可以直接提取关键字
async def parseCommand(self,msg :Message): async def parseCommand(self,msg :Message):
commands:dict[str,types.MethodType|types.FunctionType] = { commands:dict[str,types.MethodType|types.FunctionType] = {
@@ -54,7 +127,38 @@ class djtuWebsocket (botpy.Client) :
await msg.reply(content=reply) await msg.reply(content=reply)
# 触发概率大,以后要做好解析防止刷屏 # 触发概率大,以后要做好解析防止刷屏
# async def parseGlobalMessage(self,msg:Message): async def parseGlobalMessage(self,payload):
try :
msg = payload['d']
gid = msg['group_id']
content = msg['content']
except:
return
# 加入群聊
new_group = True
if not groups is None :
for i in groups.groups :
if i.find(gid) != -1 :
new_group = False
if new_group :
groups.groups.append(gid)
groups.save()
# 解析指令
commands:dict[str,types.MethodType|types.FunctionType] = {
r'吃什么' : lambda :"是啊吃什么"
}
required = content
reply = ""
for cmd,func in commands.items():
if required.find(cmd) != -1:
try:
reply = func()
except:
reply = "服务异常"
break
if reply.__len__() == 0:
return
await self.api.post_group_message(gid,content=reply)
# await msg.reply(content="awda") # await msg.reply(content="awda")
# 监听队列,接受其他线程的消息 # 监听队列,接受其他线程的消息
@@ -64,12 +168,12 @@ class djtuWebsocket (botpy.Client) :
# time.sleep会阻塞整个线程我去 # time.sleep会阻塞整个线程我去
await asyncio.sleep(20) await asyncio.sleep(20)
else: else:
# 广播
try : try :
msg = self.q.get() msg = self.q.get()
if group_open_id is None: for i in groups.groups:
logger.error("群聊不存在")
continue asyncio.create_task(self.api.post_group_message(i,content=msg))
asyncio.create_task(self.api.post_group_message(group_open_id,content=msg))
except Exception as e: except Exception as e:
logger.error("MCWatcher发送群聊任务失败:\n"+str(e)) logger.error("MCWatcher发送群聊任务失败:\n"+str(e))
@@ -80,7 +184,7 @@ bbyAccount = os.getenv("BOBBY_ACCOUNT")
bbyPasswd = os.getenv("BOBBY_PASSWORD") bbyPasswd = os.getenv("BOBBY_PASSWORD")
appid = os.getenv("APP_ID") appid = os.getenv("APP_ID")
secret_bot = os.getenv("SECRET") secret_bot = os.getenv("SECRET")
group_open_id = os.getenv("GROUP_OPEN_ID") groups = group.GroupCtl()
if appid is None or secret_bot is None : if appid is None or secret_bot is None :
raise SystemExit("未找到bot配置!") raise SystemExit("未找到bot配置!")
@@ -109,14 +213,14 @@ async def main(ws:djtuWebsocket, *args: Any, **kwargs: Any) -> None:
logger.error(e) logger.error(e)
# bot初始化 # bot初始化
ws = djtuWebsocket(botpy.Intents(public_messages=True)) ws = djtuWebsocket(Intents_ex(public_messages=True,member_event=True))
# 启动mcwatcher线程 # 启动mcwatcher线程
def pushQuene(cont:str): def pushQuene(cont:str):
ws.q.put(cont) ws.q.put(cont)
Thread(target=watcher.MCWatcher,name="watcher",kwargs={ Thread(target=watcher.MCWatcher,name="watcher",kwargs={
"hookfunction":pushQuene, "hookfunction":pushQuene,
"logging":logger "logging":logger
}).start() }).start()
# bot线程运行 # bot线程运行
+22
View File
@@ -0,0 +1,22 @@
import os
# 记录加入的群组
class GroupCtl :
path = os.path.join(os.getcwd(),"joined_group.cfg")
groups:list[str] = []
def __init__(self) -> None:
with open(self.openfile()) as awa:
self.groups = awa.readlines()
def save(self):
# 重新加载
fd = self.openfile()
os.truncate(self.path,0)
os.write(fd,bytes('\n'.join(self.groups),'utf-8'))
os.close(fd)
def openfile(self):
return os.open(self.path,os.O_RDWR|os.O_CREAT)