pbf.controller.Client
Client包的使用方法
Msg类的使用
构造器定义
Msg(*messages, event: pbf.controller.Data.Event = None)
您可以传入多个消息,消息可以是str或Statement对象。str中可以包含CQ码,会自动转为Statement对象。
msg1 = [
TextStatement("这是一段消息"),
FaceStatement(114)
]
msg2 = [
FaceStatement(514),
"str类型会自动被转为TextStatement",
TextStatement("这是另一段文本")
]
msg3 = [
"[CQ:face,id=191]", # 若str中含有CQ码,会自动被转换!
TextStatement("这是一段text消息"),
"这是另一段text消息"
]
上面三种传参方式都是可以的
event参数是当前正在处理的事件,您可以选择不传入。
如果传入event,后续调用send方法的时候将会自动选择事件中对应的用户或群聊发送
如果不传入,您需要调用send_to方法指定用户或群聊ID并发送
send方法
send(self, retry: int = 0, image: bool = True)
retry表示重试次数,0表示不重试image表示是否尝试自动转为图片发送
当retry次数耗尽时,若image传参为True,就会尝试自动将消息转为图片发送。
send_to方法
send_to(self, user_id: int = None, group_id: int = None)
顾名思义,您需要传入user_id和group_id中的至少一项。
如果两者都传入,那么会优先向user_id用户发送消息
如果两者都为None,那么会抛出ValueError("No user_id or group_id specified!")
Client类的使用
Client类用来与OneBot实现直接进行交互,调用接口。Msg类也是继承Client类实现的。
构造器
Client(event: pbf.controller.Data.Event = None)
event参数可以传入,如果不传入,就不能使用request_by_event方法
request方法
request(self, action: str, data=None, echo: str = "")
关于每一个参数的详细解释,见OneBot v12文档
action表示动作名称,如send_messagedata是动作参数,即OneBot文档中的paramsecho是回声,可以用于唯一标识一个动作请求
该方法会根据pbf.config.ob_version的值自动适配不同的OneBot标准
pbf.config.ob_version的可选值有"v11"和"v12"
返回请求下来的json解码后的数据
request_by_event方法
使用该方法,可以很方便地根据event中的数据来自动填充动作参数,比如:
# 下面的例子均采用OneBot v12标准
Client(event).request_by_event("delete_message", ["message_id"]) # 撤回当前事件对应的消息
# 这样可以自动从`event`中提取出`message_id`并发送请求
Client(event).request_by_event("send_message", ["detail_type", "group_id"], {"message":"Hello"}) # 发送消息到当前事件对应的群里
# 这样可以在`detail_type`和`group_id`的基础上,再添加`message`参数发送请求
1""" 2# Client包的使用方法 3 4## Msg类的使用 5 6### 构造器定义 7```python 8Msg(*messages, event: pbf.controller.Data.Event = None) 9``` 10您可以传入多个消息,消息可以是str或Statement对象。str中可以包含CQ码,会自动转为Statement对象。<br> 11```python 12msg1 = [ 13 TextStatement("这是一段消息"), 14 FaceStatement(114) 15] 16 17msg2 = [ 18 FaceStatement(514), 19 "str类型会自动被转为TextStatement", 20 TextStatement("这是另一段文本") 21] 22 23msg3 = [ 24 "[CQ:face,id=191]", # 若str中含有CQ码,会自动被转换! 25 TextStatement("这是一段text消息"), 26 "这是另一段text消息" 27] 28``` 29上面三种传参方式都是可以的 30 31`event`参数是当前正在处理的事件,您可以选择不传入。<br> 32如果传入`event`,后续调用`send`方法的时候将会自动选择事件中对应的用户或群聊发送<br> 33如果不传入,您需要调用`send_to`方法指定用户或群聊ID并发送 34 35### `send`方法 36```python 37send(self, retry: int = 0, image: bool = True) 38``` 39- `retry`表示重试次数,`0`表示不重试 40- `image`表示是否尝试自动转为图片发送 41 42当`retry`次数耗尽时,若`image`传参为`True`,就会尝试自动将消息转为图片发送。 43 44### `send_to`方法 45```python 46send_to(self, user_id: int = None, group_id: int = None) 47``` 48顾名思义,您需要传入`user_id`和`group_id`中的至少一项。<br> 49如果两者都传入,那么会优先向`user_id`用户发送消息<br> 50如果两者都为None,那么会抛出`ValueError("No user_id or group_id specified!")` 51 52 53## Client类的使用 54Client类用来与OneBot实现直接进行交互,调用接口。Msg类也是继承Client类实现的。 55 56### 构造器 57```python 58Client(event: pbf.controller.Data.Event = None) 59``` 60`event`参数可以传入,如果不传入,就不能使用`request_by_event`方法 61 62### `request`方法 63```python 64request(self, action: str, data=None, echo: str = "") 65``` 66**关于每一个参数的详细解释,见[OneBot v12文档](https://12.onebot.dev/connect/data-protocol/action-request/)** <br> 67- `action`表示动作名称,如`send_message` 68- `data`是动作参数,即OneBot文档中的`params` 69- `echo`是回声,可以用于唯一标识一个动作请求 70 71该方法会根据`pbf.config.ob_version`的值自动适配不同的OneBot标准<br> 72`pbf.config.ob_version`的可选值有`"v11"`和`"v12"`<br> 73返回请求下来的json解码后的数据 74 75### `request_by_event`方法 76使用该方法,可以很方便地根据`event`中的数据来自动填充动作参数,比如: 77```python 78# 下面的例子均采用OneBot v12标准 79 80Client(event).request_by_event("delete_message", ["message_id"]) # 撤回当前事件对应的消息 81# 这样可以自动从`event`中提取出`message_id`并发送请求 82 83Client(event).request_by_event("send_message", ["detail_type", "group_id"], {"message":"Hello"}) # 发送消息到当前事件对应的群里 84# 这样可以在`detail_type`和`group_id`的基础上,再添加`message`参数发送请求 85``` 86""" 87 88 89from ..setup import logger, pluginsManager 90from .. import config 91from .. import version 92from .Data import Event 93from ..statement.TextStatement import TextStatement 94from ..utils.CQCode import CQCode 95 96import requests 97 98 99class Client: 100 def __init__(self, event: Event = None): 101 """ 102 初始化Client。<br> 103 使用request_by_event方法时,需要传入Event对象。 104 :param event: Event or None 105 :return: None 106 """ 107 if event is None: 108 event = Event() 109 self.event: Event = event 110 111 def request_by_event(self, action: str, data: list, addition=None, echo: str = ""): 112 """ 113 通过Event对象发送请求。 114 :param action: str 请求动作 115 :param data: list 每个元素表示从Event对象中获取的参数 116 :param addition: dict (可选)附加参数 117 :param echo: str (可选)回声 118 :return: dict 请求结果 119 """ 120 if self.event is None: 121 raise ValueError("No event specified!") 122 if addition is None: 123 addition = {} 124 request_data = dict() 125 for i in data: 126 request_data[i] = getattr(self.event, i) 127 for i in addition: 128 request_data[i] = addition[i] 129 return self.request(action, request_data, echo) 130 131 def request(self, action: str, data=None, echo: str = ""): 132 """ 133 发送请求。 134 :param action: str 请求动作 135 :param data: dict (可选)请求参数 136 :param echo: (可选)回声 137 :return: dict 请求结果 138 """ 139 if data is None: 140 data = {} 141 headers = { 142 "Authorization": "Bearer " + config.ob_access_token, 143 "PBF-Client": f"PBFNext v{version}", 144 } 145 req = None 146 if config.ob_version == config.OneBotVersion.v11: 147 req = requests.post(f"{config.ob_uri}/{action}", 148 json=data, 149 headers=headers) 150 elif config.ob_version == config.OneBotVersion.v12: 151 req = requests.post(f"{config.ob_uri}/", 152 json={ 153 "action": action, 154 "params": data, 155 "echo": echo 156 }, 157 headers=headers) 158 data = req.json() 159 return data 160 161 162class Msg(Client): 163 def __init__(self, *messages, event: Event = None): 164 """ 165 初始化Msg。<br> 166 若使用send方法发送消息,需要传入Event对象。 167 :param messages: *list 消息列表。元素可以是str或Statement对象。str中可以包含CQ码,会自动转为Statement对象。 168 :param event: Event (可选)Event对象 169 """ 170 super().__init__(event) 171 self.messages: list = list(messages) 172 if isinstance(self.messages[0], list) or isinstance(self.messages[0], tuple): 173 # 有的时候Msg(msg_list, event=event).send()忘加`*`(手动滑稽 174 self.messages = list(self.messages[0]) 175 176 def getParam(self): 177 """ 178 获取符合OB标准的消息列表。 179 :return: list 消息列表 180 """ 181 ret_arr: list = [] 182 for i in range(len(self.messages)): 183 if isinstance(self.messages[i], str): 184 if "[CQ:" in self.messages[i]: 185 statements: list = CQCode(self.messages[i]).toStatement() 186 # 将statements插入到self.messages中 187 self.messages.pop(i) 188 self.messages[i:i] = statements 189 else: 190 self.messages[i] = TextStatement(self.messages[i]) 191 ret_arr.append(self.messages[i].get()) 192 return ret_arr 193 194 def send(self, retry: int = 0, image: bool = True): 195 """ 196 发送消息。<br> 197 需要在初始化时传入Event对象,会自动判断发送到群或私聊。 198 :param retry: int (可选)重试次数 199 :param image: bool (可选)是否尝试发送图片 200 :return: dict 请求结果 201 """ 202 if self.event.group_id is not None: 203 data = self.send_to(group_id=self.event.group_id) 204 else: 205 data = self.send_to(user_id=self.event.user_id) 206 if data.get("status") == "ok" or data.get("status") == "success": 207 return data 208 elif data.get("status") == "failed" and retry: 209 logger.warning("Failed to send message, retrying...") 210 return self.send(retry-1, image) 211 elif data.get("status") == "failed" and image: 212 logger.warning("Failed to send message, retrying with image...") 213 return self.toImage() 214 logger.warning("Failed to send message") 215 return data 216 217 def toImage(self): 218 """ 219 将消息转为图片发送。 220 :return: dict 请求结果 221 """ 222 if not pluginsManager.hasApi("Pillow"): 223 logger.error("Pillow not found") 224 return {"status": "failed", "message": "Pillow not found"} 225 Pillow = pluginsManager.require("Pillow") 226 params = self.getParam() 227 Pillow.hello() # TODO to image 228 229 def send_to(self, user_id: int = None, group_id: int = None): 230 """ 231 发送消息到指定用户或群。<br> 232 注意:user_id和group_id至少指定一个,都指定时优先向用户ID发送。 233 :param user_id: (可选)用户ID 234 :param group_id: (可选)群ID 235 :return: dict 请求结果 236 """ 237 params = self.getParam() 238 239 if user_id is not None: 240 return self.request("send_msg", {"user_id": user_id, "message": params}) 241 elif group_id is not None: 242 return self.request("send_msg", {"group_id": group_id, "message": params}) 243 else: 244 raise ValueError("No user_id or group_id specified!")
100class Client: 101 def __init__(self, event: Event = None): 102 """ 103 初始化Client。<br> 104 使用request_by_event方法时,需要传入Event对象。 105 :param event: Event or None 106 :return: None 107 """ 108 if event is None: 109 event = Event() 110 self.event: Event = event 111 112 def request_by_event(self, action: str, data: list, addition=None, echo: str = ""): 113 """ 114 通过Event对象发送请求。 115 :param action: str 请求动作 116 :param data: list 每个元素表示从Event对象中获取的参数 117 :param addition: dict (可选)附加参数 118 :param echo: str (可选)回声 119 :return: dict 请求结果 120 """ 121 if self.event is None: 122 raise ValueError("No event specified!") 123 if addition is None: 124 addition = {} 125 request_data = dict() 126 for i in data: 127 request_data[i] = getattr(self.event, i) 128 for i in addition: 129 request_data[i] = addition[i] 130 return self.request(action, request_data, echo) 131 132 def request(self, action: str, data=None, echo: str = ""): 133 """ 134 发送请求。 135 :param action: str 请求动作 136 :param data: dict (可选)请求参数 137 :param echo: (可选)回声 138 :return: dict 请求结果 139 """ 140 if data is None: 141 data = {} 142 headers = { 143 "Authorization": "Bearer " + config.ob_access_token, 144 "PBF-Client": f"PBFNext v{version}", 145 } 146 req = None 147 if config.ob_version == config.OneBotVersion.v11: 148 req = requests.post(f"{config.ob_uri}/{action}", 149 json=data, 150 headers=headers) 151 elif config.ob_version == config.OneBotVersion.v12: 152 req = requests.post(f"{config.ob_uri}/", 153 json={ 154 "action": action, 155 "params": data, 156 "echo": echo 157 }, 158 headers=headers) 159 data = req.json() 160 return data
101 def __init__(self, event: Event = None): 102 """ 103 初始化Client。<br> 104 使用request_by_event方法时,需要传入Event对象。 105 :param event: Event or None 106 :return: None 107 """ 108 if event is None: 109 event = Event() 110 self.event: Event = event
初始化Client。
使用request_by_event方法时,需要传入Event对象。
Parameters
- event: Event or None
Returns
None
112 def request_by_event(self, action: str, data: list, addition=None, echo: str = ""): 113 """ 114 通过Event对象发送请求。 115 :param action: str 请求动作 116 :param data: list 每个元素表示从Event对象中获取的参数 117 :param addition: dict (可选)附加参数 118 :param echo: str (可选)回声 119 :return: dict 请求结果 120 """ 121 if self.event is None: 122 raise ValueError("No event specified!") 123 if addition is None: 124 addition = {} 125 request_data = dict() 126 for i in data: 127 request_data[i] = getattr(self.event, i) 128 for i in addition: 129 request_data[i] = addition[i] 130 return self.request(action, request_data, echo)
通过Event对象发送请求。
Parameters
- action: str 请求动作
- data: list 每个元素表示从Event对象中获取的参数
- addition: dict (可选)附加参数
- echo: str (可选)回声
Returns
dict 请求结果
132 def request(self, action: str, data=None, echo: str = ""): 133 """ 134 发送请求。 135 :param action: str 请求动作 136 :param data: dict (可选)请求参数 137 :param echo: (可选)回声 138 :return: dict 请求结果 139 """ 140 if data is None: 141 data = {} 142 headers = { 143 "Authorization": "Bearer " + config.ob_access_token, 144 "PBF-Client": f"PBFNext v{version}", 145 } 146 req = None 147 if config.ob_version == config.OneBotVersion.v11: 148 req = requests.post(f"{config.ob_uri}/{action}", 149 json=data, 150 headers=headers) 151 elif config.ob_version == config.OneBotVersion.v12: 152 req = requests.post(f"{config.ob_uri}/", 153 json={ 154 "action": action, 155 "params": data, 156 "echo": echo 157 }, 158 headers=headers) 159 data = req.json() 160 return data
发送请求。
Parameters
- action: str 请求动作
- data: dict (可选)请求参数
- echo: (可选)回声
Returns
dict 请求结果
163class Msg(Client): 164 def __init__(self, *messages, event: Event = None): 165 """ 166 初始化Msg。<br> 167 若使用send方法发送消息,需要传入Event对象。 168 :param messages: *list 消息列表。元素可以是str或Statement对象。str中可以包含CQ码,会自动转为Statement对象。 169 :param event: Event (可选)Event对象 170 """ 171 super().__init__(event) 172 self.messages: list = list(messages) 173 if isinstance(self.messages[0], list) or isinstance(self.messages[0], tuple): 174 # 有的时候Msg(msg_list, event=event).send()忘加`*`(手动滑稽 175 self.messages = list(self.messages[0]) 176 177 def getParam(self): 178 """ 179 获取符合OB标准的消息列表。 180 :return: list 消息列表 181 """ 182 ret_arr: list = [] 183 for i in range(len(self.messages)): 184 if isinstance(self.messages[i], str): 185 if "[CQ:" in self.messages[i]: 186 statements: list = CQCode(self.messages[i]).toStatement() 187 # 将statements插入到self.messages中 188 self.messages.pop(i) 189 self.messages[i:i] = statements 190 else: 191 self.messages[i] = TextStatement(self.messages[i]) 192 ret_arr.append(self.messages[i].get()) 193 return ret_arr 194 195 def send(self, retry: int = 0, image: bool = True): 196 """ 197 发送消息。<br> 198 需要在初始化时传入Event对象,会自动判断发送到群或私聊。 199 :param retry: int (可选)重试次数 200 :param image: bool (可选)是否尝试发送图片 201 :return: dict 请求结果 202 """ 203 if self.event.group_id is not None: 204 data = self.send_to(group_id=self.event.group_id) 205 else: 206 data = self.send_to(user_id=self.event.user_id) 207 if data.get("status") == "ok" or data.get("status") == "success": 208 return data 209 elif data.get("status") == "failed" and retry: 210 logger.warning("Failed to send message, retrying...") 211 return self.send(retry-1, image) 212 elif data.get("status") == "failed" and image: 213 logger.warning("Failed to send message, retrying with image...") 214 return self.toImage() 215 logger.warning("Failed to send message") 216 return data 217 218 def toImage(self): 219 """ 220 将消息转为图片发送。 221 :return: dict 请求结果 222 """ 223 if not pluginsManager.hasApi("Pillow"): 224 logger.error("Pillow not found") 225 return {"status": "failed", "message": "Pillow not found"} 226 Pillow = pluginsManager.require("Pillow") 227 params = self.getParam() 228 Pillow.hello() # TODO to image 229 230 def send_to(self, user_id: int = None, group_id: int = None): 231 """ 232 发送消息到指定用户或群。<br> 233 注意:user_id和group_id至少指定一个,都指定时优先向用户ID发送。 234 :param user_id: (可选)用户ID 235 :param group_id: (可选)群ID 236 :return: dict 请求结果 237 """ 238 params = self.getParam() 239 240 if user_id is not None: 241 return self.request("send_msg", {"user_id": user_id, "message": params}) 242 elif group_id is not None: 243 return self.request("send_msg", {"group_id": group_id, "message": params}) 244 else: 245 raise ValueError("No user_id or group_id specified!")
164 def __init__(self, *messages, event: Event = None): 165 """ 166 初始化Msg。<br> 167 若使用send方法发送消息,需要传入Event对象。 168 :param messages: *list 消息列表。元素可以是str或Statement对象。str中可以包含CQ码,会自动转为Statement对象。 169 :param event: Event (可选)Event对象 170 """ 171 super().__init__(event) 172 self.messages: list = list(messages) 173 if isinstance(self.messages[0], list) or isinstance(self.messages[0], tuple): 174 # 有的时候Msg(msg_list, event=event).send()忘加`*`(手动滑稽 175 self.messages = list(self.messages[0])
初始化Msg。
若使用send方法发送消息,需要传入Event对象。
Parameters
- messages: *list 消息列表。元素可以是str或Statement对象。str中可以包含CQ码,会自动转为Statement对象。
- event: Event (可选)Event对象
177 def getParam(self): 178 """ 179 获取符合OB标准的消息列表。 180 :return: list 消息列表 181 """ 182 ret_arr: list = [] 183 for i in range(len(self.messages)): 184 if isinstance(self.messages[i], str): 185 if "[CQ:" in self.messages[i]: 186 statements: list = CQCode(self.messages[i]).toStatement() 187 # 将statements插入到self.messages中 188 self.messages.pop(i) 189 self.messages[i:i] = statements 190 else: 191 self.messages[i] = TextStatement(self.messages[i]) 192 ret_arr.append(self.messages[i].get()) 193 return ret_arr
获取符合OB标准的消息列表。
Returns
list 消息列表
195 def send(self, retry: int = 0, image: bool = True): 196 """ 197 发送消息。<br> 198 需要在初始化时传入Event对象,会自动判断发送到群或私聊。 199 :param retry: int (可选)重试次数 200 :param image: bool (可选)是否尝试发送图片 201 :return: dict 请求结果 202 """ 203 if self.event.group_id is not None: 204 data = self.send_to(group_id=self.event.group_id) 205 else: 206 data = self.send_to(user_id=self.event.user_id) 207 if data.get("status") == "ok" or data.get("status") == "success": 208 return data 209 elif data.get("status") == "failed" and retry: 210 logger.warning("Failed to send message, retrying...") 211 return self.send(retry-1, image) 212 elif data.get("status") == "failed" and image: 213 logger.warning("Failed to send message, retrying with image...") 214 return self.toImage() 215 logger.warning("Failed to send message") 216 return data
发送消息。
需要在初始化时传入Event对象,会自动判断发送到群或私聊。
Parameters
- retry: int (可选)重试次数
- image: bool (可选)是否尝试发送图片
Returns
dict 请求结果
218 def toImage(self): 219 """ 220 将消息转为图片发送。 221 :return: dict 请求结果 222 """ 223 if not pluginsManager.hasApi("Pillow"): 224 logger.error("Pillow not found") 225 return {"status": "failed", "message": "Pillow not found"} 226 Pillow = pluginsManager.require("Pillow") 227 params = self.getParam() 228 Pillow.hello() # TODO to image
将消息转为图片发送。
Returns
dict 请求结果
230 def send_to(self, user_id: int = None, group_id: int = None): 231 """ 232 发送消息到指定用户或群。<br> 233 注意:user_id和group_id至少指定一个,都指定时优先向用户ID发送。 234 :param user_id: (可选)用户ID 235 :param group_id: (可选)群ID 236 :return: dict 请求结果 237 """ 238 params = self.getParam() 239 240 if user_id is not None: 241 return self.request("send_msg", {"user_id": user_id, "message": params}) 242 elif group_id is not None: 243 return self.request("send_msg", {"group_id": group_id, "message": params}) 244 else: 245 raise ValueError("No user_id or group_id specified!")
发送消息到指定用户或群。
注意:user_id和group_id至少指定一个,都指定时优先向用户ID发送。
Parameters
- user_id: (可选)用户ID
- group_id: (可选)群ID
Returns
dict 请求结果