Lib.core.OnebotAPI
OnebotAPI 可以方便的调用Onebot的API
1# __ __ ____ _ ____ _ _____ 2# | \/ |_ _| _ \ __ _(_)_ __ | __ ) ___ | |_|___ \ 3# | |\/| | | | | |_) / _` | | '_ \ | _ \ / _ \| __| __) | 4# | | | | |_| | _ < (_| | | | | | | |_) | (_) | |_ / __/ 5# |_| |_|\__,_|_| \_\__,_|_|_| |_| |____/ \___/ \__|_____| 6 7""" 8OnebotAPI 9可以方便的调用Onebot的API 10""" 11 12import json 13import traceback 14import urllib.parse 15import requests 16 17from . import EventManager, ConfigManager 18from ..common import save_exc_dump 19from ..utils import Logger 20 21logger = Logger.get_logger() 22config = ConfigManager.GlobalConfig() 23 24 25class CallAPIEvent(EventManager.Event): 26 """ 27 调用API事件 28 """ 29 def __init__(self, full_path, node, data): 30 self.full_path: str = full_path 31 self.node: str = node 32 self.data: dict | None = data 33 34 35class OnebotAPI: 36 """ 37 OnebotAPI 38 """ 39 def __init__(self, host: str = None, port: int = None, 40 original: bool = False): 41 """ 42 Args: 43 host: 调用的ip 44 port: 调用的端口 45 original: 是否返回全部json(默认只返回data内) 46 """ 47 if host is None: 48 host = config.api.host 49 if port is None: 50 port = config.api.port 51 52 self.host = host 53 self.port = port 54 self.original = original 55 56 def set_url(self, host: str, port: int): 57 """ 58 设置url 59 Args: 60 host: 请求的host 61 port: 请求的端口 62 """ 63 self.host = host 64 self.port = port 65 66 def get(self, node, data: dict = None, original: bool = None): 67 """ 68 调用api 69 Args: 70 node: 节点 71 data: 数据 72 original: 是否返回全部json(默认只返回data内) 73 """ 74 75 if original is None: 76 original = self.original 77 78 if node == "": 79 raise ValueError('The node cannot be empty.') 80 81 host = self.host 82 port = self.port 83 84 if not host: 85 raise ValueError('The host cannot be empty.') 86 87 if (not isinstance(port, int)) or port > 65535 or port < 0: 88 raise ValueError('The port cannot be empty.') 89 90 if not (host.startswith("http://") or host.startswith("https://")): 91 host = "http://" + host 92 93 # 拼接url 94 url = urllib.parse.urljoin(host + ":" + str(port), node) 95 96 # 广播call_api事件 97 event = CallAPIEvent(url, node, data) 98 event.call_async() 99 if traceback.extract_stack()[-1].filename == traceback.extract_stack()[-2].filename: 100 logger.debug(f"调用 API: {node} data: {data} by: {traceback.extract_stack()[-3].filename}") 101 else: 102 logger.debug(f"调用 API: {node} data: {data} by: {traceback.extract_stack()[-2].filename}") 103 headers = { 104 "Content-Type": "application/json" 105 } 106 if config.api.access_token: 107 headers["Authorization"] = f"Bearer {config.api.access_token}" 108 # 发起get请求 109 creat_dump = True 110 try: 111 response = requests.post( 112 url, 113 headers=headers, 114 data=json.dumps(data if data is not None else {}) 115 ) 116 if response.status_code != 200 or (response.json()['status'] != 'ok' or response.json()['retcode'] != 0): 117 creat_dump = False 118 raise Exception(f"返回异常, 状态码: {response.status_code}, 返回内容: {response.text}") 119 120 # 如果original为真,则返回原值和response 121 if original: 122 return response.json() 123 else: 124 return response.json()['data'] 125 except Exception as e: 126 if ConfigManager.GlobalConfig().debug.save_dump and creat_dump: 127 dump_path = save_exc_dump(f"调用 API: {node} data: {data} 异常") 128 else: 129 dump_path = None 130 logger.error( 131 f"调用 API: {node} data: {data} 异常: {repr(e)}\n" 132 f"{traceback.format_exc()}" 133 f"{f"\n已保存异常到 {dump_path}" if dump_path else ""}" 134 ) 135 raise e 136 137 def send_private_msg(self, user_id: int, message: str | list[dict]): 138 """ 139 发送私聊消息 140 Args: 141 user_id: 用户id 142 message: 消息内容 143 """ 144 data = { 145 "user_id": user_id, 146 "message": message 147 } 148 return self.get("/send_private_msg", data) 149 150 def send_group_msg(self, group_id: int, message: str | list[dict]): 151 """ 152 发送群消息 153 Args: 154 group_id: 群号 155 message: 消息内容 156 """ 157 data = { 158 "group_id": group_id, 159 "message": message 160 } 161 return self.get("/send_group_msg", data) 162 163 def send_msg(self, user_id: int = -1, group_id: int = -1, message: str | list[dict] = ""): 164 """ 165 发送消息 166 Args: 167 user_id: 用户id 168 group_id: 群号 169 message: 消息内容 170 """ 171 if user_id != -1 and group_id != -1: 172 raise ValueError('user_id and group_id cannot be both not -1.') 173 if user_id == -1 and group_id == -1: 174 raise ValueError('user_id and group_id cannot be both -1.') 175 if user_id != -1: 176 return self.send_private_msg(user_id, message) 177 elif group_id != -1: 178 return self.send_group_msg(group_id, message) 179 else: 180 raise ValueError('user_id and group_id cannot be both -1.') 181 182 def delete_msg(self, message_id: int): 183 """ 184 删除消息 185 Args: 186 message_id: 消息id 187 """ 188 data = { 189 "message_id": message_id 190 } 191 return self.get("/delete_msg", data) 192 193 def get_msg(self, message_id: int): 194 """ 195 获取消息 196 Args: 197 message_id: 消息id 198 """ 199 data = { 200 "message_id": message_id 201 } 202 return self.get("/get_msg", data) 203 204 def get_forward_msg(self, id: int): 205 """ 206 获取合并转发消息 207 Args: 208 id: 合并转发id 209 """ 210 data = { 211 "id": id 212 } 213 return self.get("/get_forward_msg", data) 214 215 def send_like(self, user_id: int, times: int = 1): 216 """ 217 发送点赞 218 Args: 219 user_id: 用户id 220 times: 点赞次数 221 """ 222 data = { 223 "user_id": user_id, 224 "times": times 225 } 226 return self.get("/send_like", data) 227 228 def set_group_kick(self, group_id: int, user_id: int, reject_add_request: bool = False): 229 """ 230 群组踢人 231 Args: 232 group_id: 群号 233 user_id: 用户id 234 reject_add_request: 拒绝加群请求 235 """ 236 data = { 237 "group_id": group_id, 238 "user_id": user_id, 239 "reject_add_request": reject_add_request 240 } 241 return self.get("/set_group_kick", data) 242 243 def set_group_ban(self, group_id: int, user_id: int, duration: int = 30 * 60): 244 """ 245 群组单人禁言 246 Args: 247 group_id: 群号 248 user_id: 用户id 249 duration: 禁言时长,单位秒,0 表示取消禁言 250 """ 251 data = { 252 "group_id": group_id, 253 "user_id": user_id, 254 "duration": duration 255 } 256 return self.get("/set_group_ban", data) 257 258 def set_group_anonymous_ban(self, group_id: int, anonymous: dict, duration: int = 30 * 60): 259 """ 260 群组匿名用户禁言 261 Args: 262 group_id: 群号 263 anonymous: 匿名用户对象 264 duration: 禁言时长,单位秒,无法取消禁言 265 """ 266 data = { 267 "group_id": group_id, 268 "anonymous": anonymous, 269 "duration": duration 270 } 271 return self.get("/set_group_anonymous_ban", data) 272 273 def set_group_whole_ban(self, group_id: int, enable: bool = True): 274 """ 275 群组全员禁言 276 Args: 277 group_id: 群号 278 enable: 是否禁言 279 """ 280 data = { 281 "group_id": group_id, 282 "enable": enable 283 } 284 return self.get("/set_group_whole_ban", data) 285 286 def set_group_admin(self, group_id: int, user_id: int, enable: bool = True): 287 """ 288 群组设置管理员 289 Args: 290 group_id: 群号 291 user_id: 用户id 292 enable: 是否设置管理员 293 """ 294 data = { 295 "group_id": group_id, 296 "user_id": user_id, 297 "enable": enable 298 } 299 return self.get("/set_group_admin", data) 300 301 def set_group_card(self, group_id: int, user_id: int, card: str = ""): 302 """ 303 设置群名片(群备注) 304 Args: 305 group_id: 群号 306 user_id: 用户id 307 card: 群名片内容 308 """ 309 data = { 310 "group_id": group_id, 311 "user_id": user_id, 312 "card": card 313 } 314 return self.get("/set_group_card", data) 315 316 def set_group_name(self, group_id: int, group_name: str): 317 """ 318 设置群名 319 Args: 320 group_id: 群号 321 group_name: 群名 322 """ 323 data = { 324 "group_id": group_id, 325 "group_name": group_name 326 } 327 return self.get("/set_group_name", data) 328 329 def set_group_leave(self, group_id: int, is_dismiss: bool = False): 330 """ 331 Args: 332 group_id: 群号 333 is_dismiss: 是否解散,如果登录号是群主,则仅在此项为True时能够解散 334 """ 335 data = { 336 "group_id": group_id, 337 "is_dismiss": is_dismiss 338 } 339 return self.get("/set_group_leave", data) 340 341 def set_group_special_title(self, group_id: int, user_id: int, special_title: str = "", duration: int = -1): 342 """ 343 设置群组专属头衔 344 Args: 345 group_id: 群号 346 user_id: 要设置的QQ号 347 special_title: 专属头衔,不填或空字符串表示删除专属头衔 348 duration: 专属头衔有效期,-1表示永久,其他值表示在此时间之前专属头衔会消失 349 """ 350 data = { 351 "group_id": group_id, 352 "user_id": user_id, 353 "special_title": special_title, 354 } 355 if duration != -1: 356 data["duration"] = duration 357 358 return self.get("/set_group_special_title", data) 359 360 def set_friend_add_request(self, flag: str, approve: bool = True, remark: str = ""): 361 """ 362 设置好友添加请求 363 Args: 364 flag: 请求flag 365 approve: 是否同意请求 366 remark: 添加后的好友备注 367 """ 368 data = { 369 "flag": flag, 370 "approve": approve, 371 "remark": remark 372 } 373 return self.get("/set_friend_add_request", data) 374 375 def set_group_add_request(self, flag: str, sub_type: str = "add", approve: bool = True, reason: str = ""): 376 """ 377 设置群添加请求 378 Args: 379 flag: 请求flag 380 sub_type: 添加请求类型,请参考api文档 381 approve: 是否同意请求 382 reason: 拒绝理由 383 """ 384 data = { 385 "flag": flag, 386 "sub_type": sub_type, 387 "approve": approve, 388 "reason": reason 389 } 390 return self.get("/set_group_add_request", data) 391 392 def get_login_info(self): 393 """ 394 获取登录号信息 395 """ 396 return self.get("/get_login_info") 397 398 def get_stranger_info(self, user_id: int, no_cache: bool = False): 399 """ 400 获取陌生人信息 401 Args: 402 user_id: 对方QQ号 403 no_cache: 是否不使用缓存(使用缓存可能更新不及时,但响应更快) 404 """ 405 data = { 406 "user_id": user_id, 407 "no_cache": no_cache 408 } 409 return self.get("/get_stranger_info", data) 410 411 def get_friend_list(self): 412 """ 413 获取好友列表 414 """ 415 return self.get("/get_friend_list") 416 417 def get_group_info(self, group_id: int, no_cache: bool = False): 418 """ 419 获取群信息 420 Args: 421 group_id: 群号 422 no_cache: 是否不使用缓存(使用缓存可能更新不及时,但响应更快) 423 """ 424 data = { 425 "group_id": group_id, 426 "no_cache": no_cache 427 } 428 return self.get("/get_group_info", data) 429 430 def get_group_list(self): 431 """ 432 获取群列表 433 """ 434 return self.get("/get_group_list") 435 436 def get_group_member_info(self, group_id: int, user_id: int, no_cache: bool = False): 437 """ 438 获取群成员信息 439 Args: 440 group_id: 群号 441 user_id: QQ号 442 no_cache: 是否不使用缓存(使用缓存可能更新不及时,但响应更快) 443 """ 444 data = { 445 "group_id": group_id, 446 "user_id": user_id, 447 "no_cache": no_cache 448 } 449 return self.get("/get_group_member_info", data) 450 451 def get_group_member_list(self, group_id: int): 452 """ 453 获取群成员列表 454 Args: 455 group_id: 群号 456 """ 457 data = { 458 "group_id": group_id 459 } 460 return self.get("/get_group_member_list", data) 461 462 def get_group_honor_info(self, group_id: int, type_: str = "all"): 463 """ 464 获取群荣誉信息 465 Args: 466 group_id: 群号 467 type_: 要获取的群荣誉类型,可传入 talkative performer legend strong_newbie emotion 以分别获取单个类型的群荣誉数据,或传入 all 获取所有数据 468 """ 469 data = { 470 "group_id": group_id, 471 "type": type_ 472 } 473 return self.get("/get_group_honor_info", data) 474 475 def get_cookies(self): 476 """ 477 获取Cookies 478 """ 479 return self.get("/get_cookies") 480 481 def get_csrf_token(self): 482 """ 483 获取CSRF Token 484 """ 485 return self.get("/get_csrf_token") 486 487 def get_credentials(self): 488 """ 489 获取Credentials 490 """ 491 return self.get("/get_credentials") 492 493 def get_record(self, file: str, out_format: str = "mp3", out_file: str = ""): 494 """ 495 获取语音 496 Args: 497 file: 文件ID 498 out_format: 输出格式,mp3或amr,默认mp3 499 out_file: 输出文件名,默认使用文件ID 500 """ 501 data = { 502 "file": file, 503 "out_format": out_format, 504 "out_file": out_file 505 } 506 return self.get("/get_record", data) 507 508 def get_image(self, file: str): 509 """ 510 获取图片 511 Args: 512 file: 文件ID 513 """ 514 data = { 515 "file": file 516 } 517 return self.get("/get_image", data) 518 519 def can_send_image(self): 520 """ 521 检查是否可以发送图片 522 """ 523 return self.get("/can_send_image") 524 525 def can_send_record(self): 526 """ 527 检查是否可以发送语音 528 """ 529 return self.get("/can_send_record") 530 531 def get_status(self): 532 """ 533 获取运行状态 534 """ 535 return self.get("/get_status") 536 537 def get_version_info(self): 538 """ 539 获取版本信息 540 """ 541 return self.get("/get_version_info") 542 543 def set_restart(self, delay: int = 0): 544 """ 545 重启OneBot 546 Args: 547 delay: 延迟时间,单位秒,默认0 548 """ 549 data = { 550 "delay": delay 551 } 552 return self.get("/set_restart", data) 553 554 def clean_cache(self): 555 """ 556 清理缓存 557 """ 558 return self.get("/clean_cache") 559 560 561api = OnebotAPI()
logger =
<RootLogger root (INFO)>
config =
<Lib.core.ConfigManager.GlobalConfig object>
26class CallAPIEvent(EventManager.Event): 27 """ 28 调用API事件 29 """ 30 def __init__(self, full_path, node, data): 31 self.full_path: str = full_path 32 self.node: str = node 33 self.data: dict | None = data
调用API事件
Inherited Members
class
OnebotAPI:
36class OnebotAPI: 37 """ 38 OnebotAPI 39 """ 40 def __init__(self, host: str = None, port: int = None, 41 original: bool = False): 42 """ 43 Args: 44 host: 调用的ip 45 port: 调用的端口 46 original: 是否返回全部json(默认只返回data内) 47 """ 48 if host is None: 49 host = config.api.host 50 if port is None: 51 port = config.api.port 52 53 self.host = host 54 self.port = port 55 self.original = original 56 57 def set_url(self, host: str, port: int): 58 """ 59 设置url 60 Args: 61 host: 请求的host 62 port: 请求的端口 63 """ 64 self.host = host 65 self.port = port 66 67 def get(self, node, data: dict = None, original: bool = None): 68 """ 69 调用api 70 Args: 71 node: 节点 72 data: 数据 73 original: 是否返回全部json(默认只返回data内) 74 """ 75 76 if original is None: 77 original = self.original 78 79 if node == "": 80 raise ValueError('The node cannot be empty.') 81 82 host = self.host 83 port = self.port 84 85 if not host: 86 raise ValueError('The host cannot be empty.') 87 88 if (not isinstance(port, int)) or port > 65535 or port < 0: 89 raise ValueError('The port cannot be empty.') 90 91 if not (host.startswith("http://") or host.startswith("https://")): 92 host = "http://" + host 93 94 # 拼接url 95 url = urllib.parse.urljoin(host + ":" + str(port), node) 96 97 # 广播call_api事件 98 event = CallAPIEvent(url, node, data) 99 event.call_async() 100 if traceback.extract_stack()[-1].filename == traceback.extract_stack()[-2].filename: 101 logger.debug(f"调用 API: {node} data: {data} by: {traceback.extract_stack()[-3].filename}") 102 else: 103 logger.debug(f"调用 API: {node} data: {data} by: {traceback.extract_stack()[-2].filename}") 104 headers = { 105 "Content-Type": "application/json" 106 } 107 if config.api.access_token: 108 headers["Authorization"] = f"Bearer {config.api.access_token}" 109 # 发起get请求 110 creat_dump = True 111 try: 112 response = requests.post( 113 url, 114 headers=headers, 115 data=json.dumps(data if data is not None else {}) 116 ) 117 if response.status_code != 200 or (response.json()['status'] != 'ok' or response.json()['retcode'] != 0): 118 creat_dump = False 119 raise Exception(f"返回异常, 状态码: {response.status_code}, 返回内容: {response.text}") 120 121 # 如果original为真,则返回原值和response 122 if original: 123 return response.json() 124 else: 125 return response.json()['data'] 126 except Exception as e: 127 if ConfigManager.GlobalConfig().debug.save_dump and creat_dump: 128 dump_path = save_exc_dump(f"调用 API: {node} data: {data} 异常") 129 else: 130 dump_path = None 131 logger.error( 132 f"调用 API: {node} data: {data} 异常: {repr(e)}\n" 133 f"{traceback.format_exc()}" 134 f"{f"\n已保存异常到 {dump_path}" if dump_path else ""}" 135 ) 136 raise e 137 138 def send_private_msg(self, user_id: int, message: str | list[dict]): 139 """ 140 发送私聊消息 141 Args: 142 user_id: 用户id 143 message: 消息内容 144 """ 145 data = { 146 "user_id": user_id, 147 "message": message 148 } 149 return self.get("/send_private_msg", data) 150 151 def send_group_msg(self, group_id: int, message: str | list[dict]): 152 """ 153 发送群消息 154 Args: 155 group_id: 群号 156 message: 消息内容 157 """ 158 data = { 159 "group_id": group_id, 160 "message": message 161 } 162 return self.get("/send_group_msg", data) 163 164 def send_msg(self, user_id: int = -1, group_id: int = -1, message: str | list[dict] = ""): 165 """ 166 发送消息 167 Args: 168 user_id: 用户id 169 group_id: 群号 170 message: 消息内容 171 """ 172 if user_id != -1 and group_id != -1: 173 raise ValueError('user_id and group_id cannot be both not -1.') 174 if user_id == -1 and group_id == -1: 175 raise ValueError('user_id and group_id cannot be both -1.') 176 if user_id != -1: 177 return self.send_private_msg(user_id, message) 178 elif group_id != -1: 179 return self.send_group_msg(group_id, message) 180 else: 181 raise ValueError('user_id and group_id cannot be both -1.') 182 183 def delete_msg(self, message_id: int): 184 """ 185 删除消息 186 Args: 187 message_id: 消息id 188 """ 189 data = { 190 "message_id": message_id 191 } 192 return self.get("/delete_msg", data) 193 194 def get_msg(self, message_id: int): 195 """ 196 获取消息 197 Args: 198 message_id: 消息id 199 """ 200 data = { 201 "message_id": message_id 202 } 203 return self.get("/get_msg", data) 204 205 def get_forward_msg(self, id: int): 206 """ 207 获取合并转发消息 208 Args: 209 id: 合并转发id 210 """ 211 data = { 212 "id": id 213 } 214 return self.get("/get_forward_msg", data) 215 216 def send_like(self, user_id: int, times: int = 1): 217 """ 218 发送点赞 219 Args: 220 user_id: 用户id 221 times: 点赞次数 222 """ 223 data = { 224 "user_id": user_id, 225 "times": times 226 } 227 return self.get("/send_like", data) 228 229 def set_group_kick(self, group_id: int, user_id: int, reject_add_request: bool = False): 230 """ 231 群组踢人 232 Args: 233 group_id: 群号 234 user_id: 用户id 235 reject_add_request: 拒绝加群请求 236 """ 237 data = { 238 "group_id": group_id, 239 "user_id": user_id, 240 "reject_add_request": reject_add_request 241 } 242 return self.get("/set_group_kick", data) 243 244 def set_group_ban(self, group_id: int, user_id: int, duration: int = 30 * 60): 245 """ 246 群组单人禁言 247 Args: 248 group_id: 群号 249 user_id: 用户id 250 duration: 禁言时长,单位秒,0 表示取消禁言 251 """ 252 data = { 253 "group_id": group_id, 254 "user_id": user_id, 255 "duration": duration 256 } 257 return self.get("/set_group_ban", data) 258 259 def set_group_anonymous_ban(self, group_id: int, anonymous: dict, duration: int = 30 * 60): 260 """ 261 群组匿名用户禁言 262 Args: 263 group_id: 群号 264 anonymous: 匿名用户对象 265 duration: 禁言时长,单位秒,无法取消禁言 266 """ 267 data = { 268 "group_id": group_id, 269 "anonymous": anonymous, 270 "duration": duration 271 } 272 return self.get("/set_group_anonymous_ban", data) 273 274 def set_group_whole_ban(self, group_id: int, enable: bool = True): 275 """ 276 群组全员禁言 277 Args: 278 group_id: 群号 279 enable: 是否禁言 280 """ 281 data = { 282 "group_id": group_id, 283 "enable": enable 284 } 285 return self.get("/set_group_whole_ban", data) 286 287 def set_group_admin(self, group_id: int, user_id: int, enable: bool = True): 288 """ 289 群组设置管理员 290 Args: 291 group_id: 群号 292 user_id: 用户id 293 enable: 是否设置管理员 294 """ 295 data = { 296 "group_id": group_id, 297 "user_id": user_id, 298 "enable": enable 299 } 300 return self.get("/set_group_admin", data) 301 302 def set_group_card(self, group_id: int, user_id: int, card: str = ""): 303 """ 304 设置群名片(群备注) 305 Args: 306 group_id: 群号 307 user_id: 用户id 308 card: 群名片内容 309 """ 310 data = { 311 "group_id": group_id, 312 "user_id": user_id, 313 "card": card 314 } 315 return self.get("/set_group_card", data) 316 317 def set_group_name(self, group_id: int, group_name: str): 318 """ 319 设置群名 320 Args: 321 group_id: 群号 322 group_name: 群名 323 """ 324 data = { 325 "group_id": group_id, 326 "group_name": group_name 327 } 328 return self.get("/set_group_name", data) 329 330 def set_group_leave(self, group_id: int, is_dismiss: bool = False): 331 """ 332 Args: 333 group_id: 群号 334 is_dismiss: 是否解散,如果登录号是群主,则仅在此项为True时能够解散 335 """ 336 data = { 337 "group_id": group_id, 338 "is_dismiss": is_dismiss 339 } 340 return self.get("/set_group_leave", data) 341 342 def set_group_special_title(self, group_id: int, user_id: int, special_title: str = "", duration: int = -1): 343 """ 344 设置群组专属头衔 345 Args: 346 group_id: 群号 347 user_id: 要设置的QQ号 348 special_title: 专属头衔,不填或空字符串表示删除专属头衔 349 duration: 专属头衔有效期,-1表示永久,其他值表示在此时间之前专属头衔会消失 350 """ 351 data = { 352 "group_id": group_id, 353 "user_id": user_id, 354 "special_title": special_title, 355 } 356 if duration != -1: 357 data["duration"] = duration 358 359 return self.get("/set_group_special_title", data) 360 361 def set_friend_add_request(self, flag: str, approve: bool = True, remark: str = ""): 362 """ 363 设置好友添加请求 364 Args: 365 flag: 请求flag 366 approve: 是否同意请求 367 remark: 添加后的好友备注 368 """ 369 data = { 370 "flag": flag, 371 "approve": approve, 372 "remark": remark 373 } 374 return self.get("/set_friend_add_request", data) 375 376 def set_group_add_request(self, flag: str, sub_type: str = "add", approve: bool = True, reason: str = ""): 377 """ 378 设置群添加请求 379 Args: 380 flag: 请求flag 381 sub_type: 添加请求类型,请参考api文档 382 approve: 是否同意请求 383 reason: 拒绝理由 384 """ 385 data = { 386 "flag": flag, 387 "sub_type": sub_type, 388 "approve": approve, 389 "reason": reason 390 } 391 return self.get("/set_group_add_request", data) 392 393 def get_login_info(self): 394 """ 395 获取登录号信息 396 """ 397 return self.get("/get_login_info") 398 399 def get_stranger_info(self, user_id: int, no_cache: bool = False): 400 """ 401 获取陌生人信息 402 Args: 403 user_id: 对方QQ号 404 no_cache: 是否不使用缓存(使用缓存可能更新不及时,但响应更快) 405 """ 406 data = { 407 "user_id": user_id, 408 "no_cache": no_cache 409 } 410 return self.get("/get_stranger_info", data) 411 412 def get_friend_list(self): 413 """ 414 获取好友列表 415 """ 416 return self.get("/get_friend_list") 417 418 def get_group_info(self, group_id: int, no_cache: bool = False): 419 """ 420 获取群信息 421 Args: 422 group_id: 群号 423 no_cache: 是否不使用缓存(使用缓存可能更新不及时,但响应更快) 424 """ 425 data = { 426 "group_id": group_id, 427 "no_cache": no_cache 428 } 429 return self.get("/get_group_info", data) 430 431 def get_group_list(self): 432 """ 433 获取群列表 434 """ 435 return self.get("/get_group_list") 436 437 def get_group_member_info(self, group_id: int, user_id: int, no_cache: bool = False): 438 """ 439 获取群成员信息 440 Args: 441 group_id: 群号 442 user_id: QQ号 443 no_cache: 是否不使用缓存(使用缓存可能更新不及时,但响应更快) 444 """ 445 data = { 446 "group_id": group_id, 447 "user_id": user_id, 448 "no_cache": no_cache 449 } 450 return self.get("/get_group_member_info", data) 451 452 def get_group_member_list(self, group_id: int): 453 """ 454 获取群成员列表 455 Args: 456 group_id: 群号 457 """ 458 data = { 459 "group_id": group_id 460 } 461 return self.get("/get_group_member_list", data) 462 463 def get_group_honor_info(self, group_id: int, type_: str = "all"): 464 """ 465 获取群荣誉信息 466 Args: 467 group_id: 群号 468 type_: 要获取的群荣誉类型,可传入 talkative performer legend strong_newbie emotion 以分别获取单个类型的群荣誉数据,或传入 all 获取所有数据 469 """ 470 data = { 471 "group_id": group_id, 472 "type": type_ 473 } 474 return self.get("/get_group_honor_info", data) 475 476 def get_cookies(self): 477 """ 478 获取Cookies 479 """ 480 return self.get("/get_cookies") 481 482 def get_csrf_token(self): 483 """ 484 获取CSRF Token 485 """ 486 return self.get("/get_csrf_token") 487 488 def get_credentials(self): 489 """ 490 获取Credentials 491 """ 492 return self.get("/get_credentials") 493 494 def get_record(self, file: str, out_format: str = "mp3", out_file: str = ""): 495 """ 496 获取语音 497 Args: 498 file: 文件ID 499 out_format: 输出格式,mp3或amr,默认mp3 500 out_file: 输出文件名,默认使用文件ID 501 """ 502 data = { 503 "file": file, 504 "out_format": out_format, 505 "out_file": out_file 506 } 507 return self.get("/get_record", data) 508 509 def get_image(self, file: str): 510 """ 511 获取图片 512 Args: 513 file: 文件ID 514 """ 515 data = { 516 "file": file 517 } 518 return self.get("/get_image", data) 519 520 def can_send_image(self): 521 """ 522 检查是否可以发送图片 523 """ 524 return self.get("/can_send_image") 525 526 def can_send_record(self): 527 """ 528 检查是否可以发送语音 529 """ 530 return self.get("/can_send_record") 531 532 def get_status(self): 533 """ 534 获取运行状态 535 """ 536 return self.get("/get_status") 537 538 def get_version_info(self): 539 """ 540 获取版本信息 541 """ 542 return self.get("/get_version_info") 543 544 def set_restart(self, delay: int = 0): 545 """ 546 重启OneBot 547 Args: 548 delay: 延迟时间,单位秒,默认0 549 """ 550 data = { 551 "delay": delay 552 } 553 return self.get("/set_restart", data) 554 555 def clean_cache(self): 556 """ 557 清理缓存 558 """ 559 return self.get("/clean_cache")
OnebotAPI
OnebotAPI(host: str = None, port: int = None, original: bool = False)
40 def __init__(self, host: str = None, port: int = None, 41 original: bool = False): 42 """ 43 Args: 44 host: 调用的ip 45 port: 调用的端口 46 original: 是否返回全部json(默认只返回data内) 47 """ 48 if host is None: 49 host = config.api.host 50 if port is None: 51 port = config.api.port 52 53 self.host = host 54 self.port = port 55 self.original = original
Arguments:
- host: 调用的ip
- port: 调用的端口
- original: 是否返回全部json(默认只返回data内)
def
set_url(self, host: str, port: int):
57 def set_url(self, host: str, port: int): 58 """ 59 设置url 60 Args: 61 host: 请求的host 62 port: 请求的端口 63 """ 64 self.host = host 65 self.port = port
设置url
Arguments:
- host: 请求的host
- port: 请求的端口
def
get(self, node, data: dict = None, original: bool = None):
67 def get(self, node, data: dict = None, original: bool = None): 68 """ 69 调用api 70 Args: 71 node: 节点 72 data: 数据 73 original: 是否返回全部json(默认只返回data内) 74 """ 75 76 if original is None: 77 original = self.original 78 79 if node == "": 80 raise ValueError('The node cannot be empty.') 81 82 host = self.host 83 port = self.port 84 85 if not host: 86 raise ValueError('The host cannot be empty.') 87 88 if (not isinstance(port, int)) or port > 65535 or port < 0: 89 raise ValueError('The port cannot be empty.') 90 91 if not (host.startswith("http://") or host.startswith("https://")): 92 host = "http://" + host 93 94 # 拼接url 95 url = urllib.parse.urljoin(host + ":" + str(port), node) 96 97 # 广播call_api事件 98 event = CallAPIEvent(url, node, data) 99 event.call_async() 100 if traceback.extract_stack()[-1].filename == traceback.extract_stack()[-2].filename: 101 logger.debug(f"调用 API: {node} data: {data} by: {traceback.extract_stack()[-3].filename}") 102 else: 103 logger.debug(f"调用 API: {node} data: {data} by: {traceback.extract_stack()[-2].filename}") 104 headers = { 105 "Content-Type": "application/json" 106 } 107 if config.api.access_token: 108 headers["Authorization"] = f"Bearer {config.api.access_token}" 109 # 发起get请求 110 creat_dump = True 111 try: 112 response = requests.post( 113 url, 114 headers=headers, 115 data=json.dumps(data if data is not None else {}) 116 ) 117 if response.status_code != 200 or (response.json()['status'] != 'ok' or response.json()['retcode'] != 0): 118 creat_dump = False 119 raise Exception(f"返回异常, 状态码: {response.status_code}, 返回内容: {response.text}") 120 121 # 如果original为真,则返回原值和response 122 if original: 123 return response.json() 124 else: 125 return response.json()['data'] 126 except Exception as e: 127 if ConfigManager.GlobalConfig().debug.save_dump and creat_dump: 128 dump_path = save_exc_dump(f"调用 API: {node} data: {data} 异常") 129 else: 130 dump_path = None 131 logger.error( 132 f"调用 API: {node} data: {data} 异常: {repr(e)}\n" 133 f"{traceback.format_exc()}" 134 f"{f"\n已保存异常到 {dump_path}" if dump_path else ""}" 135 ) 136 raise e
调用api
Arguments:
- node: 节点
- data: 数据
- original: 是否返回全部json(默认只返回data内)
def
send_private_msg(self, user_id: int, message: str | list[dict]):
138 def send_private_msg(self, user_id: int, message: str | list[dict]): 139 """ 140 发送私聊消息 141 Args: 142 user_id: 用户id 143 message: 消息内容 144 """ 145 data = { 146 "user_id": user_id, 147 "message": message 148 } 149 return self.get("/send_private_msg", data)
发送私聊消息
Arguments:
- user_id: 用户id
- message: 消息内容
def
send_group_msg(self, group_id: int, message: str | list[dict]):
151 def send_group_msg(self, group_id: int, message: str | list[dict]): 152 """ 153 发送群消息 154 Args: 155 group_id: 群号 156 message: 消息内容 157 """ 158 data = { 159 "group_id": group_id, 160 "message": message 161 } 162 return self.get("/send_group_msg", data)
发送群消息
Arguments:
- group_id: 群号
- message: 消息内容
def
send_msg( self, user_id: int = -1, group_id: int = -1, message: str | list[dict] = ''):
164 def send_msg(self, user_id: int = -1, group_id: int = -1, message: str | list[dict] = ""): 165 """ 166 发送消息 167 Args: 168 user_id: 用户id 169 group_id: 群号 170 message: 消息内容 171 """ 172 if user_id != -1 and group_id != -1: 173 raise ValueError('user_id and group_id cannot be both not -1.') 174 if user_id == -1 and group_id == -1: 175 raise ValueError('user_id and group_id cannot be both -1.') 176 if user_id != -1: 177 return self.send_private_msg(user_id, message) 178 elif group_id != -1: 179 return self.send_group_msg(group_id, message) 180 else: 181 raise ValueError('user_id and group_id cannot be both -1.')
发送消息
Arguments:
- user_id: 用户id
- group_id: 群号
- message: 消息内容
def
delete_msg(self, message_id: int):
183 def delete_msg(self, message_id: int): 184 """ 185 删除消息 186 Args: 187 message_id: 消息id 188 """ 189 data = { 190 "message_id": message_id 191 } 192 return self.get("/delete_msg", data)
删除消息
Arguments:
- message_id: 消息id
def
get_msg(self, message_id: int):
194 def get_msg(self, message_id: int): 195 """ 196 获取消息 197 Args: 198 message_id: 消息id 199 """ 200 data = { 201 "message_id": message_id 202 } 203 return self.get("/get_msg", data)
获取消息
Arguments:
- message_id: 消息id
def
get_forward_msg(self, id: int):
205 def get_forward_msg(self, id: int): 206 """ 207 获取合并转发消息 208 Args: 209 id: 合并转发id 210 """ 211 data = { 212 "id": id 213 } 214 return self.get("/get_forward_msg", data)
获取合并转发消息
Arguments:
- id: 合并转发id
def
send_like(self, user_id: int, times: int = 1):
216 def send_like(self, user_id: int, times: int = 1): 217 """ 218 发送点赞 219 Args: 220 user_id: 用户id 221 times: 点赞次数 222 """ 223 data = { 224 "user_id": user_id, 225 "times": times 226 } 227 return self.get("/send_like", data)
发送点赞
Arguments:
- user_id: 用户id
- times: 点赞次数
def
set_group_kick(self, group_id: int, user_id: int, reject_add_request: bool = False):
229 def set_group_kick(self, group_id: int, user_id: int, reject_add_request: bool = False): 230 """ 231 群组踢人 232 Args: 233 group_id: 群号 234 user_id: 用户id 235 reject_add_request: 拒绝加群请求 236 """ 237 data = { 238 "group_id": group_id, 239 "user_id": user_id, 240 "reject_add_request": reject_add_request 241 } 242 return self.get("/set_group_kick", data)
群组踢人
Arguments:
- group_id: 群号
- user_id: 用户id
- reject_add_request: 拒绝加群请求
def
set_group_ban(self, group_id: int, user_id: int, duration: int = 1800):
244 def set_group_ban(self, group_id: int, user_id: int, duration: int = 30 * 60): 245 """ 246 群组单人禁言 247 Args: 248 group_id: 群号 249 user_id: 用户id 250 duration: 禁言时长,单位秒,0 表示取消禁言 251 """ 252 data = { 253 "group_id": group_id, 254 "user_id": user_id, 255 "duration": duration 256 } 257 return self.get("/set_group_ban", data)
群组单人禁言
Arguments:
- group_id: 群号
- user_id: 用户id
- duration: 禁言时长,单位秒,0 表示取消禁言
def
set_group_anonymous_ban(self, group_id: int, anonymous: dict, duration: int = 1800):
259 def set_group_anonymous_ban(self, group_id: int, anonymous: dict, duration: int = 30 * 60): 260 """ 261 群组匿名用户禁言 262 Args: 263 group_id: 群号 264 anonymous: 匿名用户对象 265 duration: 禁言时长,单位秒,无法取消禁言 266 """ 267 data = { 268 "group_id": group_id, 269 "anonymous": anonymous, 270 "duration": duration 271 } 272 return self.get("/set_group_anonymous_ban", data)
群组匿名用户禁言
Arguments:
- group_id: 群号
- anonymous: 匿名用户对象
- duration: 禁言时长,单位秒,无法取消禁言
def
set_group_whole_ban(self, group_id: int, enable: bool = True):
274 def set_group_whole_ban(self, group_id: int, enable: bool = True): 275 """ 276 群组全员禁言 277 Args: 278 group_id: 群号 279 enable: 是否禁言 280 """ 281 data = { 282 "group_id": group_id, 283 "enable": enable 284 } 285 return self.get("/set_group_whole_ban", data)
群组全员禁言
Arguments:
- group_id: 群号
- enable: 是否禁言
def
set_group_admin(self, group_id: int, user_id: int, enable: bool = True):
287 def set_group_admin(self, group_id: int, user_id: int, enable: bool = True): 288 """ 289 群组设置管理员 290 Args: 291 group_id: 群号 292 user_id: 用户id 293 enable: 是否设置管理员 294 """ 295 data = { 296 "group_id": group_id, 297 "user_id": user_id, 298 "enable": enable 299 } 300 return self.get("/set_group_admin", data)
群组设置管理员
Arguments:
- group_id: 群号
- user_id: 用户id
- enable: 是否设置管理员
def
set_group_card(self, group_id: int, user_id: int, card: str = ''):
302 def set_group_card(self, group_id: int, user_id: int, card: str = ""): 303 """ 304 设置群名片(群备注) 305 Args: 306 group_id: 群号 307 user_id: 用户id 308 card: 群名片内容 309 """ 310 data = { 311 "group_id": group_id, 312 "user_id": user_id, 313 "card": card 314 } 315 return self.get("/set_group_card", data)
设置群名片(群备注)
Arguments:
- group_id: 群号
- user_id: 用户id
- card: 群名片内容
def
set_group_name(self, group_id: int, group_name: str):
317 def set_group_name(self, group_id: int, group_name: str): 318 """ 319 设置群名 320 Args: 321 group_id: 群号 322 group_name: 群名 323 """ 324 data = { 325 "group_id": group_id, 326 "group_name": group_name 327 } 328 return self.get("/set_group_name", data)
设置群名
Arguments:
- group_id: 群号
- group_name: 群名
def
set_group_leave(self, group_id: int, is_dismiss: bool = False):
330 def set_group_leave(self, group_id: int, is_dismiss: bool = False): 331 """ 332 Args: 333 group_id: 群号 334 is_dismiss: 是否解散,如果登录号是群主,则仅在此项为True时能够解散 335 """ 336 data = { 337 "group_id": group_id, 338 "is_dismiss": is_dismiss 339 } 340 return self.get("/set_group_leave", data)
Arguments:
- group_id: 群号
- is_dismiss: 是否解散,如果登录号是群主,则仅在此项为True时能够解散
def
set_group_special_title( self, group_id: int, user_id: int, special_title: str = '', duration: int = -1):
342 def set_group_special_title(self, group_id: int, user_id: int, special_title: str = "", duration: int = -1): 343 """ 344 设置群组专属头衔 345 Args: 346 group_id: 群号 347 user_id: 要设置的QQ号 348 special_title: 专属头衔,不填或空字符串表示删除专属头衔 349 duration: 专属头衔有效期,-1表示永久,其他值表示在此时间之前专属头衔会消失 350 """ 351 data = { 352 "group_id": group_id, 353 "user_id": user_id, 354 "special_title": special_title, 355 } 356 if duration != -1: 357 data["duration"] = duration 358 359 return self.get("/set_group_special_title", data)
设置群组专属头衔
Arguments:
- group_id: 群号
- user_id: 要设置的QQ号
- special_title: 专属头衔,不填或空字符串表示删除专属头衔
- duration: 专属头衔有效期,-1表示永久,其他值表示在此时间之前专属头衔会消失
def
set_friend_add_request(self, flag: str, approve: bool = True, remark: str = ''):
361 def set_friend_add_request(self, flag: str, approve: bool = True, remark: str = ""): 362 """ 363 设置好友添加请求 364 Args: 365 flag: 请求flag 366 approve: 是否同意请求 367 remark: 添加后的好友备注 368 """ 369 data = { 370 "flag": flag, 371 "approve": approve, 372 "remark": remark 373 } 374 return self.get("/set_friend_add_request", data)
设置好友添加请求
Arguments:
- flag: 请求flag
- approve: 是否同意请求
- remark: 添加后的好友备注
def
set_group_add_request( self, flag: str, sub_type: str = 'add', approve: bool = True, reason: str = ''):
376 def set_group_add_request(self, flag: str, sub_type: str = "add", approve: bool = True, reason: str = ""): 377 """ 378 设置群添加请求 379 Args: 380 flag: 请求flag 381 sub_type: 添加请求类型,请参考api文档 382 approve: 是否同意请求 383 reason: 拒绝理由 384 """ 385 data = { 386 "flag": flag, 387 "sub_type": sub_type, 388 "approve": approve, 389 "reason": reason 390 } 391 return self.get("/set_group_add_request", data)
设置群添加请求
Arguments:
- flag: 请求flag
- sub_type: 添加请求类型,请参考api文档
- approve: 是否同意请求
- reason: 拒绝理由
def
get_stranger_info(self, user_id: int, no_cache: bool = False):
399 def get_stranger_info(self, user_id: int, no_cache: bool = False): 400 """ 401 获取陌生人信息 402 Args: 403 user_id: 对方QQ号 404 no_cache: 是否不使用缓存(使用缓存可能更新不及时,但响应更快) 405 """ 406 data = { 407 "user_id": user_id, 408 "no_cache": no_cache 409 } 410 return self.get("/get_stranger_info", data)
获取陌生人信息
Arguments:
- user_id: 对方QQ号
- no_cache: 是否不使用缓存(使用缓存可能更新不及时,但响应更快)
def
get_group_info(self, group_id: int, no_cache: bool = False):
418 def get_group_info(self, group_id: int, no_cache: bool = False): 419 """ 420 获取群信息 421 Args: 422 group_id: 群号 423 no_cache: 是否不使用缓存(使用缓存可能更新不及时,但响应更快) 424 """ 425 data = { 426 "group_id": group_id, 427 "no_cache": no_cache 428 } 429 return self.get("/get_group_info", data)
获取群信息
Arguments:
- group_id: 群号
- no_cache: 是否不使用缓存(使用缓存可能更新不及时,但响应更快)
def
get_group_member_info(self, group_id: int, user_id: int, no_cache: bool = False):
437 def get_group_member_info(self, group_id: int, user_id: int, no_cache: bool = False): 438 """ 439 获取群成员信息 440 Args: 441 group_id: 群号 442 user_id: QQ号 443 no_cache: 是否不使用缓存(使用缓存可能更新不及时,但响应更快) 444 """ 445 data = { 446 "group_id": group_id, 447 "user_id": user_id, 448 "no_cache": no_cache 449 } 450 return self.get("/get_group_member_info", data)
获取群成员信息
Arguments:
- group_id: 群号
- user_id: QQ号
- no_cache: 是否不使用缓存(使用缓存可能更新不及时,但响应更快)
def
get_group_member_list(self, group_id: int):
452 def get_group_member_list(self, group_id: int): 453 """ 454 获取群成员列表 455 Args: 456 group_id: 群号 457 """ 458 data = { 459 "group_id": group_id 460 } 461 return self.get("/get_group_member_list", data)
获取群成员列表
Arguments:
- group_id: 群号
def
get_group_honor_info(self, group_id: int, type_: str = 'all'):
463 def get_group_honor_info(self, group_id: int, type_: str = "all"): 464 """ 465 获取群荣誉信息 466 Args: 467 group_id: 群号 468 type_: 要获取的群荣誉类型,可传入 talkative performer legend strong_newbie emotion 以分别获取单个类型的群荣誉数据,或传入 all 获取所有数据 469 """ 470 data = { 471 "group_id": group_id, 472 "type": type_ 473 } 474 return self.get("/get_group_honor_info", data)
获取群荣誉信息
Arguments:
- group_id: 群号
- type_: 要获取的群荣誉类型,可传入 talkative performer legend strong_newbie emotion 以分别获取单个类型的群荣誉数据,或传入 all 获取所有数据
def
get_csrf_token(self):
482 def get_csrf_token(self): 483 """ 484 获取CSRF Token 485 """ 486 return self.get("/get_csrf_token")
获取CSRF Token
def
get_credentials(self):
488 def get_credentials(self): 489 """ 490 获取Credentials 491 """ 492 return self.get("/get_credentials")
获取Credentials
def
get_record(self, file: str, out_format: str = 'mp3', out_file: str = ''):
494 def get_record(self, file: str, out_format: str = "mp3", out_file: str = ""): 495 """ 496 获取语音 497 Args: 498 file: 文件ID 499 out_format: 输出格式,mp3或amr,默认mp3 500 out_file: 输出文件名,默认使用文件ID 501 """ 502 data = { 503 "file": file, 504 "out_format": out_format, 505 "out_file": out_file 506 } 507 return self.get("/get_record", data)
获取语音
Arguments:
- file: 文件ID
- out_format: 输出格式,mp3或amr,默认mp3
- out_file: 输出文件名,默认使用文件ID
def
get_image(self, file: str):
509 def get_image(self, file: str): 510 """ 511 获取图片 512 Args: 513 file: 文件ID 514 """ 515 data = { 516 "file": file 517 } 518 return self.get("/get_image", data)
获取图片
Arguments:
- file: 文件ID
def
can_send_record(self):
526 def can_send_record(self): 527 """ 528 检查是否可以发送语音 529 """ 530 return self.get("/can_send_record")
检查是否可以发送语音
api =
<OnebotAPI object>