diff --git a/admin/dashboard/blueprints/contacts.py b/admin/dashboard/blueprints/contacts.py index 955660b..1cff6fc 100644 --- a/admin/dashboard/blueprints/contacts.py +++ b/admin/dashboard/blueprints/contacts.py @@ -1,10 +1,9 @@ from flask import Blueprint, render_template, jsonify, request, current_app from .auth import login_required -import logging +from loguru import logger # 创建联系人管理蓝图 contacts_bp = Blueprint('contacts', __name__, url_prefix='/contacts') -logger = logging.getLogger("ContactsBlueprint") # 联系人管理页面 @contacts_bp.route('/') diff --git a/admin/dashboard/blueprints/messages.py b/admin/dashboard/blueprints/messages.py index 1e5a8ff..c5d7380 100644 --- a/admin/dashboard/blueprints/messages.py +++ b/admin/dashboard/blueprints/messages.py @@ -1,13 +1,13 @@ from flask import Blueprint, render_template, jsonify, request, current_app from .auth import login_required -import logging +from loguru import logger import xml.etree.ElementTree as ET from datetime import datetime from utils.message_formatter import format_quote_message # 创建消息管理蓝图 messages_bp = Blueprint('messages', __name__) -logger = logging.getLogger("MessagesBlueprint") +logger = logger # 消息列表页面 @messages_bp.route('/messages') diff --git a/admin/dashboard/blueprints/plugin_routes.py b/admin/dashboard/blueprints/plugin_routes.py index 83437d8..73972fa 100644 --- a/admin/dashboard/blueprints/plugin_routes.py +++ b/admin/dashboard/blueprints/plugin_routes.py @@ -1,5 +1,5 @@ import json -import logging +from loguru import logger import os import toml @@ -9,7 +9,7 @@ from admin.dashboard.blueprints.auth import login_required # 创建蓝图 plugin_routes = Blueprint('plugin_routes', __name__) -LOG = logging.getLogger(__name__) +LOG = logger # 机器人管理页面 diff --git a/admin/dashboard/blueprints/robot.py b/admin/dashboard/blueprints/robot.py index c7cbe42..cc385de 100644 --- a/admin/dashboard/blueprints/robot.py +++ b/admin/dashboard/blueprints/robot.py @@ -1,12 +1,12 @@ from flask import Blueprint, render_template, jsonify, request, current_app from .auth import login_required -import logging +from loguru import logger from utils.robot_cmd.robot_command import GroupBotManager, Feature, PermissionStatus from datetime import datetime # 创建机器人管理蓝图 robot_bp = Blueprint('robot', __name__, url_prefix='/robot') -logger = logging.getLogger("RobotBlueprint") +LOG = logger # 机器人管理页面 @robot_bp.route('/') @@ -31,7 +31,7 @@ def api_robot_groups(): if groups is None: groups = set() - logger.info(f"获取到 {len(groups)} 个群组") + LOG.info(f"获取到 {len(groups)} 个群组") group_data = [] for group_id in groups: @@ -53,7 +53,7 @@ def api_robot_groups(): "robot_status": robot_status.value if robot_status else "unknown" }) except Exception as e: - logger.warning(f"处理群组 {group_id} 信息时出错: {e}") + LOG.warning(f"处理群组 {group_id} 信息时出错: {e}") # 添加基本信息,避免单个群组错误影响整个列表 group_data.append({ "group_id": group_id, @@ -63,7 +63,7 @@ def api_robot_groups(): return jsonify({"success": True, "data": group_data}) except Exception as e: - logger.error(f"获取群组列表失败: {e}") + LOG.error(f"获取群组列表失败: {e}") return jsonify({"success": False, "error": str(e)}), 500 @robot_bp.route('/api/group//permissions') @@ -83,7 +83,7 @@ def api_robot_group_permissions(group_id): return jsonify({"success": True, "data": permission_data}) except Exception as e: - logger.error(f"获取群组权限失败: {e}") + LOG.error(f"获取群组权限失败: {e}") return jsonify({"success": False, "error": str(e)}), 500 @robot_bp.route('/api/group//permissions', methods=['POST']) @@ -112,7 +112,7 @@ def api_update_robot_permissions(group_id): GroupBotManager.set_group_permission(group_id, feature, new_status) return jsonify({"success": True}) except Exception as e: - logger.error(f"更新群组权限失败: {e}") + LOG.error(f"更新群组权限失败: {e}") return jsonify({"success": False, "error": str(e)}), 400 @robot_bp.route('/api/batch_operation', methods=['POST']) @@ -135,7 +135,7 @@ def api_robot_batch_operation(): else: return jsonify({"success": False, "error": "不支持的操作类型"}), 400 except Exception as e: - logger.error(f"批量操作失败: {e}") + LOG.error(f"批量操作失败: {e}") return jsonify({"success": False, "error": str(e)}), 400 @robot_bp.route('/api/add_group', methods=['POST']) @@ -179,7 +179,7 @@ def api_add_group(): } }) except Exception as e: - logger.error(f"添加群组失败: {e}") + LOG.error(f"添加群组失败: {e}") return jsonify({"success": False, "error": str(e)}), 500 @robot_bp.route('/api/group//message_trend') @@ -211,7 +211,7 @@ def api_group_message_trend(group_id): } }) except Exception as e: - logger.error(f"获取群组消息趋势数据出错: {e}") + LOG.error(f"获取群组消息趋势数据出错: {e}") return jsonify({'success': False, 'error': str(e)}), 500 # 添加缺失的群组状态更新接口 @@ -225,7 +225,7 @@ def api_update_group_status(group_id): if status == 'disabled': # 禁用该群组的所有功能 - logger.info(f"正在禁用群组 {group_id} 的所有功能") + LOG.info(f"正在禁用群组 {group_id} 的所有功能") # 获取所有功能并禁用 for feature in Feature: @@ -245,7 +245,7 @@ def api_update_group_status(group_id): }) elif status == 'enabled': # 启用该群组的基本功能 - logger.info(f"正在启用群组 {group_id} 的基本功能") + LOG.info(f"正在启用群组 {group_id} 的基本功能") # 添加到群组列表 if group_id not in GroupBotManager.local_cache["group_list"]: @@ -269,5 +269,5 @@ def api_update_group_status(group_id): }), 400 except Exception as e: - logger.error(f"更新群组状态失败: {e}") + LOG.error(f"更新群组状态失败: {e}") return jsonify({"success": False, "error": str(e)}), 500 \ No newline at end of file diff --git a/admin/dashboard/blueprints/stats.py b/admin/dashboard/blueprints/stats.py index ed6be8a..95a8bd8 100644 --- a/admin/dashboard/blueprints/stats.py +++ b/admin/dashboard/blueprints/stats.py @@ -1,12 +1,11 @@ from flask import Blueprint, render_template, jsonify, request from .auth import login_required -import logging +from loguru import logger from datetime import datetime from flask import current_app # 创建统计数据蓝图 stats_bp = Blueprint('stats', __name__) -logger = logging.getLogger("StatsBlueprint") # 页面路由 @stats_bp.route('/plugins') diff --git a/admin/dashboard/blueprints/system.py b/admin/dashboard/blueprints/system.py index 01cffe2..d2f568c 100644 --- a/admin/dashboard/blueprints/system.py +++ b/admin/dashboard/blueprints/system.py @@ -1,6 +1,6 @@ from flask import Blueprint, render_template, jsonify, request, send_from_directory, current_app from .auth import login_required -import logging +from loguru import logger import os import time from datetime import datetime @@ -10,7 +10,7 @@ from collections import deque # 创建系统信息蓝图 system_bp = Blueprint('system', __name__) -logger = logging.getLogger("SystemBlueprint") + # 记录应用启动时间 APP_START_TIME = time.time() diff --git a/admin/dashboard/blueprints/virtual_group.py b/admin/dashboard/blueprints/virtual_group.py index fdaaabc..bce4404 100644 --- a/admin/dashboard/blueprints/virtual_group.py +++ b/admin/dashboard/blueprints/virtual_group.py @@ -1,9 +1,9 @@ -import logging +from loguru import logger import uuid from flask import Blueprint, jsonify, request, current_app, render_template from .auth import login_required -logger = logging.getLogger(__name__) + virtual_group_bp = Blueprint('virtual_group', __name__) # 添加虚拟群组管理视图 diff --git a/admin/dashboard/server.py b/admin/dashboard/server.py index 5d6144b..616faa8 100644 --- a/admin/dashboard/server.py +++ b/admin/dashboard/server.py @@ -2,23 +2,22 @@ """ 统计看板服务器 - 使用Flask蓝图重构版 """ -import logging import os import sys import threading -import time -from datetime import datetime - -from gewechat_client import GewechatClient +from loguru import logger from db.message_storage import MessageStorageDB from db.stats_db import StatsDBOperator from flask import Flask, send_from_directory import toml +from wechat_ipad import WechatAPIClient + # 添加项目根目录到系统路径,确保可以导入项目模块 sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) + class DashboardServer: """统计看板服务器""" @@ -34,10 +33,8 @@ class DashboardServer: self.username = username or self.config.get("auth", {}).get("username", "admin") self.password = password or self.config.get("auth", {}).get("password", "admin123") - self.logger = logging.getLogger("DashboardServer") - self.logger.info(f"Dashboard配置加载完成: 服务器将运行在 {self.host}:{self.port}") - logging.getLogger("werkzeug").setLevel(logging.WARNING) - + self.LOG = logger + self.LOG.info(f"Dashboard配置加载完成: 服务器将运行在 {self.host}:{self.port}") # 如果提供了robot实例,则使用其对象 if robot_instance: self.db_manager = robot_instance.db_manager @@ -47,11 +44,10 @@ class DashboardServer: self.contact_manager = robot_instance.contact_manager self.plugin_manager = robot_instance.plugin_manager self.plugin_registry = robot_instance.plugin_registry - self.client:GewechatClient= robot_instance.client - self.app_id = robot_instance.app_id - self.logger.info("使用Robot实例的对象进行初始化") + self.client: WechatAPIClient = robot_instance.ipad_bot + self.LOG.info("使用Robot实例的对象进行初始化") else: - self.logger.error("未提供Robot实例,Dashboard无法正常工作") + self.LOG.error("未提供Robot实例,Dashboard无法正常工作") raise ValueError("必须提供Robot实例") self.app = self._create_app() @@ -75,7 +71,7 @@ class DashboardServer: toml.dump(default_config, f) return default_config except Exception as e: - self.logger.error(f"加载Dashboard配置文件失败: {e}") + self.LOG.error(f"加载Dashboard配置文件失败: {e}") # 返回默认配置 return { "server": {"host": "0.0.0.0", "port": 8888}, @@ -90,10 +86,10 @@ class DashboardServer: app.secret_key = "stats_dashboard_secret_key" # 禁用模板缓存,使修改HTML文件后立即生效 app.config['TEMPLATES_AUTO_RELOAD'] = True - + # 将dashboard_server实例设置为app的属性 app.dashboard_server = self - + # 配置静态文件访问 static_folder = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static') @@ -120,9 +116,9 @@ class DashboardServer: # 注册蓝图 self._register_blueprints(app) - + return app - + def _register_blueprints(self, app): """注册所有蓝图""" # 在函数内部导入蓝图,避免循环导入 @@ -146,52 +142,52 @@ class DashboardServer: app.register_blueprint(stats_bp) app.register_blueprint(system_bp) app.register_blueprint(plugin_routes) - - self.logger.info("所有蓝图已注册") + + self.LOG.info("所有蓝图已注册") def run(self): """运行服务器""" from werkzeug.serving import make_server - self.logger.info(f"启动服务器: {self.host}:{self.port}") + self.LOG.info(f"启动服务器: {self.host}:{self.port}") try: # 使用线程安全的方式运行服务器 self._server = make_server(self.host, self.port, self.app) self._server.serve_forever() except Exception as e: - self.logger.error(f"服务器运行失败: {e}") + self.LOG.error(f"服务器运行失败: {e}") self._stop_event.set() def stop(self): """停止服务器""" - self.logger.info("正在停止服务器...") + self.LOG.info("正在停止服务器...") self._stop_event.set() # 使用werkzeug服务器的关闭方法 if self._server: self._server.shutdown() - self.logger.info("服务器已停止") + self.LOG.info("服务器已停止") def get_current_user_info(self): """获取当前登录的微信用户信息""" try: if not self.client: - self.logger.error("client实例不可用,无法获取当前用户信息") + self.LOG.error("client实例不可用,无法获取当前用户信息") return {"success": False, "message": "实例不可用"} - + # 获取当前登录的微信ID - resp = self.client.get_profile(self.app_id) - + resp = self.client.get_profile(self.client.wxid) + self.LOG.info(f"get_current_user_info:{resp}") if not resp or resp.get("ret") != 200: - self.logger.error(f"获取用户信息失败: {resp}") + self.LOG.error(f"获取用户信息失败: {resp}") return {"success": False, "message": "获取用户信息失败"} - + # 从新的resp格式中获取用户信息 user_data = resp.get("data", {}) if not user_data: return {"success": False, "message": "未获取到用户数据"} - + return { "success": True, "data": { @@ -203,5 +199,5 @@ class DashboardServer: } } except Exception as e: - self.logger.error(f"获取当前用户信息失败: {e}") + self.LOG.error(f"获取当前用户信息失败: {e}") return {"success": False, "message": f"获取用户信息出错: {str(e)}"} diff --git a/base/func_claude.py b/base/func_claude.py index aeb8fe6..e1e7b47 100644 --- a/base/func_claude.py +++ b/base/func_claude.py @@ -1,6 +1,6 @@ import requests import json -import logging +from loguru import logger from datetime import datetime @@ -11,7 +11,7 @@ class Claude(): self.api = conf.get("api") prompt = conf.get("prompt") self.model = conf.get("model") - self.LOG = logging.getLogger("Claude") + self.LOG = logger self.conversation_list = {} self.system_content_msg = {"role": "system", "content": prompt} diff --git a/base/func_deepseek.py b/base/func_deepseek.py index f9ae493..e21a8e8 100644 --- a/base/func_deepseek.py +++ b/base/func_deepseek.py @@ -1,6 +1,6 @@ import requests import json -import logging +from loguru import logger from datetime import datetime @@ -11,7 +11,7 @@ class DeepSeek(): self.api = conf.get("api") prompt = conf.get("prompt") self.model = conf.get("model") - self.LOG = logging.getLogger("deepseek") + self.LOG = logger("deepseek") self.conversation_list = {} self.system_content_msg = {"role": "system", "content": prompt} diff --git a/base/func_doubao.py b/base/func_doubao.py index 1f70ceb..8e6a73a 100644 --- a/base/func_doubao.py +++ b/base/func_doubao.py @@ -1,6 +1,6 @@ import requests import json -import logging +from loguru import logger from datetime import datetime @@ -11,7 +11,7 @@ class Doubao(): self.api = conf.get("api") prompt = conf.get("prompt") self.model = conf.get("model") - self.LOG = logging.getLogger("doubao") + self.LOG = logger self.conversation_list = {} self.system_content_msg = {"role": "system", "content": prompt} diff --git a/base/func_english_news.py b/base/func_english_news.py index fcf9595..9331d20 100644 --- a/base/func_english_news.py +++ b/base/func_english_news.py @@ -14,19 +14,9 @@ from utils.markdown_to_image import convert_md_str_to_image import requests from time import localtime, sleep from lxml import etree -import logging +from loguru import logger from datetime import datetime -# 配置日志 -logging.basicConfig( - level=logging.INFO, - format='%(asctime)s - %(levelname)s - %(message)s', - handlers=[ - logging.FileHandler(f'news_crawler_{datetime.now().strftime("%Y%m%d")}.log'), - logging.StreamHandler() - ] -) -logger = logging.getLogger(__name__) # 请求配置 HEADERS = { diff --git a/base/func_news.py b/base/func_news.py index 088141f..7ae4268 100644 --- a/base/func_news.py +++ b/base/func_news.py @@ -3,7 +3,7 @@ import json import re -import logging +from loguru import logger import time from datetime import datetime @@ -16,7 +16,7 @@ from utils.ai.dify_news_analyze import dify_news_title_analyze class News(object): def __init__(self) -> None: - self.LOG = logging.getLogger(__name__) + self.LOG = logger self.week = {0: "周一", 1: "周二", 2: "周三", 3: "周四", 4: "周五", 5: "周六", 6: "周日"} self.headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0"} diff --git a/db/base.py b/db/base.py index 9522ad5..cd4076e 100644 --- a/db/base.py +++ b/db/base.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -import logging +from loguru import logger from typing import List, Dict, Any, Optional, Tuple, Union from db.connection import DBConnectionManager @@ -7,12 +7,13 @@ from db.connection import DBConnectionManager class BaseDBOperator: """基础数据库操作类""" - + def __init__(self, db_manager: DBConnectionManager): self.db_manager = db_manager - self.LOG = logging.getLogger(self.__class__.__name__) - - def execute_query(self, sql: str, params: Optional[tuple] = None, fetch_one: bool = False) -> Union[List[Dict], Dict, None]: + self.LOG = logger + + def execute_query(self, sql: str, params: Optional[tuple] = None, fetch_one: bool = False) -> Union[ + List[Dict], Dict, None]: """执行查询SQL""" conn = self.db_manager.get_mysql_connection() try: @@ -26,7 +27,7 @@ class BaseDBOperator: return None finally: conn.close() - + def execute_update(self, sql: str, params: Optional[tuple] = None) -> bool: """执行更新SQL""" conn = self.db_manager.get_mysql_connection() @@ -41,12 +42,12 @@ class BaseDBOperator: return False finally: conn.close() - + def execute_batch(self, sql: str, params_list: List[tuple]) -> bool: """批量执行SQL""" if not params_list: return True - + conn = self.db_manager.get_mysql_connection() try: with conn.cursor() as cursor: @@ -59,12 +60,12 @@ class BaseDBOperator: return False finally: conn.close() - + def execute_transaction(self, operations: List[Tuple[str, tuple]]) -> bool: """执行事务""" if not operations: return True - + conn = self.db_manager.get_mysql_connection() try: with conn.cursor() as cursor: @@ -77,4 +78,4 @@ class BaseDBOperator: conn.rollback() return False finally: - conn.close() \ No newline at end of file + conn.close() diff --git a/db/connection.py b/db/connection.py index 5908c90..413031d 100644 --- a/db/connection.py +++ b/db/connection.py @@ -1,4 +1,5 @@ -import logging + +from loguru import logger import mysql.connector import redis @@ -35,7 +36,7 @@ class DBConnectionManager: mysql_config: MySQL配置 redis_config: Redis配置 """ - self.logger = logging.getLogger("DBConnectionManager") + self.LOG = logger self.mysql_pool = None self.redis_pool = None @@ -55,7 +56,7 @@ class DBConnectionManager: """ try: if not config: - self.logger.warning("MySQL配置为空,跳过初始化") + self.LOG.warning("MySQL配置为空,跳过初始化") return # 准备连接池配置 @@ -74,9 +75,9 @@ class DBConnectionManager: # 创建连接池 self.mysql_pool = mysql.connector.pooling.MySQLConnectionPool(**pool_config) - self.logger.info("MySQL连接池初始化成功") + self.LOG.info("MySQL连接池初始化成功") except Exception as e: - self.logger.error(f"MySQL连接池初始化失败: {e}") + self.LOG.error(f"MySQL连接池初始化失败: {e}") self.mysql_pool = None def init_redis_pool(self, config): @@ -87,7 +88,7 @@ class DBConnectionManager: """ try: if not config: - self.logger.warning("Redis配置为空,跳过初始化") + self.LOG.warning("Redis配置为空,跳过初始化") return self.redis_pool = redis.ConnectionPool( @@ -98,9 +99,9 @@ class DBConnectionManager: decode_responses=config.get('decode_responses', True), max_connections=config.get('max_connections', 10) ) - self.logger.info("Redis连接池初始化成功") + self.LOG.info("Redis连接池初始化成功") except Exception as e: - self.logger.error(f"Redis连接池初始化失败: {e}") + self.LOG.error(f"Redis连接池初始化失败: {e}") self.redis_pool = None def get_mysql_connection(self): diff --git a/db/contacts_db.py b/db/contacts_db.py index 8297e4b..603de34 100644 --- a/db/contacts_db.py +++ b/db/contacts_db.py @@ -4,7 +4,7 @@ 用于管理微信联系人信息的存储和查询 """ -import logging +from loguru import logger import json from typing import List, Dict, Optional, Union, Any @@ -18,7 +18,7 @@ class ContactsDBOperator(BaseDBOperator): def __init__(self, db_manager: DBConnectionManager): super().__init__(db_manager) - self.logger = logging.getLogger(__name__) + self.LOG = logger def _ensure_table_exists(self): """确保联系人表存在""" @@ -106,9 +106,9 @@ class ContactsDBOperator(BaseDBOperator): UNIQUE KEY `idx_chatroom_id` (`chatroom_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='微信群信息表'; """) - self.logger.info("成功创建或确认微信群信息表存在") + self.LOG.info("成功创建或确认微信群信息表存在") except Exception as e: - self.logger.error(f"创建微信联系人表或群成员表失败: {e}") + self.LOG.error(f"创建微信联系人表或群成员表失败: {e}") raise def save_contacts(self, contacts_data: List[Dict], contact_type: str) -> bool: @@ -122,7 +122,7 @@ class ContactsDBOperator(BaseDBOperator): bool: 是否成功保存 """ if not contacts_data: - self.logger.warning(f"没有{contact_type}类型的联系人数据需要保存") + self.LOG.warning(f"没有{contact_type}类型的联系人数据需要保存") return True try: @@ -169,11 +169,11 @@ class ContactsDBOperator(BaseDBOperator): self.execute_update(sql, values) - self.logger.info(f"成功保存{len(contacts_data)}个{contact_type}类型的联系人") + self.LOG.info(f"成功保存{len(contacts_data)}个{contact_type}类型的联系人") return True except Exception as e: - self.logger.error(f"保存{contact_type}类型的联系人失败: {e}") + self.LOG.error(f"保存{contact_type}类型的联系人失败: {e}") return False def save_simple_contacts(self, contact_list: List[str], contact_type: str) -> bool: @@ -187,7 +187,7 @@ class ContactsDBOperator(BaseDBOperator): bool: 是否成功保存 """ if not contact_list: - self.logger.warning(f"没有{contact_type}类型的联系人数据需要保存") + self.LOG.warning(f"没有{contact_type}类型的联系人数据需要保存") return True try: @@ -201,11 +201,11 @@ class ContactsDBOperator(BaseDBOperator): self.execute_update(sql, (user_name, contact_type)) - self.logger.info(f"成功保存{len(contact_list)}个{contact_type}类型的简单联系人") + self.LOG.info(f"成功保存{len(contact_list)}个{contact_type}类型的简单联系人") return True except Exception as e: - self.logger.error(f"保存{contact_type}类型的简单联系人失败: {e}") + self.LOG.error(f"保存{contact_type}类型的简单联系人失败: {e}") return False def get_contacts_by_type(self, contact_type: str) -> List[Dict]: @@ -227,7 +227,7 @@ class ContactsDBOperator(BaseDBOperator): results = self.execute_query(sql, (contact_type,)) return results except Exception as e: - self.logger.error(f"获取{contact_type}类型的联系人失败: {e}") + self.LOG.error(f"获取{contact_type}类型的联系人失败: {e}") return [] def get_contact_by_user_name(self, user_name: str) -> Optional[Dict]: @@ -249,7 +249,7 @@ class ContactsDBOperator(BaseDBOperator): result = self.execute_query(sql, (user_name,), fetch_one=True) return result except Exception as e: - self.logger.error(f"获取联系人{user_name}失败: {e}") + self.LOG.error(f"获取联系人{user_name}失败: {e}") return None def get_display_name(self, user_name: str) -> str: @@ -294,10 +294,10 @@ class ContactsDBOperator(BaseDBOperator): display_name = result.get('remark') or result.get('nick_name') or user_name contacts_dict[user_name] = display_name - self.logger.info(f"从数据库获取了 {len(contacts_dict)} 个联系人信息") + self.LOG.info(f"从数据库获取了 {len(contacts_dict)} 个联系人信息") return contacts_dict except Exception as e: - self.logger.error(f"获取所有联系人信息失败: {e}") + self.LOG.error(f"获取所有联系人信息失败: {e}") return {} def get_all_contacts_name_map(self) -> Dict[str, str]: @@ -323,7 +323,7 @@ class ContactsDBOperator(BaseDBOperator): return name_map except Exception as e: - self.logger.error(f"获取所有联系人名称映射失败: {e}") + self.LOG.error(f"获取所有联系人名称映射失败: {e}") return {} def save_chatroom_member_simple(self, chatroom_id: str, member_details: List[Dict]) -> bool: """保存简化版的群成员信息到数据库 @@ -331,35 +331,79 @@ class ContactsDBOperator(BaseDBOperator): Args: chatroom_id: 群聊ID member_details: 群成员信息列表,格式为: - [{'wxid': str, 'nickName': str, 'inviterUserName': str, - 'memberFlag': int, 'displayName': str, - 'bigHeadImgUrl': str, 'smallHeadImgUrl': str}] - + [{'UserName': str, 'NickName': str, 'InviterUserName': str, + 'ChatroomMemberFlag': int, 'DisplayName': str}] + Returns: bool: 是否成功保存 """ if not member_details or not chatroom_id: - self.logger.warning(f"没有群聊{chatroom_id}的成员信息需要保存") + self.LOG.warning(f"没有群聊{chatroom_id}的成员信息需要保存") return False try: for member in member_details: - wxid = member.get('wxid', '') + # 处理新的数据结构 + wxid = "" + if "UserName" in member: + if isinstance(member["UserName"], dict): + wxid = member["UserName"].get("string", "") + else: + wxid = member.get("UserName", "") + elif "wxid" in member: + wxid = member.get("wxid", "") + if not wxid: continue + + # 提取昵称 + nick_name = "" + if "NickName" in member: + if isinstance(member["NickName"], dict): + nick_name = member["NickName"].get("string", "") + else: + nick_name = member.get("NickName", "") + elif "nickName" in member: + nick_name = member.get("nickName", "") + + # 提取邀请人 + inviter_user_name = "" + if "InviterUserName" in member: + inviter_user_name = member.get("InviterUserName", "") + elif "inviterUserName" in member: + inviter_user_name = member.get("inviterUserName", "") + + # 提取成员标志 + member_flag = 0 + if "ChatroomMemberFlag" in member: + member_flag = member.get("ChatroomMemberFlag", 0) + elif "memberFlag" in member: + member_flag = member.get("memberFlag", 0) + + # 判断是否为群主 + is_owner = 0 + if chatroom_id and wxid: + # 查询群信息,检查是否为群主 + chat_room_owner_sql = """ + SELECT chat_room_owner FROM t_chatrooms + WHERE chatroom_id = %s + """ + chat_room_owner_result = self.execute_query(chat_room_owner_sql, (chatroom_id,), fetch_one=True) + if chat_room_owner_result and chat_room_owner_result.get('chat_room_owner') == wxid: + is_owner = 1 # 构建数据 data = { 'chatroom_id': chatroom_id, 'wxid': wxid, - 'nick_name': member.get('nickName', ''), - 'display_name': member.get('displayName', ''), - 'inviter_user_name': member.get('inviterUserName', ''), - 'member_flag': member.get('memberFlag', 0), + 'nick_name': nick_name, + 'display_name': member.get('DisplayName', ''), + 'inviter_user_name': inviter_user_name, + 'member_flag': member_flag, 'big_head_img_url': member.get('bigHeadImgUrl', ''), 'small_head_img_url': member.get('smallHeadImgUrl', ''), - 'is_owner': 0, # 默认值 - 'is_admin': 0, # 默认值 + 'is_owner': is_owner, + 'is_admin': 1 if member_flag == 2049 else 0, # 根据memberFlag判断是否为管理员 # 其他字段使用默认值 'sex': 0, 'signature': '', @@ -387,11 +431,11 @@ class ContactsDBOperator(BaseDBOperator): self.execute_update(sql, values) - self.logger.info(f"成功保存群聊{chatroom_id}的{len(member_details)}个成员信息") + self.LOG.info(f"成功保存群聊{chatroom_id}的{len(member_details)}个成员信息") return True except Exception as e: - self.logger.error(f"保存群聊{chatroom_id}的成员信息失败: {e}") + self.LOG.error(f"保存群聊{chatroom_id}的成员信息失败: {e}") return False def save_chatroom_member_detail(self, chatroom_id: str, member_details: List[Dict]) -> bool: """保存群成员详细信息到数据库 @@ -404,7 +448,7 @@ class ContactsDBOperator(BaseDBOperator): bool: 是否成功保存 """ if not member_details or not chatroom_id: - self.logger.warning(f"没有群聊{chatroom_id}的成员详细信息需要保存") + self.LOG.warning(f"没有群聊{chatroom_id}的成员详细信息需要保存") return False try: @@ -473,11 +517,11 @@ class ContactsDBOperator(BaseDBOperator): self.execute_update(sql, values) - self.logger.info(f"成功保存群聊{chatroom_id}的{len(member_details)}个成员详细信息") + self.LOG.info(f"成功保存群聊{chatroom_id}的{len(member_details)}个成员详细信息") return True except Exception as e: - self.logger.error(f"保存群聊{chatroom_id}的成员详细信息失败: {e}") + self.LOG.error(f"保存群聊{chatroom_id}的成员详细信息失败: {e}") return False def process_chatroom_member_detail_response(self, chatroom_id: str, response: Dict) -> bool: @@ -492,51 +536,95 @@ class ContactsDBOperator(BaseDBOperator): """ try: if response.get('ret') != 200: - self.logger.error(f"获取群聊{chatroom_id}成员详情失败: {response.get('msg')}") + self.LOG.error(f"获取群聊{chatroom_id}成员详情失败: {response.get('msg')}") return False data = response.get('data', []) if not data: - self.logger.warning(f"群聊{chatroom_id}成员详情数据为空") + self.LOG.warning(f"群聊{chatroom_id}成员详情数据为空") return False return self.save_chatroom_member_detail(chatroom_id, data) except Exception as e: - self.logger.error(f"处理群聊{chatroom_id}成员详情数据失败: {e}") + self.LOG.error(f"处理群聊{chatroom_id}成员详情数据失败: {e}") return False def save_chatroom_info(self, chatroom_data: dict) -> bool: """保存群信息到数据库""" try: + # 处理新的数据结构 + user_name = "" + if isinstance(chatroom_data, dict): + if "UserName" in chatroom_data and isinstance(chatroom_data["UserName"], dict): + user_name = chatroom_data["UserName"].get("string", "") + elif "chatroomId" in chatroom_data: + user_name = chatroom_data.get("chatroomId", "") + + if not user_name: + self.LOG.warning("无法获取群聊ID,保存失败") + return False + + # 提取群聊名称 + nick_name = "" + if "NickName" in chatroom_data and isinstance(chatroom_data["NickName"], dict): + nick_name = chatroom_data["NickName"].get("string", "") + elif "chatroomName" in chatroom_data: + nick_name = chatroom_data.get("chatroomName", "") + + # 提取群主信息 + chat_room_owner = "" + if "ChatRoomOwner" in chatroom_data: + chat_room_owner = chatroom_data.get("ChatRoomOwner", "") + + # 提取群通知设置 + chat_room_notify = 0 + if "ChatRoomNotify" in chatroom_data: + chat_room_notify = chatroom_data.get("ChatRoomNotify", 0) + + # 提取群头像 + small_head_img_url = "" + if "SmallHeadImgUrl" in chatroom_data: + small_head_img_url = chatroom_data.get("SmallHeadImgUrl", "").strip() + + # 提取群成员列表 + member_list = [] + if "NewChatroomData" in chatroom_data and "ChatRoomMember" in chatroom_data["NewChatroomData"]: + member_list = chatroom_data["NewChatroomData"].get("ChatRoomMember", []) + elif "memberList" in chatroom_data: + member_list = chatroom_data.get("memberList", []) + data = { - 'chatroom_id': chatroom_data.get('chatroomId', ''), - 'nick_name': chatroom_data.get('nickName', ''), - 'py_initial': chatroom_data.get('pyInitial', ''), - 'quan_pin': chatroom_data.get('quanPin', ''), - 'sex': chatroom_data.get('sex', 0), - 'remark': chatroom_data.get('remark', ''), - 'remark_py_initial': chatroom_data.get('remarkPyInitial', ''), - 'remark_quan_pin': chatroom_data.get('remarkQuanPin', ''), - 'chat_room_notify': chatroom_data.get('chatRoomNotify', 0), - 'chat_room_owner': chatroom_data.get('chatRoomOwner', ''), - 'small_head_img_url': chatroom_data.get('smallHeadImgUrl', ''), - 'member_list': json.dumps(chatroom_data.get('memberList', [])) + 'chatroom_id': user_name, + 'nick_name': nick_name, + 'py_initial': chatroom_data.get('Pyinitial', {}).get('string', ''), + 'quan_pin': chatroom_data.get('QuanPin', {}).get('string', ''), + 'sex': chatroom_data.get('Sex', 0), + 'remark': chatroom_data.get('Remark', {}).get('string', ''), + 'remark_py_initial': chatroom_data.get('RemarkPyinitial', {}).get('string', ''), + 'remark_quan_pin': chatroom_data.get('RemarkQuanPin', {}).get('string', ''), + 'chat_room_notify': chat_room_notify, + 'chat_room_owner': chat_room_owner, + 'small_head_img_url': small_head_img_url, + 'member_list': json.dumps(member_list) } + fields = ', '.join(data.keys()) placeholders = ', '.join(['%s'] * len(data)) update_clause = ', '.join([f"{k}=VALUES({k})" for k in data.keys() if k != 'chatroom_id']) values = tuple(data.values()) + sql = f""" INSERT INTO t_chatrooms ({fields}) VALUES ({placeholders}) ON DUPLICATE KEY UPDATE {update_clause} """ + self.execute_update(sql, values) - self.logger.info(f"成功保存群聊 {data['chatroom_id']} 信息") + self.LOG.info(f"成功保存群聊 {data['chatroom_id']} 信息") return True except Exception as e: - self.logger.error(f"保存群聊信息失败: {e}") + self.LOG.error(f"保存群聊信息失败: {e}") return False def get_chatroom_info(self, chatroom_id: str) -> Optional[dict]: @@ -548,7 +636,7 @@ class ContactsDBOperator(BaseDBOperator): result['member_list'] = json.loads(result['member_list']) return result except Exception as e: - self.logger.error(f"获取群聊{chatroom_id}信息失败: {e}") + self.LOG.error(f"获取群聊{chatroom_id}信息失败: {e}") return None def update_chatroom_info(self, chatroom_id: str, update_data: dict) -> bool: @@ -559,10 +647,10 @@ class ContactsDBOperator(BaseDBOperator): values.append(chatroom_id) sql = f"UPDATE t_chatrooms SET {set_clause} WHERE chatroom_id = %s" self.execute_update(sql, tuple(values)) - self.logger.info(f"成功更新群聊 {chatroom_id} 信息") + self.LOG.info(f"成功更新群聊 {chatroom_id} 信息") return True except Exception as e: - self.logger.error(f"更新群聊{chatroom_id}信息失败: {e}") + self.LOG.error(f"更新群聊{chatroom_id}信息失败: {e}") return False def delete_chatroom_info(self, chatroom_id: str) -> bool: @@ -570,8 +658,8 @@ class ContactsDBOperator(BaseDBOperator): try: sql = "DELETE FROM t_chatrooms WHERE chatroom_id = %s" self.execute_update(sql, (chatroom_id,)) - self.logger.info(f"成功删除群聊 {chatroom_id} 信息") + self.LOG.info(f"成功删除群聊 {chatroom_id} 信息") return True except Exception as e: - self.logger.error(f"删除群聊{chatroom_id}信息失败: {e}") + self.LOG.error(f"删除群聊{chatroom_id}信息失败: {e}") return False diff --git a/db/group_virtual_redis.py b/db/group_virtual_redis.py index bc252e2..90551fd 100644 --- a/db/group_virtual_redis.py +++ b/db/group_virtual_redis.py @@ -1,5 +1,5 @@ import json -import logging +from loguru import logger from typing import Dict, Any, List, Optional from db.connection import DBConnectionManager @@ -11,7 +11,7 @@ class GroupVirtualRedisDB: def __init__(self, db_manager: DBConnectionManager): self.db_manager = db_manager self.redis_client = db_manager.get_redis_connection() - self.LOG = logging.getLogger("Plugin.GroupVirtual.Redis") + self.LOG = logger self.chat_groups_key = "group_virtual:chat_groups" def load_chat_groups(self) -> Dict[str, Any]: diff --git a/db/kid_photo_redis.py b/db/kid_photo_redis.py index a3f3bc4..9308bba 100644 --- a/db/kid_photo_redis.py +++ b/db/kid_photo_redis.py @@ -2,7 +2,7 @@ from datetime import datetime import json import os -import logging +from loguru import logger from typing import Dict, Optional, List, Any, Set from db.connection import DBConnectionManager @@ -14,14 +14,14 @@ class KidPhotoRedisDB: def __init__(self, db_manager: DBConnectionManager): self.db_manager = db_manager self.prefix = "group:kid_photo:" - logger = logging.getLogger("DB.KidPhotoRedis") + self.LOG = logger def get_redis_connection(self): """获取Redis连接""" try: return self.db_manager.get_redis_connection() except Exception as e: - self.logger.error(f"获取Redis连接失败: {e}") + self.LOG.error(f"获取Redis连接失败: {e}") return None def save_last_analysis_time(self, group_id: str) -> bool: @@ -34,7 +34,7 @@ class KidPhotoRedisDB: redis_client.set(f'{self.prefix}{group_id}:last_time', str(timestamp)) return True except Exception as e: - self.logger.error(f"保存最后分析时间失败: {e}") + self.LOG.error(f"保存最后分析时间失败: {e}") return False def get_last_analysis_time(self, group_id: str) -> Optional[int]: @@ -50,7 +50,7 @@ class KidPhotoRedisDB: return int(timestamp) return None except Exception as e: - self.logger.error(f"获取最后分析时间失败: {e}") + self.LOG.error(f"获取最后分析时间失败: {e}") return None def save_analysis_result(self, group_id: str, result: Dict) -> bool: @@ -62,7 +62,7 @@ class KidPhotoRedisDB: redis_client.set(f'{self.prefix}{group_id}:results', json.dumps(result, ensure_ascii=False)) return True except Exception as e: - self.logger.error(f"保存分析结果失败: {e}") + self.LOG.error(f"保存分析结果失败: {e}") return False def get_last_analysis_result(self, group_id: str) -> Optional[Dict]: @@ -78,10 +78,10 @@ class KidPhotoRedisDB: return json.loads(result) return None except json.JSONDecodeError as e: - self.logger.error(f"解析分析结果JSON失败: {e}") + self.LOG.error(f"解析分析结果JSON失败: {e}") return None except Exception as e: - self.logger.error(f"获取最后分析结果失败: {e}") + self.LOG.error(f"获取最后分析结果失败: {e}") return None def save_processed_photo(self, group_id: str, photo_path: str) -> bool: @@ -96,7 +96,7 @@ class KidPhotoRedisDB: redis_client.sadd(f'{self.prefix}{group_id}:processed_photos', photo_path) return True except Exception as e: - self.logger.error(f"保存已处理照片失败: {e}") + self.LOG.error(f"保存已处理照片失败: {e}") return False def save_processed_photos(self, group_id: str, photo_paths: List[str]) -> bool: @@ -128,7 +128,7 @@ class KidPhotoRedisDB: pipeline.execute() return True except Exception as e: - self.logger.error(f"批量保存已处理照片失败: {e}") + self.LOG.error(f"批量保存已处理照片失败: {e}") return False def get_processed_photos(self, group_id: str) -> Set[str]: @@ -146,7 +146,7 @@ class KidPhotoRedisDB: photos.add(path) return photos except Exception as e: - self.logger.error(f"获取已处理照片失败: {e}") + self.LOG.error(f"获取已处理照片失败: {e}") return set() def is_photo_processed(self, group_id: str, photo_path: str) -> bool: @@ -160,7 +160,7 @@ class KidPhotoRedisDB: return False return redis_client.sismember(f'{self.prefix}{group_id}:processed_photos', photo_path) except Exception as e: - self.logger.error(f"检查照片是否已处理失败: {e}") + self.LOG.error(f"检查照片是否已处理失败: {e}") return False def save_photo_mapping(self, group_id: str, kid_id: str, photo_path: str) -> bool: @@ -183,7 +183,7 @@ class KidPhotoRedisDB: pipeline.execute() return True except Exception as e: - self.logger.error(f"保存照片映射关系失败: {e}") + self.LOG.error(f"保存照片映射关系失败: {e}") return False def get_kid_photos(self, group_id: str, kid_id: str) -> List[str]: @@ -204,7 +204,7 @@ class KidPhotoRedisDB: photos.append(path) return photos except Exception as e: - self.logger.error(f"获取小朋友照片失败: {e}") + self.LOG.error(f"获取小朋友照片失败: {e}") return [] def get_photo_kid(self, group_id: str, photo_name: str) -> Optional[str]: @@ -222,7 +222,7 @@ class KidPhotoRedisDB: kid_id = kid_id.decode('utf-8') return kid_id except Exception as e: - self.logger.error(f"获取照片对应的小朋友ID失败: {e}") + self.LOG.error(f"获取照片对应的小朋友ID失败: {e}") return None def save_last_process_time(self, group_id: str) -> bool: @@ -235,7 +235,7 @@ class KidPhotoRedisDB: redis_client.set(f'{self.prefix}{group_id}:last_process_time', str(timestamp)) return True except Exception as e: - self.logger.error(f"保存最后处理时间失败: {e}") + self.LOG.error(f"保存最后处理时间失败: {e}") return False def get_last_process_time(self, group_id: str) -> Optional[int]: @@ -252,7 +252,7 @@ class KidPhotoRedisDB: return int(timestamp) return None except Exception as e: - self.logger.error(f"获取最后处理时间失败: {e}") + self.LOG.error(f"获取最后处理时间失败: {e}") return None def clear_processed_photos(self, group_id: str) -> bool: @@ -264,7 +264,7 @@ class KidPhotoRedisDB: redis_client.delete(f'{self.prefix}{group_id}:processed_photos') return True except Exception as e: - self.logger.error(f"清理已处理照片记录失败: {e}") + self.LOG.error(f"清理已处理照片记录失败: {e}") return False def clear_analysis_data(self, group_id: str) -> bool: @@ -301,5 +301,5 @@ class KidPhotoRedisDB: pipeline.execute() return True except Exception as e: - self.logger.error(f"清理分析数据失败: {e}") + self.LOG.error(f"清理分析数据失败: {e}") return False \ No newline at end of file diff --git a/db/message_storage.py b/db/message_storage.py index c611d29..c71e2e8 100644 --- a/db/message_storage.py +++ b/db/message_storage.py @@ -5,7 +5,7 @@ from typing import Dict, List, Optional from db.base import BaseDBOperator from db.connection import DBConnectionManager -from gewechat.call_back_message.message import WxMessage +from wechat_ipad.models.message import WxMessage class MessageStorageDB(BaseDBOperator): diff --git a/db/points_db.py b/db/points_db.py index 50246eb..1ed9385 100644 --- a/db/points_db.py +++ b/db/points_db.py @@ -2,7 +2,7 @@ """ 积分系统数据库操作类 """ -import logging +from loguru import logger from datetime import datetime, timedelta from enum import Enum from typing import Dict, List, Optional, Tuple, Any @@ -27,7 +27,7 @@ class PointsDBOperator(BaseDBOperator): def __init__(self, db_manager=None): """初始化积分数据库操作类""" super().__init__(db_manager or DBConnectionManager.get_instance()) - self.logger = logging.getLogger("PointsDBOperator") + self.LOG = logger # 确保数据库表存在,后续不需要处理了。 # self._ensure_tables_exist() @@ -93,9 +93,9 @@ class PointsDBOperator(BaseDBOperator): ) ENGINE=InnoDB CHARACTER SET utf8mb4; """) - self.logger.info("积分系统数据库表检查/创建完成") + self.LOG.info("积分系统数据库表检查/创建完成") except Exception as e: - self.logger.error(f"创建积分系统数据库表失败: {e}") + self.LOG.error(f"创建积分系统数据库表失败: {e}") raise def get_user_points(self, user_id: str, group_id: str) -> Dict: @@ -122,7 +122,7 @@ class PointsDBOperator(BaseDBOperator): # 如果新表没有数据,尝试从旧表迁移数据 return self._migrate_user_points(user_id, group_id) except Exception as e: - self.logger.error(f"获取用户积分失败: {e}") + self.LOG.error(f"获取用户积分失败: {e}") return { "user_id": user_id, "group_id": group_id, @@ -188,7 +188,7 @@ class PointsDBOperator(BaseDBOperator): WHERE user_id = %s AND group_id = %s """, (user_id, group_id), fetch_one=True) or result except Exception as e: - self.logger.error(f"迁移用户积分失败: {e}") + self.LOG.error(f"迁移用户积分失败: {e}") return result def add_points(self, user_id: str, group_id: str, points: int, @@ -261,7 +261,7 @@ class PointsDBOperator(BaseDBOperator): return True, updated_points except Exception as e: - self.logger.error(f"增加用户积分失败: {e}") + self.LOG.error(f"增加用户积分失败: {e}") return False, {"error": str(e)} def deduct_points(self, user_id: str, group_id: str, points: int, @@ -318,7 +318,7 @@ class PointsDBOperator(BaseDBOperator): return True, updated_points except Exception as e: - self.logger.error(f"扣除用户积分失败: {e}") + self.LOG.error(f"扣除用户积分失败: {e}") return False, {"error": str(e)} def transfer_points(self, from_user_id: str, to_user_id: str, group_id: str, @@ -368,7 +368,7 @@ class PointsDBOperator(BaseDBOperator): "to_user": to_result } except Exception as e: - self.logger.error(f"转移用户积分失败: {e}") + self.LOG.error(f"转移用户积分失败: {e}") return False, {"error": str(e)} def get_user_transactions(self, user_id: str, group_id: str, limit: int = 10) -> List[Dict]: @@ -391,7 +391,7 @@ class PointsDBOperator(BaseDBOperator): LIMIT %s """, (user_id, group_id, limit)) except Exception as e: - self.logger.error(f"获取用户交易记录失败: {e}") + self.LOG.error(f"获取用户交易记录失败: {e}") return [] def get_points_ranking(self, group_id: str, limit: int = 10) -> List[Dict]: @@ -414,7 +414,7 @@ class PointsDBOperator(BaseDBOperator): LIMIT %s """, (group_id, limit)) except Exception as e: - self.logger.error(f"获取积分排行榜失败: {e}") + self.LOG.error(f"获取积分排行榜失败: {e}") return [] def get_plugin_config(self, plugin_name: str) -> Optional[Dict]: @@ -433,7 +433,7 @@ class PointsDBOperator(BaseDBOperator): WHERE plugin_name = %s """, (plugin_name,), fetch_one=True) except Exception as e: - self.logger.error(f"获取插件积分配置失败: {e}") + self.LOG.error(f"获取插件积分配置失败: {e}") return None def set_plugin_config(self, plugin_name: str, points_required: int, @@ -462,7 +462,7 @@ class PointsDBOperator(BaseDBOperator): """, (plugin_name, points_required, is_enabled, description)) return True except Exception as e: - self.logger.error(f"设置插件积分配置失败: {e}") + self.LOG.error(f"设置插件积分配置失败: {e}") return False def get_all_plugin_configs(self) -> List[Dict]: @@ -475,7 +475,7 @@ class PointsDBOperator(BaseDBOperator): try: return self.execute_query("SELECT * FROM t_plugin_point_config") except Exception as e: - self.logger.error(f"获取所有插件积分配置失败: {e}") + self.LOG.error(f"获取所有插件积分配置失败: {e}") return [] def check_plugin_points(self, user_id: str, group_id: str, plugin_name: str) -> Tuple[bool, Dict]: @@ -515,7 +515,7 @@ class PointsDBOperator(BaseDBOperator): "required_points": plugin_config["points_required"] } except Exception as e: - self.logger.error(f"检查插件积分失败: {e}") + self.LOG.error(f"检查插件积分失败: {e}") return True, {"error": str(e)} # 出错时默认允许使用 def use_plugin(self, user_id: str, group_id: str, plugin_name: str) -> Tuple[bool, Dict]: @@ -547,7 +547,7 @@ class PointsDBOperator(BaseDBOperator): PointSource.PLUGIN, f"使用插件: {plugin_name}" ) except Exception as e: - self.logger.error(f"使用插件扣除积分失败: {e}") + self.LOG.error(f"使用插件扣除积分失败: {e}") return False, {"error": str(e)} def get_user_points_stats(self, group_id: str) -> Dict[str, Any]: @@ -591,7 +591,7 @@ class PointsDBOperator(BaseDBOperator): return stats except Exception as e: - self.logger.error(f"获取群组积分统计信息失败: {e}") + self.LOG.error(f"获取群组积分统计信息失败: {e}") return stats def imprison_user(self, user_id: str, group_id: str, hours: int = 24, reason: str = None) -> bool: @@ -612,7 +612,7 @@ class PointsDBOperator(BaseDBOperator): """, (user_id, group_id, end_time, reason, end_time, reason)) return True except Exception as e: - self.logger.error(f"关押用户失败: {e}") + self.LOG.error(f"关押用户失败: {e}") return False def check_prison_status(self, user_id: str, group_id: str) -> Optional[Dict]: @@ -630,7 +630,7 @@ class PointsDBOperator(BaseDBOperator): """, (user_id, group_id)) return records[0] if records else None except Exception as e: - self.logger.error(f"检查用户在押状态失败: {e}") + self.LOG.error(f"检查用户在押状态失败: {e}") return None def bailout_user(self, prisoner_id: str, bailout_user_id: str, group_id: str) -> Tuple[bool, str]: @@ -660,5 +660,5 @@ class PointsDBOperator(BaseDBOperator): return True, "保释成功" except Exception as e: - self.logger.error(f"保释用户失败: {e}") + self.LOG.error(f"保释用户失败: {e}") return False, f"保释失败: {str(e)}" \ No newline at end of file diff --git a/event_system/event_manager.py b/event_system/event_manager.py index bfd1cac..791c1ae 100644 --- a/event_system/event_manager.py +++ b/event_system/event_manager.py @@ -1,4 +1,4 @@ -import logging +from loguru import logger from typing import Dict, List, Type, Callable, Any from threading import Lock @@ -30,7 +30,7 @@ class EventManager: raise RuntimeError("EventManager 是单例类,请使用 get_instance() 方法获取实例") self.handlers: Dict[Type[Event], List[Callable]] = {} - self.logger = logging.getLogger("EventManager") + self.LOG = logger def register(self, event_type: Type[Event], handler: Callable) -> None: """注册事件处理器""" @@ -39,13 +39,13 @@ class EventManager: if handler not in self.handlers[event_type]: self.handlers[event_type].append(handler) - self.logger.debug(f"注册事件处理器: {event_type.__name__} -> {handler.__name__}") + self.LOG.debug(f"注册事件处理器: {event_type.__name__} -> {handler.__name__}") def unregister(self, event_type: Type[Event], handler: Callable) -> None: """取消注册事件处理器""" if event_type in self.handlers and handler in self.handlers[event_type]: self.handlers[event_type].remove(handler) - self.logger.debug(f"取消注册事件处理器: {event_type.__name__} -> {handler.__name__}") + self.LOG.debug(f"取消注册事件处理器: {event_type.__name__} -> {handler.__name__}") def publish(self, event_type: Type[Event], event_data: Dict[str, Any] = None) -> None: """发布事件""" @@ -59,4 +59,4 @@ class EventManager: try: handler(event) except Exception as e: - self.logger.error(f"事件处理器 {handler.__name__} 处理 {event_type.__name__} 事件出错: {e}") + self.LOG.error(f"事件处理器 {handler.__name__} 处理 {event_type.__name__} 事件出错: {e}") diff --git a/gewechat.zip b/gewechat.zip new file mode 100644 index 0000000..9d0e1ce Binary files /dev/null and b/gewechat.zip differ diff --git a/gewechat/__init__.py b/gewechat/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/gewechat/api/callback.py b/gewechat/api/callback.py deleted file mode 100644 index 9c4be16..0000000 --- a/gewechat/api/callback.py +++ /dev/null @@ -1,124 +0,0 @@ -from fastapi import APIRouter, Request -from gewechat.call_back_message.message import WxMessage, MessageType, AppMessageType -import logging - -from robot import Robot -from utils.json_converter import json_to_object - -router = APIRouter() -logger = logging.getLogger(__name__) - -# 存储Robot实例的字典,以appid为键 -robot_instances = {} - - -def register_robot(appid, robot_instance): - """注册Robot实例""" - robot_instances[appid] = robot_instance - logger.info(f"已注册appid为{appid}的Robot实例") - - -@router.post("/gewechat/message/callback") -async def callback(request: Request): - """接收微信消息回调""" - try: - # 获取原始JSON数据 - json_data = await request.json() - logger.info(f"收到回调消息: {json_data}") - - # 检查是否为测试消息 - if 'testMsg' in json_data and json_data.get('testMsg') == '验证回调地址是否可用': - logger.info("收到回调地址验证消息,返回成功") - return {"code": 0, "message": "success"} - - # 创建消息对象 - msg = WxMessage.from_json(json_data) - - # 根据消息类型处理 - if msg.type_name == "AddMsg": - await handle_add_message(msg) - elif msg.type_name == "ModContacts": - await handle_mod_contacts(msg) - elif msg.type_name == "DelContacts": - await handle_del_contacts(msg) - elif msg.type_name == "Offline": - await handle_offline(msg) - - return {"code": 0, "message": "success"} - - except Exception as e: - logger.error(f"处理回调消息失败: {str(e)}", exc_info=True) - return {"code": -1, "message": f"处理失败: {str(e)}"} - - -async def handle_add_message(msg: WxMessage): - """处理新消息""" - try: - # 获取对应的Robot实例 - robot: Robot = robot_instances.get(msg.appid) - if robot: - # 调用Robot的onMsg方法处理消息 - robot.onMsg(msg) - else: - logger.warning(f"未找到appid为{msg.appid}的Robot实例") - - except Exception as e: - logger.error(f"处理新消息失败: {str(e)}", exc_info=True) - raise - - -async def handle_mod_contacts(msg: WxMessage): - logger.info(f"联系人信息变更: {msg.raw_data}") - - -async def handle_del_contacts(msg: WxMessage): - """处理联系人删除""" - logger.info(f"联系人被删除: {msg.raw_data}") - # 获取对应的Robot实例并刷新联系人 - robot = robot_instances.get(msg.appid) - if robot: - robot.refresh_contacts() - - -async def handle_offline(msg: WxMessage): - """处理离线通知""" - logger.info(f"账号离线: {msg.wxid}") - # 可以在这里处理账号离线逻辑 - - -async def handle_text_message(msg: WxMessage): - """处理文本消息""" - logger.info(f"收到文本消息: {msg.content.raw_content}") - # TODO: 实现文本消息处理逻辑 - - -async def handle_image_message(msg: WxMessage): - """处理图片消息""" - image_content = msg.get_image_content() - if image_content: - logger.info(f"收到图片消息: {image_content.url}") - # TODO: 实现图片消息处理逻辑 - - -async def handle_app_message(msg: WxMessage): - """处理应用消息""" - app_type = msg.get_app_message_type() - if app_type == AppMessageType.LINK: - logger.info("收到链接消息") - elif app_type == AppMessageType.FILE: - logger.info("收到文件消息") - elif app_type == AppMessageType.MINIPROGRAM: - logger.info("收到小程序消息") - # TODO: 实现应用消息处理逻辑 - - -async def handle_system_message(msg: WxMessage): - """处理系统消息""" - logger.info(f"收到系统消息: {msg.content.raw_content}") - # TODO: 实现系统消息处理逻辑 - - -async def handle_system_notify(msg: WxMessage): - """处理系统通知""" - logger.info(f"收到系统通知: {msg.content.raw_content}") - # TODO: 实现系统通知处理逻辑 diff --git a/gewechat/api/start_server.py b/gewechat/api/start_server.py deleted file mode 100644 index e88dc09..0000000 --- a/gewechat/api/start_server.py +++ /dev/null @@ -1,89 +0,0 @@ -import threading -import logging -import socket -import uvicorn -from fastapi import FastAPI - -from gewechat.api.callback import router as callback_router -from gewechat.client import gewe_client, Client - -# 配置日志 -logger = logging.getLogger(__name__) - - -def is_port_in_use(port, host='0.0.0.0'): - """检查端口是否被占用""" - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: - try: - s.bind((host, port)) - return False - except socket.error: - return True - - -def start_fastapi_server(host="0.0.0.0", port=8999): - """启动FastAPI服务器""" - # 检查端口是否被占用 - if is_port_in_use(port, host): - logger.warning(f"端口 {port} 已被占用,尝试使用其他端口") - # 尝试其他端口 - for test_port in range(9000, 9100): - if not is_port_in_use(test_port, host): - port = test_port - break - else: - logger.error("无法找到可用端口,服务器启动失败") - return False - - try: - app = FastAPI() - app.include_router(callback_router) - - # 添加健康检查路由 - @app.get("/health") - async def health_check(): - return {"status": "ok"} - - logger.info(f"正在启动FastAPI服务器,地址: http://{host}:{port}") - - # 使用线程启动uvicorn服务器 - server_thread = threading.Thread( - target=uvicorn.run, - args=(app,), - kwargs={"host": host, "port": port, "log_level": "info"}, - daemon=True - ) - server_thread.start() - logger.info(f"FastAPI 服务已在 http://{host}:{port} 启动") - logger.info(f"回调URL: http://{host}:{port}/gewechat/callback") - - return port - except Exception as e: - logger.error(f"启动FastAPI服务器失败: {e}", exc_info=True) - return False - - -if __name__ == '__main__': - # 配置日志 - logging.basicConfig( - level=logging.INFO, - format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' - ) - - # 启动服务器 - port = start_fastapi_server() - if port: - print(f"服务器启动成功,端口: {port}") - print(f"回调URL: http://localhost:{port}/gewechat/callback") - print(f"健康检查URL: http://localhost:{port}/health") - - # 保持主线程运行 - try: - import time - - while True: - time.sleep(1) - except KeyboardInterrupt: - print("服务器已停止") - else: - print("服务器启动失败") diff --git a/gewechat/call_back_message/Gewechat.apifox.json b/gewechat/call_back_message/Gewechat.apifox.json deleted file mode 100644 index d45e89e..0000000 --- a/gewechat/call_back_message/Gewechat.apifox.json +++ /dev/null @@ -1 +0,0 @@ -{"apifoxProject":"1.0.0","$schema":{"app":"apifox","type":"project","version":"1.2.0"},"info":{"name":"Gewechat","description":"","mockRule":{"rules":[],"enableSystemRule":true}},"apiCollection":[{"name":"根目录","id":38390999,"auth":{},"securityScheme":{},"parentId":0,"serverId":"","description":"","identityPattern":{"httpApi":{"type":"methodAndPath","bodyType":"","fields":[]}},"shareSettings":{},"visibility":"SHARED","preProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"postProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"inheritPostProcessors":{},"inheritPreProcessors":{},"items":[{"name":"基础API","id":38391003,"auth":{},"securityScheme":{},"parentId":0,"serverId":"default","description":"","identityPattern":{"httpApi":{"type":"inherit","bodyType":""}},"shareSettings":{},"visibility":"INHERITED","preProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"postProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"inheritPostProcessors":{},"inheritPreProcessors":{},"items":[{"name":"登录模块","id":38391004,"auth":{},"securityScheme":{},"parentId":38391003,"serverId":"","description":"","identityPattern":{"httpApi":{"type":"inherit","bodyType":"","fields":[]}},"shareSettings":{},"visibility":"INHERITED","preProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"postProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"inheritPostProcessors":{},"inheritPreProcessors":{},"items":[{"name":"获取Token(步骤1)","api":{"id":"197179336","method":"post","path":"/tools/getTokenId","parameters":{"query":[],"path":[],"cookie":[],"header":[]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"496059644","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"string","description":"token"}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": \"\"\n}","responseId":496059644,"ordering":1}],"requestBody":{"type":"none","parameters":[],"jsonSchema":{"type":"object","properties":{"01J3HCEM46W9BAVQJF1QV48WG3":{"x-tmp-pending-properties":true}},"x-apifox-orders":["01J3HCEM46W9BAVQJF1QV48WG3"],"required":["01J3HCEM46W9BAVQJF1QV48WG3"]},"examples":[{"value":"{\n \n}","mediaType":"none","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":81,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{}},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.496059644"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"获取登录二维码(步骤2) ","api":{"id":"196794502","method":"post","path":"/login/getLoginQrCode","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"MxBFeRlPw4","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","schema":{"type":"string"},"enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312687","code":200,"name":"成功","headers":[],"jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"qrData":{"type":"string","description":"二维码内包含的信息(可用二维码生成工具结合值生成可扫描的微信二维码)"},"appId":{"type":"string","description":"设备ID"},"qrImgBase64":{"type":"string","description":"二维码图片base64"},"uuid":{"type":"string","description":"二维码的uuid"}},"required":["qrData","qrImgBase64","uuid","appId"],"description":"响应数据","x-apifox-orders":["qrData","appId","qrImgBase64","uuid"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"description":"","contentType":"json","mediaType":""}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"appId\": \"wx_wR_U4zPj2M_OTS3BCyoE4\",\n \"qrData\": \"http://weixin.qq.com/x/4dmHZZMtoLbHoLZwd1wE\",\n \"qrImgBase64\": \"data:image/jpg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/wAALCAJaAloBAREA/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/9oACAEBAAA/AP1Toooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooor8gP29f29fjt8Fv2sfHPg3wb45/sbw3pv2H7JZf2RYT+X5lhbyv88sDOcvI55Y4zgcACvAP+Ho/7Tv8A0U3/AMoGl/8AyNR/w9H/AGnf+im/+UDS/wD5Go/4ej/tO/8ARTf/ACgaX/8AI1H/AA9H/ad/6Kb/AOUDS/8A5Go/4ej/ALTv/RTf/KBpf/yNR/w9H/ad/wCim/8AlA0v/wCRqP8Ah6P+07/0U3/ygaX/API1H/D0f9p3/opv/lA0v/5Go/4ej/tO/wDRTf8AygaX/wDI1H/D0f8Aad/6Kb/5QNL/APkaj/h6P+07/wBFN/8AKBpf/wAjV9//APBKT9qP4n/tKf8AC0f+Fj+Jv+Ej/sX+y/sH+gWtr5Pn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\",\n \"uuid\": \"4dmHZZMtoLbHoLZwd1wE\"\n }\n}","responseId":495312687,"ordering":1,"description":"","oasKey":"","oasExtensions":""}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID,首次登录传空,之后传接口返回的appId","additionalProperties":false}},"required":["appId"],"x-apifox-orders":["appId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\"\n}","mediaType":"application/json"}],"oasExtensions":""},"description":"- appId参数为设备ID,首次登录传空,会自动触发创建设备,掉线后重新登录则必须传接口返回的appId,注意**同一个号避免重复创建设备**,以免触发官方风控\n- **取码时传的appId需要与上次登录扫码的微信一致,否则会导致登录失败**\n- 响应结果中的qrImgBase64为微信二维码图片的base64,前端需要**将二维码图片展示给用户并进行手机扫码操作**(PS: **扫码后调用步骤2,手机上才显示登录**)。(或使用响应结果中的qrData生成二维码)","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":54,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{}},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312687"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"执行登录(步骤3)","api":{"id":"196794503","method":"post","path":"/login/checkLogin","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"aMdXp5nLEw","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","schema":{"type":"string"},"enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312688","code":200,"name":"成功","headers":[],"jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"uuid":{"type":"string","description":"二维码的uuid"},"headImgUrl":{"type":"string","description":"头像地址"},"nickName":{"type":"string","description":"昵称"},"expiredTime":{"type":"integer","description":"二维码超时时间"},"status":{"type":"integer","description":"状态"},"loginInfo":{"type":"object","properties":{"uin":{"type":"integer","description":"uin"},"wxid":{"type":"string","description":"微信ID,返回此值则是登录成功"},"nickName":{"type":"string","description":"昵称"},"mobile":{"type":"string","description":"绑定的手机号"},"alias":{"type":"string","description":"微信号"}},"required":["uin","wxid","nickName","mobile","alias"],"description":"登录成功信息","x-apifox-orders":["uin","wxid","nickName","mobile","alias"]}},"required":["uuid","headImgUrl","nickName","expiredTime","status","loginInfo"],"description":"响应数据","x-apifox-orders":["uuid","headImgUrl","nickName","expiredTime","status","loginInfo"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"description":"","contentType":"json","mediaType":""}],"responseExamples":[{"name":"扫码但未点确认时的响应","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"uuid\": \"AZ0yN8d1wJmiNfQBKFgu\",\n \"headImgUrl\": \"http://wx.qlogo.cn/mmhead/ver_1/ZYUmcl1UNzyB2onM08Ij901TaUOLIjHj2UicK3XGDsjEWl4XgQN5IjodunHicBVsZiaZc1iaGCRfluAxkzyibbiau3WBfFj2nprzKp2KryicMjGIvDbWOQGmibwVK648a3o4A8hD/0\",\n \"nickName\": \"G\",\n \"expiredTime\": 225,\n \"status\": 1,\n \"loginInfo\": null\n }\n}","responseId":495312688,"ordering":1,"description":"","oasKey":"","oasExtensions":""},{"name":"登录成功","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"uuid\": \"4YHmGvoXvgmS1MqWVtQ2\",\n \"headImgUrl\": \"http://wx.qlogo.cn/mmhead/ver_1/ZYUmcl1UNzyB2onM08Ij901TaUOLIjHj2UicK3XGDsjEWl4XgQN5IjodunHicBVsZiaZc1iaGCRfluAxkzyibbiau3WBfFj2nprzKp2KryicMjGIvDbWOQGmibwVK648a3o4A8hD/0\",\n \"nickName\": \"G\",\n \"expiredTime\": 230,\n \"status\": 2,\n \"loginInfo\": {\n \"uin\": 4077276085,\n \"wxid\": \"wxid_0xsqb3o0tsvz22\",\n \"nickName\": \"G\",\n \"mobile\": \"17114312382\",\n \"alias\": null\n }\n }\n}","responseId":495312688,"ordering":2,"description":"","oasKey":"","oasExtensions":""}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"uuid":{"type":"string","description":"取码返回的uuid","additionalProperties":false},"captchCode":{"type":"string","description":"扫码后手机提示输入的验证码"}},"required":["appId","uuid","captchCode"],"x-apifox-orders":["appId","uuid","captchCode"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"uuid\": \"IZDexGAEu9_6JkDX0pX-\"\n}","mediaType":"application/json"}],"oasExtensions":""},"description":"- 获取到登录二维码后需每间隔5s调用本接口来判断是否登录成功\n- 新设备登录平台,次日凌晨会掉线一次,重新登录时需调用[获取二维码且传appId取码](/apidoc/shared-69ba62ca-cb7d-437e-85e4-6f3d3df271b1/api-196794502),登录成功后则可以长期在线\n- 登录成功后请保存appId与wxid的对应关系,后续接口中会用到","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":108,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{}},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312688"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"设置消息回调地址","api":{"id":"196884570","method":"post","path":"/tools/setCallback","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"aMdXp5nLEw","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","schema":{"type":"string"},"enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495495974","code":200,"name":"成功","headers":[],"jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"description":"","contentType":"json","mediaType":""}],"responseExamples":[{"name":"扫码但未点确认时的响应","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495495974,"ordering":1},{"name":"登录成功","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"uuid\": \"4YHmGvoXvgmS1MqWVtQ2\",\n \"headImgUrl\": \"http://wx.qlogo.cn/mmhead/ver_1/ZYUmcl1UNzyB2onM08Ij901TaUOLIjHj2UicK3XGDsjEWl4XgQN5IjodunHicBVsZiaZc1iaGCRfluAxkzyibbiau3WBfFj2nprzKp2KryicMjGIvDbWOQGmibwVK648a3o4A8hD/0\",\n \"nickName\": \"G\",\n \"expiredTime\": 230,\n \"status\": 2,\n \"loginInfo\": {\n \"uin\": 4077276085,\n \"wxid\": \"wxid_0xsqb3o0tsvz22\",\n \"nickName\": \"G\",\n \"mobile\": \"17114312382\",\n \"alias\": null\n }\n }\n}","responseId":495495974,"ordering":2}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"token":{"type":"string","description":"token","additionalProperties":false},"callbackUrl":{"type":"string","description":"回调接收地址","additionalProperties":false}},"required":["token","callbackUrl"],"x-apifox-orders":["token","callbackUrl"]},"examples":[{"value":"{\n \"token\": \"{{gewe-token}}\",\n \"callbackUrl\": \"http://www.baidu.com\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":114,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{}},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495495974"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"查看设备列表","api":{"id":"266307392","method":"post","path":"/login/deviceList","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"aMdXp5nLEw","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","schema":{"type":"string"},"enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"623722504","code":200,"name":"成功","headers":[],"jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"array","items":{"type":"string"}}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"description":"","contentType":"json","mediaType":""}],"responseExamples":[{"name":"扫码但未点确认时的响应","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": [\n \"wx_YQFamjNEfV1LFFl9TRYVb\"\n ]\n}","responseId":623722504,"ordering":1,"description":"","oasKey":"","oasExtensions":""},{"name":"登录成功","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"uuid\": \"4YHmGvoXvgmS1MqWVtQ2\",\n \"headImgUrl\": \"http://wx.qlogo.cn/mmhead/ver_1/ZYUmcl1UNzyB2onM08Ij901TaUOLIjHj2UicK3XGDsjEWl4XgQN5IjodunHicBVsZiaZc1iaGCRfluAxkzyibbiau3WBfFj2nprzKp2KryicMjGIvDbWOQGmibwVK648a3o4A8hD/0\",\n \"nickName\": \"G\",\n \"expiredTime\": 230,\n \"status\": 2,\n \"loginInfo\": {\n \"uin\": 4077276085,\n \"wxid\": \"wxid_0xsqb3o0tsvz22\",\n \"nickName\": \"G\",\n \"mobile\": \"17114312382\",\n \"alias\": null\n }\n }\n}","responseId":623722504,"ordering":2,"description":"","oasKey":"","oasExtensions":""}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{},"x-apifox-orders":[]},"examples":[{"value":"","mediaType":"application/json"}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":120,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{}},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.623722504"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}}]},{"name":"联系人模块","id":38391005,"auth":{},"securityScheme":{},"parentId":38391003,"serverId":"","description":"","identityPattern":{"httpApi":{"type":"inherit","bodyType":"","fields":[]}},"shareSettings":{},"visibility":"INHERITED","preProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"postProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"inheritPostProcessors":{},"inheritPreProcessors":{},"items":[{"name":"获取通讯录列表","api":{"id":"196794504","method":"post","path":"/contacts/fetchContactsList","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312689","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"friends":{"type":"array","items":{"type":"string"},"description":"好友的wxid"},"chatrooms":{"type":"array","items":{"type":"string"},"description":"保存到通讯录中群聊的ID"},"ghs":{"type":"array","items":{"type":"string"},"description":"关注的公众号ID"}},"required":["friends","chatrooms","ghs"],"x-apifox-orders":["friends","chatrooms","ghs"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"friends\": [\n \"tmessage\",\n \"medianote\",\n \"qmessage\",\n \"qqmail\",\n \"wxid_910acevfm2nb21\",\n \"qqsafe\",\n \"wxid_9299552988412\",\n \"weixin\",\n \"exmail_tool\",\n \"wxid_mp05xmje0ctn22\",\n \"wxid_09oq4f4j4wg912\",\n \"wxid_6bfguz79h8n122\",\n \"wxid_lyuq4hr4lrjq22\",\n \"wxid_a1zqyljsrsdu12\",\n \"wxid_lv3pb3zhna3522\",\n \"wxid_k2biq6fuinsr22\",\n \"wxid_ujredjhxz9y712\",\n \"wxid_uwb7989u0jea12\",\n \"wxid_in46ey732vxu12\",\n \"wxid_3rvervwohj6921\",\n \"wxid_4wkls7tu62ua12\",\n \"wxid_g0bdknnotx2f12\",\n \"wxid_ce5fgp0icb3y21\",\n \"wxid_1482424825211\",\n \"wxid_vw3p4f6jy7bm12\",\n \"wxid_o2m8xm71c23522\",\n \"wxid_bclqpc2ho6o412\",\n \"wxid_98pjjzpiisi721\",\n \"wxid_noq2wsn5c8h222\"\n ],\n \"chatrooms\": [\n \"2180313478@chatroom\",\n \"14358945067@chatroom\",\n \"17362526147@chatroom\",\n \"11685224357@chatroom\",\n \"17522822550@chatroom\"\n ],\n \"ghs\": [\n \"gh_7aac992b0363\",\n \"gh_d7293b5f14f4\",\n \"gh_f51ce3ef83a4\",\n \"gh_7d20df86e26b\",\n \"gh_69bfb92a3e43\"\n ]\n }\n}","responseId":495312689,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false}},"x-apifox-orders":["appId"],"required":["appId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"- 本接口为长耗时接口,耗时时间根据好友数量递增,若接口返回超时可通过[获取通讯录列表缓存接口](https://apifox.com/apidoc/shared-69ba62ca-cb7d-437e-85e4-6f3d3df271b1/api-196794505)获取响应结果\n- 本接口返回的群聊仅为[保存到通讯录中的群聊](https://zhidao.baidu.com/question/144774265918920605/answer/4326874247.html),若想获取会话列表中的所有群聊,需要通过[消息订阅](https://apifox.com/apidoc/shared-69ba62ca-cb7d-437e-85e4-6f3d3df271b1/api-196884570)做二次处理。原因:当未获取的群有成员在群内发消息的话会有消息回调, 开发者此刻调用[获取群详情接口](https://apifox.com/apidoc/shared-69ba62ca-cb7d-437e-85e4-6f3d3df271b1/api-196794513)查询群信息入库保存即可,比如说手机上三年前不说话的群,侧滑删除了,用户手机上也不会看到被删除的群聊的 ,但是有群成员说了话他会显示,原理就是各个终端(Android、IOS、桌面版微信)取得了消息回调,又去获取群详情信息,本地数据库缓存了下来,显示的手机群聊,让用户感知的。","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":0,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312689"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"获取通讯录列表缓存","api":{"id":"196794505","method":"post","path":"/contacts/fetchContactsListCache","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312690","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495312690,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false}},"x-apifox-orders":["appId"],"required":["appId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"通讯录列表数据缓存10分钟,超时则需要重新调用[获取通讯录列表接口](https://apifox.com/apidoc/shared-69ba62ca-cb7d-437e-85e4-6f3d3df271b1/api-196794504)","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":6,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312690"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"搜索好友","api":{"id":"196794506","method":"post","path":"/contacts/search","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312691","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"v3":{"type":"string","description":"搜索好友的v3,添加好友时使用"},"nickName":{"type":"string","description":"搜索好友的昵称"},"sex":{"type":"integer","description":"搜索好友的性别"},"signature":{"type":"null","description":"搜索好友的签名"},"bigHeadImgUrl":{"type":"string","description":"搜索好友的大尺寸头像"},"smallHeadImgUrl":{"type":"string","description":"搜索好友的小尺寸头像"},"v4":{"type":"string","description":"搜索好友的v4,添加好友时使用"}},"required":["v3","nickName","sex","signature","bigHeadImgUrl","smallHeadImgUrl","v4"],"x-apifox-orders":["v3","nickName","sex","signature","bigHeadImgUrl","smallHeadImgUrl","v4"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"v3\": \"v3_020b3826fd030100000000006c20217514f7f2000000501ea9a3dba12f95f6b60a0536a1adb690dcccc9bf58cc80765e6eb16bc2678a36a0ed264e1b22596f787de6acc71a4beb20b69ab88bfd6d71aa1858b3@stranger\",\n \"nickName\": \"zhang\",\n \"sex\": 1,\n \"signature\": \"学习、成长、锻炼\",\n \"bigHeadImgUrl\": \"http://wx.qlogo.cn/mmhead/ver_1/yoYJGtDmGicz9QGOFRb71Ns6onQO63bnfJibicBwEmO73m18N7BicrGzeYsdxOrUf5qwJq9mMaQbDwEBA92uPOuibZg/0\",\n \"smallHeadImgUrl\": \"http://wx.qlogo.cn/mmhead/ver_1/yoYJGtDmGicz9QGOFRb71Ns6onQO63bnfJibicBwEmO73m18N7BicrGzeYsdxOrUf5qwJq9mMaQbDwEBA92uPOuibZg/132\",\n \"v4\": \"v4_000b708f0b04000001000000000056d3690365e0eefe00ef467a8e651000000050ded0b020927e3c97896a09d47e6e9ec65e1f9d32b06f86df4790587a6308149b3c8a90185e824efccd5b41bd75f6240ab020f9dd4b5915a083c6784a5cfcb806f53ca340b4c95b24f474d6e3fc0661301b3b3b741aac3eb5@stranger\"\n }\n}","responseId":495312691,"ordering":1},{"name":"异常示例","data":"{\n \"ret\": 500,\n \"msg\": \"搜索联系人失败\",\n \"data\": {\n \"code\": \"-4\",\n \"msg\": \"用户不存在\"\n }\n}","responseId":495312691,"ordering":2}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"contactsInfo":{"type":"string","description":"搜索的联系人信息,微信号、手机号..."}},"x-apifox-orders":["appId","contactsInfo"],"required":["appId","contactsInfo"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"contactsInfo\": \"zhangch\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"搜索的联系人信息若已经是好友,响应结果的v3则为好友的wxid\n本接口返回的数据可通过[添加联系人接口](https://apifox.com/apidoc/shared-69ba62ca-cb7d-437e-85e4-6f3d3df271b1/api-196794507)发送添加好友请求","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":12,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312691"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"添加联系人/同意添加好友","api":{"id":"196794507","method":"post","path":"/contacts/addContacts","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312692","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495312692,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"scene":{"type":"integer","description":"添加来源,同意添加好友时传回调消息xml中的scene值。\n添加好友时的枚举值如下:\n3 :微信号搜索\n4 :QQ好友\n8 :来自群聊\n15:手机号"},"option":{"type":"integer","description":"操作类型,2添加好友 3同意好友 4拒绝好友"},"v3":{"type":"string","description":"通过搜索或回调消息获取到的v3"},"v4":{"type":"string","description":"通过搜索或回调消息获取到的v4"},"content":{"type":"string","description":"添加好友时的招呼语"}},"x-apifox-orders":["appId","scene","option","v3","v4","content"],"required":["appId","scene","content","v4","v3","option"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"scene\": 3,\n \"content\": \"hallo\",\n \"v4\": \"v4_000b708f0b04000001000000000054a9e826263634356493c57b8e651000000050ded0b020927e3c97896a09d47e6e9e455d674c2544e251e77c7cba08cc6cef8f7df9e52d2bd4a3cef771c8661331fa1939fbe54f4e479d6d9d4522d70aeba057ffd0dd82398730da44ee57332a7bdea4862304d4799758ba@stranger\",\n \"v3\": \"v3_020b3826fd030100000000003a070e7757675c000000501ea9a3dba12f95f6b60a0536a1adb690dcccc9bf58cc80765e6eb16bffa5996420bb1b2577634516ff82090419d8bdcd5689df8dfb21d40af93d286f72c3a0e8cfa6dcb68afed39226f008c6@stranger\",\n \"option\": 2\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"本接口建议在线3天后再进行调用。\n好友添加成功后,会通过回调消息推送一条包含v3的消息,可用于判断好友是否添加成功。","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":18,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312692"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"删除好友","api":{"id":"196794508","method":"post","path":"/contacts/deleteFriend","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312693","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495312693,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"wxid":{"type":"string","description":"删除好友的wxid"}},"x-apifox-orders":["appId","wxid"],"required":["appId","wxid"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"wxid\": \"wxid_phyyedw9xap22\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":24,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312693"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"上传手机通讯录","api":{"id":"196794509","method":"post","path":"/contacts/uploadPhoneAddressList","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312694","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495312694,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"phones":{"type":"array","items":{"type":"string","description":"手机号"},"description":"需要上传的手机号"},"opType":{"type":"integer","description":"操作类型,1:上传 2:删除"}},"x-apifox-orders":["appId","phones","opType"],"required":["appId","phones","opType"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"phones\": [\n \"18616561632\",\n \"18134173174\"\n ],\n \"opType\": 1\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":30,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312694"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"获取群/好友简要信息","api":{"id":"196794512","method":"post","path":"/contacts/getBriefInfo","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312697","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"userName":{"type":"string"},"nickName":{"type":"string"},"pyInitial":{"type":"string"},"quanPin":{"type":"string"},"sex":{"type":"integer"},"remark":{"type":"string"},"remarkPyInitial":{"type":"string"},"remarkQuanPin":{"type":"string"},"signature":{"type":"null"},"alias":{"type":"string"},"snsBgImg":{"type":"null"},"country":{"type":"string"},"bigHeadImgUrl":{"type":"string"},"smallHeadImgUrl":{"type":"string"},"description":{"type":"null"},"cardImgUrl":{"type":"null"},"labelList":{"type":"string"},"province":{"type":"string"},"city":{"type":"string"},"phoneNumList":{"type":"null"}},"x-apifox-orders":["userName","nickName","pyInitial","quanPin","sex","remark","remarkPyInitial","remarkQuanPin","signature","alias","snsBgImg","country","bigHeadImgUrl","smallHeadImgUrl","description","cardImgUrl","labelList","province","city","phoneNumList"]}}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"获取联系人信息成功\",\n \"data\": [\n {\n \"userName\": \"wxid_phyyedw9xap22\",\n \"nickName\": \"Ashley\",\n \"pyInitial\": \"ASHLEY\",\n \"quanPin\": \"Ashley\",\n \"sex\": 2,\n \"remark\": \"\",\n \"remarkPyInitial\": \"\",\n \"remarkQuanPin\": \"\",\n \"signature\": null,\n \"alias\": \"zero-one_200906\",\n \"snsBgImg\": null,\n \"country\": \"AD\",\n \"bigHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/buiaXybHTBK3BuGr1edN72zBDermWVFJ7YC8Jib2RcCSdiauAtZcPgUQpdhE9KY5NsumDAWD16fsg3A6OKuhdEr97VAHdTGgk6R1Eibuj7ZNwJ4/0\",\n \"smallHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/buiaXybHTBK3BuGr1edN72zBDermWVFJ7YC8Jib2RcCSdiauAtZcPgUQpdhE9KY5NsumDAWD16fsg3A6OKuhdEr97VAHdTGgk6R1Eibuj7ZNwJ4/132\",\n \"description\": null,\n \"cardImgUrl\": null,\n \"labelList\": \"\",\n \"province\": \"\",\n \"city\": \"\",\n \"phoneNumList\": null\n }\n ]\n}","responseId":495312697,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"wxids":{"type":"array","items":{"type":"string","description":"好友的wxid"},"description":"好友的wxid","minItems":1,"maxItems":100}},"x-apifox-orders":["appId","wxids"],"required":["appId","wxids"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"wxids\": [\n \"wxid_phyyedw9xap22\"\n ]\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":48,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312697"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"获取群/好友详细信息","api":{"id":"196794513","method":"post","path":"/contacts/getDetailInfo","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312698","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"userName":{"type":"string","description":"好友的wxid"},"nickName":{"type":"string","description":"好友的昵称"},"pyInitial":{"type":"null","description":"好友昵称的拼音首字母"},"quanPin":{"type":"string","description":"好友昵称的全拼"},"sex":{"type":"integer","description":"好友的性别"},"remark":{"type":"null","description":"好友备注"},"remarkPyInitial":{"type":"null","description":"好友备注的拼音首字母"},"remarkQuanPin":{"type":"null","description":"好友备注的全拼"},"signature":{"type":"string","description":"好友的签名"},"alias":{"type":"string","description":"好友的微信号"},"snsBgImg":{"type":"string","description":"朋友圈背景图链接"},"country":{"type":"string","description":"国家"},"bigHeadImgUrl":{"type":"string","description":"大尺寸头像链接"},"smallHeadImgUrl":{"type":"string","description":"小尺寸头像链接"},"description":{"type":"null","description":"好友的描述"},"cardImgUrl":{"type":"null","description":"好友描述的图片链接"},"labelList":{"type":"null","description":"好友的标签ID"},"province":{"type":"null","description":"省份"},"city":{"type":"null","description":"城市"},"phoneNumList":{"type":"null","description":"好友的手机号码"}},"x-apifox-orders":["userName","nickName","pyInitial","quanPin","sex","remark","remarkPyInitial","remarkQuanPin","signature","alias","snsBgImg","country","bigHeadImgUrl","smallHeadImgUrl","description","cardImgUrl","labelList","province","city","phoneNumList"]}}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"获取联系人信息成功\",\n \"data\": [\n {\n \"userName\": \"wxid_phyyedw9xap22\",\n \"nickName\": \"Ashley\",\n \"pyInitial\": null,\n \"quanPin\": \"Ashley\",\n \"sex\": 2,\n \"remark\": null,\n \"remarkPyInitial\": null,\n \"remarkQuanPin\": null,\n \"signature\": \"山林不向四季起誓 枯荣随缘。\",\n \"alias\": \"zero-one_200906\",\n \"snsBgImg\": \"http://shmmsns.qpic.cn/mmsns/UaAfqYic92wm7ZCrsEwlQMXSmBLs8dpwBzrXnrOyyP3B8bDibCCFInJ9PicC9LPYY17uWH1yIOmBYQ/0\",\n \"country\": \"AD\",\n \"bigHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/buiaXybHTBK3BuGr1edN72zBDermWVFJ7YC8Jib2RcCSdiauAtZcPgUQpdhE9KY5NsumDAWD16fsg3A6OKuhdEr97VAHdTGgk6R1Eibuj7ZNwJ4/0\",\n \"smallHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/buiaXybHTBK3BuGr1edN72zBDermWVFJ7YC8Jib2RcCSdiauAtZcPgUQpdhE9KY5NsumDAWD16fsg3A6OKuhdEr97VAHdTGgk6R1Eibuj7ZNwJ4/132\",\n \"description\": null,\n \"cardImgUrl\": null,\n \"labelList\": null,\n \"province\": null,\n \"city\": null,\n \"phoneNumList\": null\n }\n ]\n}","responseId":495312698,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"wxids":{"type":"array","items":{"type":"string","description":"好友的wxid"},"description":"好友的wxid","minItems":1,"maxItems":20}},"x-apifox-orders":["appId","wxids"],"required":["appId","wxids"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"wxids\": [\n \"yc-081726\"\n ]\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":54,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312698"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"设置好友仅聊天","api":{"id":"196794514","method":"post","path":"/contacts/setFriendPermissions","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312699","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"设置好友权限成功\"\n}","responseId":495312699,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"wxid":{"type":"string","description":"好友的wxid"},"onlyChat":{"type":"boolean","description":"设置好友是否仅聊天"}},"x-apifox-orders":["appId","wxid","onlyChat"],"required":["appId","wxid","onlyChat"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"wxid\": \"wxid_phyyedw9xap22\",\n \"onlyChat\": true\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"设置完好友仅聊天后若发现手机展示不是设置的结果,可能是手机缓存未刷新,重新进入页面刷新查看","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":60,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312699"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"设置好友备注","api":{"id":"196794515","method":"post","path":"/contacts/setFriendRemark","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312700","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"设置好友权限成功\"\n}","responseId":495312700,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"wxid":{"type":"string","description":"好友的wxid"},"remark":{"type":"string","description":"备注的备注"}},"x-apifox-orders":["appId","wxid","remark"],"required":["appId","wxid","remark"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"wxid\": \"wxid_phyyedw9xap22\",\n \"remark\": \"备注\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":66,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312700"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"获取手机通讯录","api":{"id":"196794517","method":"post","path":"/contacts/getPhoneAddressList","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312703","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"userName":{"type":"string"},"v4":{"type":"null"},"nickName":{"type":"null"},"sex":{"type":"integer"},"phoneMd5":{"type":"string"},"signature":{"type":"string"},"alias":{"type":"null"},"country":{"type":"string"},"bigHeadImgUrl":{"type":"string"},"smallHeadImgUrl":{"type":"string"},"province":{"type":"string"},"city":{"type":"string"},"personalCard":{"type":"integer"}},"x-apifox-orders":["userName","v4","nickName","sex","phoneMd5","signature","alias","country","bigHeadImgUrl","smallHeadImgUrl","province","city","personalCard"]}}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"获取手机通讯录成功\",\n \"data\": [\n {\n \"userName\": \"wxid_ddgsghdfafaphh22\",\n \"v4\": null,\n \"nickName\": null,\n \"sex\": 1,\n \"phoneMd5\": \"d36f4cc1c8bca1ef41b93d2215133cdb\",\n \"signature\": \"......\",\n \"alias\": null,\n \"country\": \"CN\",\n \"bigHeadImgUrl\": \"http://wx.qlogo.cn/mmhead/ver_1/vwGdLRK5jtpXagA7dfXlUiaU9VayWNSqia1c2Wib7icJNhPd6WHhqMIVuYuNDfEqPRC2TnmlRSkfYrib9fHyYONwdccv17gibCls7ia8elaunvgMmYicAw22wUJQ3CDw0Cm5ibrOT/0\",\n \"smallHeadImgUrl\": \"http://wx.qlogo.cn/mmhead/ver_1/vwGdLRK5jtpXagA7dfXlUiaU9VayWNSqia1c2Wib7icJNhPd6WHhqMIVuYuNDfEqPRC2TnmlRSkfYrib9fHyYONwdccv17gibCls7ia8elaunvgMmYicAw22wUJQ3CDw0Cm5ibrOT/132\",\n \"province\": \"Jiangsu\",\n \"city\": \"Xuzhou\",\n \"personalCard\": 0\n }\n ]\n}","responseId":495312703,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"phones":{"type":"array","items":{"type":"string","description":"手机号"},"description":"获取哪些手机号的好友详情,不传获取所有"}},"x-apifox-orders":["appId","phones"],"required":["appId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"phones\": []\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":78,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312703"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}}]},{"name":"群模块","id":38391006,"auth":{},"securityScheme":{},"parentId":38391003,"serverId":"","description":"","identityPattern":{"httpApi":{"type":"inherit","bodyType":"","fields":[]}},"shareSettings":{},"visibility":"INHERITED","preProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"postProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"inheritPostProcessors":{},"inheritPreProcessors":{},"items":[{"name":"创建微信群","api":{"id":"196794518","method":"post","path":"/group/createChatroom","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312704","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"headImgBase64":{"type":"string","description":"群头像的base64图片"},"chatroomId":{"type":"string","description":"群ID"}},"required":["headImgBase64","chatroomId"],"x-apifox-orders":["headImgBase64","chatroomId"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\"ret\":200,\"msg\":\"操作成功\",\"data\":{\"headImgBase64\":\"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\",\"chatroomId\":\"34757816141@chatroom\"}}","responseId":495312704,"ordering":1},{"name":"异常示例","data":"{\n \"ret\": 500,\n \"msg\": \"创建群聊失败\",\n \"data\": {\n \"code\": \"0\",\n \"msg\": \"MemberList are wrong\"\n }\n}","responseId":495312704,"ordering":2}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"wxids":{"type":"array","items":{"type":"string","description":"好友的wxid"},"description":"好友的wxid列表","minItems":2}},"x-apifox-orders":["appId","wxids"],"required":["appId","wxids"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"wxids\": [\n \"wxid_0xsqb3o0tsvz22\",\n \"wxid_phyyedw9xap22\"\n ]\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"创建微信群时最少要选择两位微信好友","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":0,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312704"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"修改群名称","api":{"id":"196794519","method":"post","path":"/group/modifyChatroomName","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312705","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495312705,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"chatroomName":{"type":"string","description":"群名称"},"chatroomId":{"type":"string","description":"群ID"}},"x-apifox-orders":["appId","chatroomName","chatroomId"],"required":["appId","chatroomName","chatroomId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"chatroomName\": \"GeWe test\",\n \"chatroomId\": \"34757816141@chatroom\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"修改完群名称后若发现手机未展示修改后的名称,可能是手机缓存未刷新,手机聊天框多切换几次会刷新。","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":6,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312705"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"修改群备注","api":{"id":"196794520","method":"post","path":"/group/modifyChatroomRemark","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312706","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495312706,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"chatroomId":{"type":"string","description":"群ID"},"chatroomRemark":{"type":"string","description":"群备注"}},"x-apifox-orders":["appId","chatroomRemark","chatroomId"],"required":["appId","chatroomRemark","chatroomId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"chatroomRemark\": \"GeWe test private\",\n \"chatroomId\": \"34757816141@chatroom\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"群备注仅自己可见\n修改完群备注后若发现手机未展示修改后的备注,可能是手机缓存未刷新,手机聊天框多切换几次会刷新。","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":12,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312706"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"修改我在群内的昵称","api":{"id":"196794521","method":"post","path":"/group/modifyChatroomNickNameForSelf","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312707","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495312707,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"chatroomId":{"type":"string","description":"群ID"},"nickName":{"type":"string","description":"群昵称"}},"x-apifox-orders":["appId","nickName","chatroomId"],"required":["appId","nickName","chatroomId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"nickName\": \"廖静\",\n \"chatroomId\": \"34757816141@chatroom\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":18,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312707"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"邀请/添加 进群","api":{"id":"196794522","method":"post","path":"/group/inviteMember","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312708","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495312708,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"chatroomId":{"type":"string","description":"群ID"},"wxids":{"type":"string","description":"邀请进群的好友wxid,多个英文逗号分隔"},"reason":{"type":"string","description":"邀请进群的说明"}},"x-apifox-orders":["appId","wxids","chatroomId","reason"],"required":["appId","wxids","chatroomId","reason"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"wxids\": \"wxid_8pvka4jg6qzt22\",\n \"chatroomId\": \"34757816141@chatroom\",\n \"reason\": \"\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":24,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312708"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"删除群成员","api":{"id":"196794523","method":"post","path":"/group/removeMember","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312709","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495312709,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"chatroomId":{"type":"string","description":"群ID"},"wxids":{"type":"string","description":"删除的群成员wxid,多个英文逗号分隔"}},"x-apifox-orders":["appId","wxids","chatroomId"],"required":["appId","wxids","chatroomId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"wxids\": \"wxid_8pvka4jg6qzt22\",\n \"chatroomId\": \"34757816141@chatroom\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":30,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312709"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"退出群聊","api":{"id":"196794524","method":"post","path":"/group/quitChatroom","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312710","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495312710,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"chatroomId":{"type":"string","description":"群ID"}},"x-apifox-orders":["appId","chatroomId"],"required":["appId","chatroomId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"chatroomId\": \"21425161836@chatroom\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":36,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312710"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"解散群聊","api":{"id":"196794525","method":"post","path":"/group/disbandChatroom","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312711","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495312711,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"chatroomId":{"type":"string","description":"群ID"}},"x-apifox-orders":["appId","chatroomId"],"required":["appId","chatroomId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"chatroomId\": \"21425161836@chatroom\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":42,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312711"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"获取群信息","api":{"id":"196794526","method":"post","path":"/group/getChatroomInfo","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312712","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"chatroomId":{"type":"string","description":"群ID"},"nickName":{"type":"string","description":"群名称"},"pyInitial":{"type":"string","description":"群名称的拼音首字母"},"quanPin":{"type":"string","description":"群名称的全拼"},"sex":{"type":"integer"},"remark":{"type":"string","description":"群备注,仅自己可见"},"remarkPyInitial":{"type":"string","description":"群备注的拼音首字母"},"remarkQuanPin":{"type":"string","description":"群备注的全拼"},"chatRoomNotify":{"type":"integer","description":"群消息是否提醒"},"chatRoomOwner":{"type":"string","description":"群主的wxid"},"smallHeadImgUrl":{"type":"string","description":"群头像链接"},"memberList":{"type":"array","items":{"type":"object","properties":{"wxid":{"type":"string","description":"群成员的wxid"},"nickName":{"type":"string","description":"群成员的昵称"},"inviterUserName":{"type":["string","null"],"description":"邀请人的wxid"},"memberFlag":{"type":"integer","description":"标识"},"displayName":{"type":"null","description":"在本群内的昵称"},"bigHeadImgUrl":{"type":"null","description":"大尺寸头像"},"smallHeadImgUrl":{"type":"null","description":"小尺寸头像"}},"required":["wxid","nickName","inviterUserName","memberFlag","displayName","bigHeadImgUrl","smallHeadImgUrl"],"x-apifox-orders":["wxid","nickName","inviterUserName","memberFlag","displayName","bigHeadImgUrl","smallHeadImgUrl"]},"description":"群成员列表"}},"required":["chatroomId","nickName","pyInitial","quanPin","sex","remark","remarkPyInitial","remarkQuanPin","chatRoomNotify","chatRoomOwner","smallHeadImgUrl","memberList"],"x-apifox-orders":["chatroomId","nickName","pyInitial","quanPin","sex","remark","remarkPyInitial","remarkQuanPin","chatRoomNotify","chatRoomOwner","smallHeadImgUrl","memberList"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"chatroomId\": \"34757816141@chatroom\",\n \"nickName\": \"GeWe test\",\n \"pyInitial\": \"GEWETEST\",\n \"quanPin\": \"GeWetest\",\n \"sex\": 0,\n \"remark\": \"GeWe test private\",\n \"remarkPyInitial\": \"GEWETESTPRIVATE\",\n \"remarkQuanPin\": \"GeWetestprivate\",\n \"chatRoomNotify\": 1,\n \"chatRoomOwner\": \"zhangchuan2288\",\n \"smallHeadImgUrl\": \"https://wx.qlogo.cn/mmcrhead/PiajxSqBRaEJEIII6n6NUHudK1r5a29cMDlW0Ef7b1ibzksfrwIcRkTicPRoWm7Km3ZQIpq8xp65nD6yUm8BHxzqhV1ic1jQvvnv/0\",\n \"memberList\": [\n {\n \"wxid\": \"zhangchuan2288\",\n \"nickName\": \"朝夕。\",\n \"inviterUserName\": null,\n \"memberFlag\": 1,\n \"displayName\": null,\n \"bigHeadImgUrl\": null,\n \"smallHeadImgUrl\": null\n },\n {\n \"wxid\": \"wxid_phyyedw9xap22\",\n \"nickName\": \"Ashley\",\n \"inviterUserName\": \"zhangchuan2288\",\n \"memberFlag\": 1,\n \"displayName\": null,\n \"bigHeadImgUrl\": null,\n \"smallHeadImgUrl\": null\n },\n {\n \"wxid\": \"wxid_0xsqb3o0tsvz22\",\n \"nickName\": \"G\",\n \"inviterUserName\": \"zhangchuan2288\",\n \"memberFlag\": 1,\n \"displayName\": null,\n \"bigHeadImgUrl\": null,\n \"smallHeadImgUrl\": null\n }\n ]\n }\n}","responseId":495312712,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"chatroomId":{"type":"string","description":"群ID"}},"x-apifox-orders":["appId","chatroomId"],"required":["appId","chatroomId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"chatroomId\": \"34757816141@chatroom\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":48,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312712"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"获取群成员列表","api":{"id":"196794527","method":"post","path":"/group/getChatroomMemberList","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312713","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"memberList":{"type":"array","items":{"type":"object","properties":{"wxid":{"type":"string","description":"群成员的wxid"},"nickName":{"type":"string","description":"群成员昵称"},"inviterUserName":{"type":["string","null"],"description":"邀请人的wxid"},"memberFlag":{"type":"integer","description":"标识"},"displayName":{"type":["string","null"],"description":"在本群内的昵称"},"bigHeadImgUrl":{"type":"string","description":"大尺寸头像"},"smallHeadImgUrl":{"type":"string","description":"小尺寸头像"}},"required":["wxid","nickName","inviterUserName","memberFlag","displayName","bigHeadImgUrl","smallHeadImgUrl"],"x-apifox-orders":["wxid","nickName","inviterUserName","memberFlag","displayName","bigHeadImgUrl","smallHeadImgUrl"]},"description":"群成员列表"},"chatroomOwner":{"type":"null","description":"群主的wxid"},"adminWxid":{"type":"null","description":"管理的wxid"}},"required":["memberList","chatroomOwner","adminWxid"],"x-apifox-orders":["memberList","chatroomOwner","adminWxid"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"memberList\": [\n {\n \"wxid\": \"zhangchuan2288\",\n \"nickName\": \"朝夕。\",\n \"inviterUserName\": null,\n \"memberFlag\": 1,\n \"displayName\": null,\n \"bigHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/T0MtLBu618rUlZqaAiaWfucmVibiawiciaSibPfz11siaLZr0qSxQTAR9lu7YicDwYAHNia1je79icxul6bzQ4LLZopiaM9EdYAEublPCLV29QKLv26ictBHjWsWnE0lvYGjibB9DkE6q/0\",\n \"smallHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/T0MtLBu618rUlZqaAiaWfucmVibiawiciaSibPfz11siaLZr0qSxQTAR9lu7YicDwYAHNia1je79icxul6bzQ4LLZopiaM9EdYAEublPCLV29QKLv26ictBHjWsWnE0lvYGjibB9DkE6q/132\"\n },\n {\n \"wxid\": \"wxid_phyyedw9xap22\",\n \"nickName\": \"Ashley\",\n \"inviterUserName\": \"zhangchuan2288\",\n \"memberFlag\": 1,\n \"displayName\": null,\n \"bigHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/5ibSibfNKwpv0TLLuSFv2hibEBqShib4BKsaxHZ2v10y9F93ibO5lK4bwib47qtuwsLZD8HY7fVicibWlWvehCLDCdicy38NaIbVupuMZMDwiaXozjUhk/0\",\n \"smallHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/5ibSibfNKwpv0TLLuSFv2hibEBqShib4BKsaxHZ2v10y9F93ibO5lK4bwib47qtuwsLZD8HY7fVicibWlWvehCLDCdicy38NaIbVupuMZMDwiaXozjUhk/132\"\n },\n {\n \"wxid\": \"wxid_0xsqb3o0tsvz22\",\n \"nickName\": \"G\",\n \"inviterUserName\": \"zhangchuan2288\",\n \"memberFlag\": 2049,\n \"displayName\": \"G1\",\n \"bigHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/FMkteDauMN35F3lhfavibDYpGibfHqrsMICtqBbWDfwfQOnIYfgHBpOJLLbac0Wf3odowXcePFHMzj954EeFOiaKcsgIaMedw5KWZhBpaLsFfSK5HNAE7AQODQ1FfrPiaTCh/0\",\n \"smallHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/FMkteDauMN35F3lhfavibDYpGibfHqrsMICtqBbWDfwfQOnIYfgHBpOJLLbac0Wf3odowXcePFHMzj954EeFOiaKcsgIaMedw5KWZhBpaLsFfSK5HNAE7AQODQ1FfrPiaTCh/132\"\n },\n {\n \"wxid\": \"wxid_8pvka4jg6qzt22\",\n \"nickName\": \"白开水加糖\",\n \"inviterUserName\": \"wxid_phyyedw9xap22\",\n \"memberFlag\": 2049,\n \"displayName\": null,\n \"bigHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/3d34Q9DWL6pHiaASIBMIG3J9deRhwz4yKpZxGibDqiaRGmF6XckV0VSeRTGHSTq55bSwK1qF4Sy1JVXIkB7tYHpR4qPh3ECcodpkqRQjSwKUa4/0\",\n \"smallHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/3d34Q9DWL6pHiaASIBMIG3J9deRhwz4yKpZxGibDqiaRGmF6XckV0VSeRTGHSTq55bSwK1qF4Sy1JVXIkB7tYHpR4qPh3ECcodpkqRQjSwKUa4/132\"\n }\n ],\n \"chatroomOwner\": \"zhangchuan2288\",\n \"adminWxid\": [\n \"wxid_8pvka4jg6qzt22\"\n ]\n }\n}","responseId":495312713,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"chatroomId":{"type":"string","description":"群ID"}},"x-apifox-orders":["appId","chatroomId"],"required":["appId","chatroomId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"chatroomId\": \"34757816141@chatroom\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":54,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312713"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"获取群成员详情","api":{"id":"196794528","method":"post","path":"/group/getChatroomMemberDetail","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312714","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"userName":{"type":"string","description":"群成员的wxid"},"nickName":{"type":"string","description":"群成员的昵称"},"pyInitial":{"type":"string","description":"群成员昵称的拼音首字母"},"quanPin":{"type":"string","description":"群成员昵称的全拼"},"sex":{"type":"integer","description":"性别"},"remark":{"type":["string","null"],"description":"备注"},"remarkPyInitial":{"type":["string","null"],"description":"备注的拼音首字母"},"remarkQuanPin":{"type":["string","null"],"description":"备注的全拼"},"chatRoomNotify":{"type":"integer","description":"消息通知"},"signature":{"type":["string","null"],"description":"签名"},"alias":{"type":["string","null"],"description":"微信号"},"snsBgImg":{"type":"string","description":"朋友圈背景图链接"},"bigHeadImgUrl":{"type":"string","description":"大尺寸头像"},"smallHeadImgUrl":{"type":"string","description":"小尺寸头像"},"description":{"type":"null","description":"描述"},"cardImgUrl":{"type":"null","description":"描述的图片链接"},"labelList":{"type":["string","null"],"description":"标签列表,多个英文逗号分隔"},"country":{"type":"string","description":"国家"},"province":{"type":["string","null"],"description":"省份"},"city":{"type":["string","null"],"description":"城市"},"phoneNumList":{"type":"array","items":{"type":"string"},"description":"手机号码"},"friendUserName":{"type":"string","description":"好友的wxid"},"inviterUserName":{"type":["string","null"],"description":"邀请人的wxid"},"memberFlag":{"type":["integer","null"],"description":"标识"}},"required":["userName","nickName","pyInitial","quanPin","sex","remark","remarkPyInitial","remarkQuanPin","chatRoomNotify","signature","alias","snsBgImg","bigHeadImgUrl","smallHeadImgUrl","description","cardImgUrl","labelList","country","province","city","phoneNumList","friendUserName","inviterUserName","memberFlag"],"x-apifox-orders":["userName","nickName","pyInitial","quanPin","sex","remark","remarkPyInitial","remarkQuanPin","chatRoomNotify","signature","alias","snsBgImg","bigHeadImgUrl","smallHeadImgUrl","description","cardImgUrl","labelList","country","province","city","phoneNumList","friendUserName","inviterUserName","memberFlag"]}}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": [\n {\n \"userName\": \"wxid_0xsqb3o0tsvz22\",\n \"nickName\": \"G\",\n \"pyInitial\": \"G\",\n \"quanPin\": \"G\",\n \"sex\": 0,\n \"remark\": null,\n \"remarkPyInitial\": null,\n \"remarkQuanPin\": null,\n \"chatRoomNotify\": 0,\n \"signature\": null,\n \"alias\": null,\n \"snsBgImg\": \"http://shmmsns.qpic.cn/mmsns/s5BUfupeMYsJx3WHf6RyTxAqLUpGZPsgD9l68D5iaf7qibkcjz08RwNwDxj9ToFvnaicFD2X8CtPe4/0\",\n \"bigHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/tmlG7SpZJMJEh0dA14icl4CWnliaI8pKvVicEMaowRywgVpljBK3nmBib0jHG4eVo5hiaqS7Gg0p7GwCuHopGYqdNBu9WVtxMB8icSFGUjibCDPoGXicPic1r3gx3PQ4YMf3GPfXj/0\",\n \"smallHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/tmlG7SpZJMJEh0dA14icl4CWnliaI8pKvVicEMaowRywgVpljBK3nmBib0jHG4eVo5hiaqS7Gg0p7GwCuHopGYqdNBu9WVtxMB8icSFGUjibCDPoGXicPic1r3gx3PQ4YMf3GPfXj/132\",\n \"description\": null,\n \"cardImgUrl\": null,\n \"labelList\": null,\n \"country\": \"CN\",\n \"province\": \"Guangdong\",\n \"city\": \"Foshan\",\n \"phoneNumList\": null,\n \"friendUserName\": \"wxid_0xsqb3o0tsvz22\",\n \"inviterUserName\": \"zhangchuan2288\",\n \"memberFlag\": 0\n },\n {\n \"userName\": \"wxid_phyyedw9xap22\",\n \"nickName\": \"Ashley\",\n \"pyInitial\": \"ASHLEY\",\n \"quanPin\": \"Ashley\",\n \"sex\": 2,\n \"remark\": \"小号\",\n \"remarkPyInitial\": \"XH\",\n \"remarkQuanPin\": \"xiaohao\",\n \"chatRoomNotify\": 0,\n \"signature\": \"山林不向四季起誓 枯荣随缘。\",\n \"alias\": \"zero-one_200906\",\n \"snsBgImg\": \"http://shmmsns.qpic.cn/mmsns/UaAfqYic92wm7ZCrsEwlQMXSmBLs8dpwBzrXnrOyyP3B8bDibCCFInJ9PicC9LPYY17uWH1yIOmBYQ/0\",\n \"bigHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/buiaXybHTBK3BuGr1edN72zBDermWVFJ7YC8Jib2RcCSdiauAtZcPgUQpdhE9KY5NsumDAWD16fsg3A6OKuhdEr97VAHdTGgk6R1Eibuj7ZNwJ4/0\",\n \"smallHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/buiaXybHTBK3BuGr1edN72zBDermWVFJ7YC8Jib2RcCSdiauAtZcPgUQpdhE9KY5NsumDAWD16fsg3A6OKuhdEr97VAHdTGgk6R1Eibuj7ZNwJ4/132\",\n \"description\": null,\n \"cardImgUrl\": null,\n \"labelList\": \"27\",\n \"country\": \"AD\",\n \"province\": null,\n \"city\": null,\n \"phoneNumList\": [\n \"\\n\\u000b14752126220\"\n ],\n \"friendUserName\": \"wxid_phyyedw9xap22\",\n \"inviterUserName\": null,\n \"memberFlag\": null\n }\n ]\n}","responseId":495312714,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"chatroomId":{"type":"string","description":"群ID"},"memberWxids":{"type":"array","items":{"type":"string","description":"群成员的wxid"}}},"x-apifox-orders":["appId","chatroomId","memberWxids"],"required":["appId","chatroomId","memberWxids"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"chatroomId\": \"34757816141@chatroom\",\n \"memberWxids\": [\n \"wxid_0xsqb3o0tsvz22\",\n \"wxid_phyyedw9xap22\"\n ]\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":60,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312714"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"获取群公告","api":{"id":"196794529","method":"post","path":"/group/getChatroomAnnouncement","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312715","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"announcement":{"type":"string","description":"群公告内容"},"announcementEditor":{"type":"string","description":"群公告作者的wxid"},"publishTime":{"type":"integer","description":"群公告发布时间"}},"required":["announcement","announcementEditor","publishTime"],"x-apifox-orders":["announcement","announcementEditor","publishTime"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"announcement\": \"群公告哈\",\n \"announcementEditor\": \"zhangchuan2288\",\n \"publishTime\": 1703839509\n }\n}","responseId":495312715,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"chatroomId":{"type":"string","description":"群ID"}},"x-apifox-orders":["appId","chatroomId"],"required":["appId","chatroomId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"chatroomId\": \"34757816141@chatroom\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":66,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312715"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"设置群公告","api":{"id":"196794530","method":"post","path":"/group/setChatroomAnnouncement","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312716","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495312716,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"chatroomId":{"type":"string","description":"群ID"},"content":{"type":"string","description":"公告内容"}},"x-apifox-orders":["appId","chatroomId","content"],"required":["appId","chatroomId","content"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"chatroomId\": \"34757816141@chatroom\",\n \"content\": \"群公告哈\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"仅群主或管理员可以发布群公告","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":72,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312716"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"同意进群","api":{"id":"196794531","method":"post","path":"/group/agreeJoinRoom","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312717","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"chatroomId":{"type":"string","description":"群ID"}},"required":["chatroomId"],"x-apifox-orders":["chatroomId"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"chatroomId\": \"19189253160@chatroom\"\n }\n}","responseId":495312717,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"url":{"type":"string","description":"邀请进群回调消息中的url"}},"x-apifox-orders":["appId","url"],"required":["appId","url"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"url\": \"https://support.weixin.qq.com/cgi-bin/mmsupport-bin/addchatroombyinvite?ticket=A%2FtYjg2L%2FGB%2FHYqOwzWNMQ%3D%3D\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":78,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312717"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"添加群成员为好友","api":{"id":"196794532","method":"post","path":"/group/addGroupMemberAsFriend","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312718","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"v3":{"type":"string","description":"添加群成员的v3,通过好友后会通过回调消息返回此值"}},"required":["v3"],"x-apifox-orders":["v3"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"v3\": \"v3_020b3826fd030100000000003a070e7757675c000000501ea9a3dba12f95f6b60a0536a1adb690dcccc9bf58cc80765e6eb16bffa5996420bb1b2577634516ff82090419d8bdcd5689df8dfb21d40af93d286f72c3a0e8cfa6dcb68afed39226f008c6@stranger\"\n }\n}","responseId":495312718,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"chatroomId":{"type":"string","description":"群ID"},"memberWxid":{"type":"string","description":"群成员的wxid"},"content":{"type":"string","description":"加好友的招呼语"}},"x-apifox-orders":["appId","chatroomId","memberWxid","content"],"required":["appId","chatroomId","content","memberWxid"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"chatroomId\": \"34757816141@chatroom\",\n \"content\": \"hallo\",\n \"memberWxid\": \"wxid_phyyedw9xap22\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"添加群成员为好友,若对方关闭从群聊添加的权限则添加失败","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":84,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312718"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"获取群二维码","api":{"id":"196794533","method":"post","path":"/group/getChatroomQrCode","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312719","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"qrBase64":{"type":"string","description":"群二维码图片的base64"},"qrTips":{"type":"string","description":"群二维码的提示"}},"required":["qrBase64","qrTips"],"x-apifox-orders":["qrBase64","qrTips"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"qrBase64\": \"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/wAALCAG4AbgBAREA/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/9oACAEBAAA/AP1Tooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooor+Veiiiiiiv6qK/lXr+qiiiv5V6/qor+Vev6qKKKKK/lXoooooor+qiiiv5V6KK/qoor+Veiv6qKKK/lXr+qiv5V6KKKKKK/qoooooor+Vev6qKKKKK/lXr+qiiiv5V6KKKKKK/qor+Veiiiv6qKK/lXor+qiiv5V6K/qoor+Veiv6qKK/lXr+qiv5V6KK/qor+Vev6qKKKKK/lXr+qiiiiiiv5V6/qor+Veiiv6qK/lXr+qiiv5V6K/qoor+Veiiv6qK/lXor+qiv5V6/qoor+Veiv6qK/lXor+qiiv5V6/qor+Veiv6qKKKKK/lXor+qiv5V6/qor+Veiiv6qK/lXr+qiiiiiiv5V6/qor+Veiiv6qK/lXr+qiiv5V6K/qor+Veiiiv6qKK/lXor+qiiv5V6/qor+Veiiiv6qKK/lXr+qiiiiv5V6KK/qor+Vev6qKK/lXr+qiv5V6KK/qor+Vev6qKKKKKK/lXr+qiv5V6KK/qor+Vev6qK/lXr+qiiv5V6K/qooor+Veiiiv6qKK/lXoooor+qiv5V6KK/qor+Vev6qKK/lXoor+qiiiiv5V6/qor+Veiiv6qK/lXr+qiiiiiiv5V6/qooooor+Vev6qK/lXr+qiv5V6K/qoor+Vev6qK/lXr+qiiv5V6/qoor+Vev6qKKK/lXoor+qiv5V6KK/qoor+Veiv6qK/lXr+qiiiv5V6/qooooor+Vev6qKKKKKK/lXoooooor+qiv5V6/qor+Vev6qK/lXr+qiv5V6/qor+Vev6qK/lXr+qiv5V6/qor+Vev6qK/lXr+qiv5V6/qor+Vev6qK/lXr+qiv5V6/qor+Vev6qK/lXr+qiv5V6/qor+Vev6qK/lXoooooor+qiiiiiiiiiiiiiiiiiiiv5V6/qor+Veiiiv6qKKK/lXr+qiiiv5V6/qor+Veiv6qK/lXr+qiv5V6/qor+Veiv6qK/lXor+qiiiiiiiiiiiiiiiiv5V6KKKKKK/qor+Veiiv6qK/lXooooooor+qiv5V6KKKK/qoooooor+Veiv6qK/lXor+qiv5V6/qooor+Veiv6qKKK/lXr+qiiiiiiv5V6KKK/qor+Vev6qK/lXr+qiiv5V6/qor+Vev6qK/lXoor+qiv5V6K/qor+Veiiv6qKKK/lXr+qiv5V6KK/qooor+Veiiv6qKKK/lXor+qiiv5V6/qooooooooor+Vev6qK/lXoor+qiv5V6/qor+Veiiv6qKKK/lXoor+qiiiv5V6KKK/qor+Veiiv6qKK/lXr+qiiv5V6/qoor+Veiv6qKK/lXor+qiv5V6/qor+Veiiiv6qKKKKKKK/lXoor+qiv5V6/qooor+Vev6qKKKK/lXoor+qiiv5V6/qooooor+Vev6qKK/lXr+qiiv5V6/qoor+Veiiv6qKKK/lXooor+qiiiv5V6/qooooooor+Vev6qK/lXr+qiiv5V6K/qor+Vev6qK/lXoor+qiv5V6K/qor+Vev6qKKKK/lXr+qiiv5V6K/qor+Vev6qK/lXor+qiiv5V6KKK/qor+Veiv6qK/lXor+qiiiiv5V6/qoooooor+Vev6qK/lXoor+qiiiv5V6K/qor+Vev6qKKKK/lXor+qiiiiv5V6KKK/qooor+Veiv6qKKKKK/lXor+qiv5V6/qoor+Vev6qKKK/lXr+qiiiiiiiiv5V6K/qor+Vev6qK/lXoor+qiv5V6K/qor+Vev6qKKK/lXr+qiiv5V6/qor+Veiv6qK/lXoor+qiv5V6/qooooor+Veiiv6qKK/lXoor+qiiv5V6KKKK/qooooooor+Veiiv6qK/lXr+qiv5V6/qoooor+Veiv6qK/lXoor+qiv5V6K/qoor+Vev6qKKK/lXr+qiv5V6/qoooor+Veiiiiiiv6qK/lXr+qiv5V6/qor+Veiiv6qKKKKKK/lXr+qiv5V6/qoor+Veiiiv6qK/lXoooor+qiiv5V6K/qor+Veiiv6qK/lXor+qiiv5V6/qoor+Vev6qK/lXooor+qiv5V6/qoor+Veiv6qKK/lXr+qiiiiiiiiiv5V6/qooor+Vev6qKK/lXr+qiiiiv5V6K/qoor+Vev6qKKKKKK/lXr+qiiiiiv5V6/qoor+Vev6qK/lXr+qiv5V6KKK/qoor+Veiv6qK/lXor+qiiiiiiiiiv5V6/qor+Vev6qK/lXoor+qiiiv5V6K/qooooor+Veiiiiv6qK/lXor+qiiv5V6/qor+Vev6qKK/lXr+qiiiiiiiv5V6KKKK/qor+Veiv6qKKKKKKK/lXr+qiiv5V6/qooor+Vev6qK/lXr+qiv5V6/qor+Veiiiv6qK/lXoor+qiiv5V6K/qoor+Veiv6qK/lXoooor+qiv5V6KK/qoor+Veiiv6qKKKKKKKKKKKKKKK/lXoor+qiv5V6/qor+Vev6qKKKKKK/lXor+qiiv5V6K/qor+Vev6qKK/lXr+qiiv5V6/qoooor+Veiiiiv6qK/lXor+qiiv5V6K/qooooooooor+Vev6qK/lXor+qiiv5V6/qoor+Veiiv6qK/lXoor+qiv5V6KKK/qooor+Veiiiiv6qK/lXr+qiiv5V6K/qoooor+Veiv6qKK/lXr+qiiiiiiiiiv5V6KK/qor+Veiiiiiv6qKK/lXor+qiv5V6KKKK/qor+Veiiiiiv6qKK/lXr+qiv5V6/qoor+Vev6qKKK/lXr+qiv5V6KKKK/qor+Veiiv6qKKKKKKKK/lXoor+qiiiv5V6/qoor+Vev6qK/lXor+qiiiv5V6/qor+Vev6qK/lXr+qiiiv5V6/qooor+Vev6qKK/lXr+qiiv5V6/qoor+Veiv6qKKK/lXr+qiiiv5V6/qoooooooooor+Vev6qK/lXr+qiv5V6K/qoor+Veiv6qK/lXr+qiiv5V6/qoor+Veiv6qK/lXr+qiv5V6K/qor+Veiiv6qKKK/lXoor+qiiv5V6/qor+Vev6qK/lXoor+qiiiiiiiiiiiiv5V6/qooor+Veiiiv6qKKK/lXr+qiiv5V6KKKK/qooor+Vev6qKK/lXor+qiv5V6/qoor+Veiiv6qKK/lXr+qiiiv5V6KKKK/qooooooor+Veiiiiiiiiiv6qKK/lXr+qiv5V6/qor+Vev6qK/lXr+qiv5V6KKKKKK/qoor+Vev6qK/lXor+qiiiv5V6/qoor+Veiiiiiiv6qK/lXr+qiiiiiiv5V6/qooor+Veiv6qK/lXoor+qiv5V6/qor+Veiv6qKK/lXoor+qiv5V6/qor+Vev6qK/lXoor+qiiiiv5V6K/qooor+Veiv6qK/lXor+qiv5V6/qor+Vev6qK/lXor+qiiiiiiv5V6K/qor+Veiiiiv6qK/lXor+qiiiiv5V6K/qoor+Veiiiv6qK/lXor+qiiv5V6KKK/qor+Vev6qK/lXoor+qiv5V6KK/qoooor+Vev6qK/lXr+qiiiiiiv5V6KK/qoooor+Veiiv6qKK/lXoor+qiv5V6KKK/qooor+Vev6qKK/lXooooor+qiv5V6/qor+Vev6qK/lXr+qiiiv5V6/qor+Veiiv6qK/lXr+qiiiiiiiiiiiv5V6KKK/qor+Vev6qKKK/lXr+qiiv5V6/qooooor+Vev6qKK/lXor+qiv5V6K/qoor+Vev6qK/lXoooooooor+qiv5V6KK/qor+Vev6qKKKKKK/lXr+qiv5V6/qor+Veiv6qKKK/lXor+qiv5V6/qor+Veiv6qKK/lXr+qiv5V6KK/qoor+Veiiv6qK/lXr+qiiiiv5V6/qor+Vev6qKK/lXor+qiiv5V6K/qooooooooooooor+Vev6qK/lXor+qiiiiv5V6K/qor+Veiv6qKKK/lXr+qiiv5V6K/qoor+Vev6qK/lXooooooor+qiv5V6/qor+Veiiiiiiiiv6qKKKKKKKK/lXr+qiiiv5V6/qor+Veiiv6qK/lXr+qiv5V6/qoor+Vev6qKK/lXr+qiv5V6K/qor+Vev6qKK/lXooor+qiv5V6/qoooor+Vev6qKK/lXr+qiiv5V6/qooor+Vev6qKKKKKKKK/lXoor+qiv5V6KKKK/qor+Vev6qK/lXr+qiiiiiiv5V6KK/qooooor+Vev6qKK/lXoooor+qiiiiiv5V6K/qor+Veiv6qKK/lXr+qiiiiiiiv5V6KKK/qooooor+Vev6qK/lXr+qiv5V6KK/qooooor+Veiv6qK/lXr+qiv5V6/qor+Vev6qK/lXor+qiiiv5V6K/qooooor+Veiv6qKKKKKKKKKK/lXor+qiv5V6K/qor+Vev6qK/lXr+qiiiv5V6K/qor+Vev6qKKK/lXor+qiv5V6/qor+Vev6qKK/lXr+qiv5V6KK/qooor+Veiv6qK/lXoor+qiiv5V6/qor+Veiiv6qKKKKKKKKK/lXr+qiv5V6K/qor+Vev6qK/lXr+qiiiv5V6/qoooor+Veiv6qKK/lXr+qiiv5V6K/qoor+Veiv6qK/lXr+qiiv5V6KK/qoor+Vev6qKK/lXr+qiv5V6/qor+Vev6qKKKKKKKK/lXr+qiiiv5V6KK/qor+Vev6qK/lXoooor+qiiiiiv5V6K/qooor+Veiiv6qKK/lXr+qiiiiv5V6KKKKKKKK/qooor+Vev6qKKKKKKK/lXoor+qiiiv5V6KK/qooor+Vev6qKKK/lXoor+qiiiiiv5V6KKK/qor+Veiiiv6qK/lXr+qiiiiiv5V6/qor+Vev6qK/lXr+qiv5V6K/qoooooor+Veiiv6qKKK/lXor+qiv5V6K/qor+Vev6qKK/lXooor+qiiv5V6KKKKK/qoor+Veiv6qKKKK/lXoor+qiv5V6KKKKK/qooor+Vev6qKKKKKKKKKKKKKK/lXor+qiv5V6/qoor+Veiiiv6qKK/lXoor+qiiiv5V6K/qoor+Veiiiv6qK/lXor+qiiiv5V6/qooor+Vev6qKKKKKKKKKK/lXoooooor+qiv5V6/qoor+Vev6qK/lXor+qiiv5V6KKKKK/qor+Vev6qK/lXoooor+qiv5V6/qoor+Vev6qK/lXr+qiiv5V6/qor+Vev6qK/lXor+qiiv5V6/qoooooor+Vev6qKKKKK/lXr+qiv5V6/qooor+Vev6qKK/lXor+qiv5V6/qooor+Vev6qKKK/lXor+qiiv5V6/qor+Veiiiiiiiiv6qKKK/lXr+qiiv5V6K/qoooooor+Vev6qK/lXoor+qiv5V6/qor+Vev6qK/lXooor+qiv5V6/qor+Veiv6qKKK/lXoooor+qiiv5V6KK/qor+Vev6qK/lXooooooooor+qiv5V6/qor+Vev6qKKKKKK/lXr+qiv5V6KK/qor+Vev6qK/lXor+qiv5V6/qoooooor+Veiv6qK/lXor+qiiiiiv5V6KK/qor+Vev6qKK/lXr+qiv5V6/qor+Vev6qK/lXor+qiv5V6/qor+Veiiv6qKKKKKK/lXr+qiv5V6KK/qor+Vev6qK/lXr+qiv5V6KKKKKKK/qoor+Veiv6qK/lXor+qiv5V6K/qor+Vev6qKKK/lXor+qiv5V6KK/qor+Veiv6qK/lXr+qiiv5V6KK/qoooooor+Vev6qKKKKK/lXr+qiv5V6K/qoor+Vev6qKK/lXoor+qiv5V6K/qor+Vev6qKKKK/lXr+qiv5V6/qoor+Veiv6qK/lXor+qiiv5V6K/qor+Vev6qK/lXr+qiiiv5V6/qoooooor+Veiiiiiiv6qKK/lXr+qiiv5V6KK/qooor+Vev6qKK/lXoor+qiv5V6K/qoooor+Vev6qKKK/lXoor+qiiv5V6/qoooor+Veiiiv6qKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK//2Q==\",\n \"qrTips\": \"该二维码7天内(1月5日前)有效,重新进入将更新\"\n }\n}","responseId":495312719,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"chatroomId":{"type":"string","description":"群ID"}},"x-apifox-orders":["appId","chatroomId"],"required":["appId","chatroomId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"chatroomId\": \"34757816141@chatroom\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"### 注意\n- 在新设备登录后的1-3天内,无法使用本功能。在此期间,如果尝试进行获取,您将收到来自微信团队的提醒。请注意遵守相关规定。\n- 生成的群二维码图片7天有效","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":90,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312719"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"群保存到通讯录","api":{"id":"196794534","method":"post","path":"/group/saveContractList","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312720","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495312720,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"chatroomId":{"type":"string","description":"群ID"},"operType":{"type":"integer","description":"操作类型 3保存到通讯录 2从通讯录移除"}},"x-apifox-orders":["appId","chatroomId","operType"],"required":["appId","chatroomId","operType"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"chatroomId\": \"34757816141@chatroom\",\n \"operType\": 3\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":96,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312720"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"管理员操作","api":{"id":"196794535","method":"post","path":"/group/adminOperate","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312721","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495312721,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"chatroomId":{"type":"string","description":"群ID"},"operType":{"type":"integer","description":"操作类型 1:添加群管理(可添加多个微信号) 2:删除群管理(可删除多个) 3:转让(只能转让一个微信号)"},"wxids":{"type":"array","items":{"type":"string","description":"群管理的wxid"}}},"x-apifox-orders":["appId","chatroomId","operType","wxids"],"required":["appId","chatroomId","operType","wxids"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"chatroomId\": \"34757816141@chatroom\",\n \"operType\": 1,\n \"wxids\": [\n \"wxid_0xsqb3o0tsvz22\"\n ]\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"添加、删除群管理员,转让群主","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":102,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312721"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"聊天置顶","api":{"id":"196794536","method":"post","path":"/group/pinChat","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312722","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495312722,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"chatroomId":{"type":"string","description":"群ID"},"top":{"type":"boolean","description":"是否置顶"}},"x-apifox-orders":["appId","chatroomId","top"],"required":["appId","chatroomId","top"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"chatroomId\": \"34757816141@chatroom\",\n \"top\": true\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":108,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312722"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"设置消息免打扰","api":{"id":"196794537","method":"post","path":"/group/setMsgSilence","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312723","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495312723,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"chatroomId":{"type":"string","description":"群ID"},"silence":{"type":"boolean","description":"是否免打扰"}},"x-apifox-orders":["appId","chatroomId","silence"],"required":["appId","chatroomId","silence"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"chatroomId\": \"34757816141@chatroom\",\n \"silence\": true\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":114,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312723"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"扫码进群","api":{"id":"196794538","method":"post","path":"/group/joinRoomUsingQRCode","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312724","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"chatroomName":{"type":"string","description":"群名称"},"html":{"type":"null"},"chatroomId":{"type":"string","description":"群ID"}},"required":["chatroomName","html","chatroomId"],"x-apifox-orders":["chatroomName","html","chatroomId"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"chatroomName\": \"GeWe-test-room(2)\",\n \"html\": null,\n \"chatroomId\": \"34559815390@chatroom\"\n }\n}","responseId":495312724,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"qrUrl":{"type":"string","description":"二维码的链接"}},"x-apifox-orders":["appId","qrUrl"],"required":["appId","qrUrl"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"qrUrl\": \"https://weixin.qq.com/g/AwYAALLELoeKLg-qWAtkYtBdyTg_i2TG22w1GS-cL1GFO9J4AemIyZAw7RSuIpZw\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"qrUrl是通过解析群二维码图片获得的内容","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":120,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312724"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"确认进群申请","api":{"id":"196794539","method":"post","path":"/group/roomAccessApplyCheckApprove","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312725","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495312725,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"chatroomId":{"type":"string","description":"群ID"},"newMsgId":{"type":"string","description":"消息ID"},"msgContent":{"type":"string","description":"消息内容"}},"x-apifox-orders":["appId","chatroomId","newMsgId","msgContent"],"required":["appId","chatroomId","msgContent","newMsgId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"chatroomId\": \"34757816141@chatroom\",\n \"msgContent\": \"\\n\\t\\n\\t\\t \\n\\t\\t \\n\\t\\t\\troomaccessapplycheck_approve\\n\\t\\t\\t \\n\\t\\t\\t \\n\\t\\t\\t \\n\\t\\t\\t \\n\\t\\t\\t\\n\\t\\t\\t\\t1\\n\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t \\n\\t\\t\\t\\t\\t \\n\\t\\t\\t\\t\\t \\n\\t\\t\\t\\t\\t \\n\\t\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t \\n\\t\\n\",\n \"newMsgId\": \"8866462780395237368\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"群聊开启邀请确认后,有人申请进群时群主和管理员会收到进群申请,本接口用于确认进群申请","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":126,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312725"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}}]},{"name":"消息模块","id":38391007,"auth":{},"securityScheme":{},"parentId":38391003,"serverId":"","description":"","identityPattern":{"httpApi":{"type":"inherit","bodyType":"","fields":[]}},"shareSettings":{},"visibility":"INHERITED","preProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"postProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"inheritPostProcessors":{},"inheritPreProcessors":{},"items":[{"name":"下载","id":38391015,"auth":{},"securityScheme":{},"parentId":38391007,"serverId":"","description":"","identityPattern":{"httpApi":{"type":"inherit","bodyType":"","fields":[]}},"shareSettings":{},"visibility":"INHERITED","preProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"postProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"inheritPostProcessors":{},"inheritPreProcessors":{},"items":[{"name":"下载图片","api":{"id":"196794561","method":"post","path":"/message/downloadImage","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313347","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"fileUrl":{"type":"string","description":"图片链接地址,7天有效"}},"required":["fileUrl"],"x-apifox-orders":["fileUrl"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"fileUrl\": \"/download/20240720/wx_BTVoJ_o_r6DpxNCNiycFE/0ca5b675-8e2c-4dc1-b288-3c44a40086ec4\"\n }\n}","responseId":495313347,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"xml":{"type":"string","description":"回调消息中的XML"},"type":{"type":"integer","description":"下载的图片类型 1:高清图片 2:常规图片 3:缩略图","default":2}},"x-apifox-orders":["appId","xml","type"],"required":["appId","type","xml"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"type\": 2,\n \"xml\": \"\\n\\n\\t\\n\\t\\n\\t\\n\\t\\n\\t\\t\\n\\t\\t0\\n\\t\\n\\n\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"**注意** 如果下载图片失败,可尝试下载另外两种图片类型,并非所有图片都会有高清、常规图片","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":0,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313347"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}}]},{"name":"发送文字消息","api":{"id":"196794540","method":"post","path":"/message/postText","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312726","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"toWxid":{"type":"string","description":"接收人的wxid"},"createTime":{"type":"integer","description":"发送时间"},"msgId":{"type":"integer","description":"消息ID"},"newMsgId":{"type":"integer","description":"消息ID"},"type":{"type":"integer","description":"消息类型"}},"required":["toWxid","createTime","msgId","newMsgId","type"],"x-apifox-orders":["toWxid","createTime","msgId","newMsgId","type"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"toWxid\": \"34757816141@chatroom\",\n \"createTime\": 1703841160,\n \"msgId\": 0,\n \"newMsgId\": 3768973957878705021,\n \"type\": 1\n }\n}","responseId":495312726,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"toWxid":{"type":"string","description":"好友/群的ID"},"content":{"type":"string","description":"消息内容"},"ats":{"type":"string","description":"@的好友,多个英文逗号分隔。群主或管理员@全部的人,则填写'notify@all'"}},"x-apifox-orders":["appId","toWxid","content","ats"],"required":["appId","toWxid","content"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"toWxid\": \"wxid_tdkou97nquqz22\",\n \"ats\": \"wxid_phyyedw9xap22\",\n \"content\": \"@猿猴 我在测试艾特内容\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"#### 注意\n在群内发送消息@某人时,content中需包含@xxx","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":0,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312726"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"发送文件消息","api":{"id":"196794541","method":"post","path":"/message/postFile","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312727","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"toWxid":{"type":"string","description":"接收人的wxid"},"createTime":{"type":"integer","description":"发送时间"},"msgId":{"type":"integer","description":"消息ID"},"newMsgId":{"type":"integer","description":"消息ID"},"type":{"type":"integer","description":"消息类型"}},"required":["toWxid","createTime","msgId","newMsgId","type"],"x-apifox-orders":["toWxid","createTime","msgId","newMsgId","type"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"toWxid\": \"34757816141@chatroom\",\n \"createTime\": 1703841225,\n \"msgId\": 769523509,\n \"newMsgId\": 4399037329770755951,\n \"type\": 6\n }\n}","responseId":495312727,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"toWxid":{"type":"string","description":"好友/群的ID"},"fileUrl":{"type":"string","description":"文件链接"},"fileName":{"type":"string","description":"文件名"}},"x-apifox-orders":["appId","toWxid","fileUrl","fileName"],"required":["appId","toWxid","fileName","fileUrl"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"toWxid\": \"34757816141@chatroom\",\n \"fileName\": \"a909.xls\",\n \"fileUrl\": \"https://scrm-1308498490.cos.ap-shanghai.myqcloud.com/pkg/a909-99066ce80e03.xls?q-sign-algorithm=sha1&q-ak=AKIDmOkqfDUUDfqjMincBSSAbleGaeQv96mB&q-sign-time=1703841209;1703848409&q-key-time=1703841209;1703848409&q-header-list=&q-url-param-list=&q-signature=2a60b0f8d9169550cd83c4a3ca9cd18138b4bb88\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":6,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312727"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"发送图片消息","api":{"id":"196794542","method":"post","path":"/message/postImage","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312728","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"toWxid":{"type":"string","description":"接收人的wxid"},"createTime":{"type":"integer","description":"发送时间"},"msgId":{"type":"integer","description":"消息ID"},"newMsgId":{"type":"integer","description":"消息ID"},"type":{"type":"null","description":"消息类型"},"aesKey":{"type":"string","description":"cdn相关的aeskey"},"fileId":{"type":"string","description":"cdn相关的fileid"},"length":{"type":"integer","description":"图片文件大小"},"width":{"type":"integer","description":"图片宽度"},"height":{"type":"integer","description":"图片高度"},"md5":{"type":"string","description":"图片md5"}},"required":["toWxid","createTime","msgId","newMsgId","type","aesKey","fileId","length","width","height","md5"],"x-apifox-orders":["toWxid","createTime","msgId","newMsgId","type","aesKey","fileId","length","width","height","md5"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"toWxid\": \"34757816141@chatroom\",\n \"createTime\": 0,\n \"msgId\": 640355969,\n \"newMsgId\": 8992614056172360013,\n \"type\": null,\n \"aesKey\": \"7678796e6d70626e6b626c6f7375616b\",\n \"fileId\": \"3052020100044b30490201000204e49785f102033d11fd0204136166b4020465966eea042437646265323234362d653662662d343464392d393363362d3139313661363863646266390204052418020201000400\",\n \"length\": 1096,\n \"width\": 400,\n \"height\": 400,\n \"md5\": \"e6355eab0393facbd6a2cde3f990ef60\"\n }\n}","responseId":495312728,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"toWxid":{"type":"string","description":"好友/群的ID"},"imgUrl":{"type":"string","description":"图片链接"}},"x-apifox-orders":["appId","toWxid","imgUrl"],"required":["appId","toWxid","imgUrl"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"toWxid\": \"34757816141@chatroom\",\n \"imgUrl\": \"http://dummyimage.com/400x400\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"#### 注意\n发送图片接口会返回cdn相关的信息,如有需求同一张图片发送多次,第二次及以后发送时可使用接口返回的cdn信息拼装xml调用[转发图片接口](https://apifox.com/apidoc/shared-69ba62ca-cb7d-437e-85e4-6f3d3df271b1/api-196794551),这样可以缩短发送时间","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":12,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312728"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"发送语音消息","api":{"id":"196794543","method":"post","path":"/message/postVoice","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312729","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"toWxid":{"type":"string","description":"接收人的wxid"},"createTime":{"type":"integer","description":"发送时间"},"msgId":{"type":"integer","description":"消息ID"},"newMsgId":{"type":"integer","description":"消息ID"},"type":{"type":"integer","description":"消息类型"}},"required":["toWxid","createTime","msgId","newMsgId","type"],"x-apifox-orders":["toWxid","createTime","msgId","newMsgId","type"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"toWxid\": \"34757816141@chatroom\",\n \"createTime\": 1704357563,\n \"msgId\": 640355967,\n \"newMsgId\": 2321462558768366474,\n \"type\": null\n }\n}","responseId":495312729,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"toWxid":{"type":"string","description":"好友/群的ID"},"voiceUrl":{"type":"string","description":"语音文件的链接,仅支持silk格式"},"voiceDuration":{"type":"integer","description":"语音时长,单位毫秒"}},"x-apifox-orders":["appId","toWxid","voiceUrl","voiceDuration"],"required":["appId","toWxid","voiceUrl","voiceDuration"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"toWxid\": \"34757816141@chatroom\",\n \"voiceUrl\": \"https://scrm-1308498490.cos.ap-shanghai.myqcloud.com/pkg/response.silk?q-sign-algorithm=sha1&q-ak=AKIDmOkqfDUUDfqjMincBSSAbleGaeQv96mB&q-sign-time=1703841529;1703848729&q-key-time=1703841529;1703848729&q-header-list=&q-url-param-list=&q-signature=781831fe71ad4bbb582715bf197a9cf86ec80c97\",\n \"voiceDuration\": 2000\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":18,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312729"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"发送视频消息","api":{"id":"196794544","method":"post","path":"/message/postVideo","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312730","code":200,"name":"成功","headers":[],"jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"toWxid":{"type":"string","description":"接收人的wxid"},"createTime":{"type":"null","description":"发送时间"},"msgId":{"type":"integer","description":"消息ID"},"newMsgId":{"type":"integer","description":"消息ID"},"type":{"type":"null","description":"消息类型"},"aesKey":{"type":"string","description":"cdn相关的aeskey"},"fileId":{"type":"string","description":"cdn相关的fileid"},"length":{"type":"integer","description":"视频文件大小"}},"required":["toWxid","createTime","msgId","newMsgId","type","aesKey","fileId","length"],"x-apifox-orders":["toWxid","createTime","msgId","newMsgId","type","aesKey","fileId","length"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"description":"","contentType":"json","mediaType":""}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"toWxid\": \"34757816141@chatroom\",\n \"createTime\": null,\n \"msgId\": 769523567,\n \"newMsgId\": 945590746179451464,\n \"type\": null,\n \"aesKey\": \"687a636f627579667a756a7168717968\",\n \"fileId\": \"3052020100044b304902010002043904752002033d11ff02045dd79b240204658e9072042466633131376136662d366566632d343638662d613633662d3536316139616133383362350204012400040201000400\",\n \"length\": 1315979\n }\n}","responseId":495312730,"ordering":1,"description":"","oasKey":"","oasExtensions":""}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"toWxid":{"type":"string","description":"好友/群的ID"},"videoUrl":{"type":"string","description":"视频的链接"},"thumbUrl":{"type":"string","description":"缩略图的链接"},"videoDuration":{"type":"integer","description":"视频的播放时长,单位秒"}},"x-apifox-orders":["appId","toWxid","videoUrl","thumbUrl","videoDuration"],"required":["appId","toWxid","videoUrl","thumbUrl","videoDuration"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"toWxid\": \"{{toWxid}}\",\n \"videoUrl\": \"https://scrm-1308498490.cos.ap-shanghai.myqcloud.com/1/41734f00f3803ca1cd8f5ad6d5f8d559.mp4?q-sign-algorithm=sha1&q-ak=AKIDmOkqfDUUDfqjMincBSSAbleGaeQv96mB&q-sign-time=1724227372;2588140972&q-key-time=1724227372;2588140972&q-header-list=&q-url-param-list=&q-signature=4e18eb97ab165f27afe0444516e54204f506c7e1\",\n \"thumbUrl\": \"https://scrm-1308498490.cos.ap-shanghai.myqcloud.com/1/logo.jpg?q-sign-algorithm=sha1&q-ak=AKIDmOkqfDUUDfqjMincBSSAbleGaeQv96mB&q-sign-time=1724227462;2588141062&q-key-time=1724227462;2588141062&q-header-list=&q-url-param-list=&q-signature=0bc8b973567d2672e5eaada1b5d466e23ce6b750\",\n \"videoDuration\": 10\n}","mediaType":"application/json"}],"oasExtensions":""},"description":"#### 注意\n发送视频接口会返回cdn相关的信息,如有需求同一个视频发送多次,第二次及以后发送时可使用接口返回的cdn信息拼装xml调用[转发视频接口](https://apifox.com/apidoc/shared-69ba62ca-cb7d-437e-85e4-6f3d3df271b1/api-196794552),这样可以缩短发送时间","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":24,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312730"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"发送链接消息","api":{"id":"196794545","method":"post","path":"/message/postLink","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495312731","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"toWxid":{"type":"string","description":"接收人的wxid"},"createTime":{"type":"integer","description":"发送时间"},"msgId":{"type":"integer","description":"消息ID"},"newMsgId":{"type":"integer","description":"消息ID"},"type":{"type":"integer","description":"消息类型"}},"required":["toWxid","createTime","msgId","newMsgId","type"],"x-apifox-orders":["toWxid","createTime","msgId","newMsgId","type"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"toWxid\": \"34757816141@chatroom\",\n \"createTime\": 1703841982,\n \"msgId\": 769523572,\n \"newMsgId\": 3358797740318930852,\n \"type\": 5\n }\n}","responseId":495312731,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"toWxid":{"type":"string","description":"好友/群的ID"},"title":{"type":"string","description":"链接标题"},"desc":{"type":"string","description":"链接描述"},"linkUrl":{"type":"string","description":"链接地址"},"thumbUrl":{"type":"string","description":"链接缩略图地址"}},"x-apifox-orders":["appId","toWxid","title","desc","linkUrl","thumbUrl"],"required":["appId","toWxid","title","desc","linkUrl","thumbUrl"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"toWxid\": \"34757816141@chatroom\",\n \"title\": \"澳门这一夜\",\n \"desc\": \"39岁郭碧婷用珠圆玉润的身材,狠狠打脸了白幼瘦女星\",\n \"linkUrl\": \"https://mbd.baidu.com/newspage/data/landingsuper?context=%7B%22nid%22%3A%22news_8864265500294006781%22%7D&n_type=-1&p_from=-1\",\n \"thumbUrl\": \"https://pics3.baidu.com/feed/0824ab18972bd407a9403f336648d15c0db30943.jpeg@f_auto?token=d26f7f142871542956aaa13799ba1946\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":30,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495312731"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"发送名片消息","api":{"id":"196794546","method":"post","path":"/message/postNameCard","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313332","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"toWxid":{"type":"string","description":"接收人的wxid"},"createTime":{"type":"integer","description":"发送时间"},"msgId":{"type":"integer","description":"消息ID"},"newMsgId":{"type":"integer","description":"消息ID"},"type":{"type":"integer","description":"消息类型"}},"required":["toWxid","createTime","msgId","newMsgId","type"],"x-apifox-orders":["toWxid","createTime","msgId","newMsgId","type"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"toWxid\": \"34757816141@chatroom\",\n \"createTime\": 1703842036,\n \"msgId\": 0,\n \"newMsgId\": 3285058507819179744,\n \"type\": 42\n }\n}","responseId":495313332,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"toWxid":{"type":"string","description":"好友/群的ID"},"nickName":{"type":"string","description":"名片的昵称"},"nameCardWxid":{"type":"string","description":"名片的wxid"}},"x-apifox-orders":["appId","toWxid","nickName","nameCardWxid"],"required":["appId","toWxid","nickName","nameCardWxid"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"toWxid\": \"34757816141@chatroom\",\n \"nickName\": \"谭艳\",\n \"nameCardWxid\": \"wxid_0xsqb3o0tsvz22\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":36,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313332"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"发送emoji消息","api":{"id":"196794547","method":"post","path":"/message/postEmoji","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313333","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"toWxid":{"type":"string","description":"接收人的wxid"},"createTime":{"type":"integer","description":"发送时间"},"msgId":{"type":"integer","description":"消息ID"},"newMsgId":{"type":"integer","description":"消息ID"},"type":{"type":"integer","description":"消息类型"}},"required":["toWxid","createTime","msgId","newMsgId","type"],"x-apifox-orders":["toWxid","createTime","msgId","newMsgId","type"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"toWxid\": \"34757816141@chatroom\",\n \"createTime\": null,\n \"msgId\": 769523643,\n \"newMsgId\": 891398861855787000,\n \"type\": null\n }\n}","responseId":495313333,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"toWxid":{"type":"string","description":"好友/群的ID"},"emojiMd5":{"type":"string","description":"emoji图片的md5"},"emojiSize":{"type":"integer","description":"emoji的文件大小"}},"x-apifox-orders":["appId","toWxid","emojiMd5","emojiSize"],"required":["appId","toWxid","emojiMd5","emojiSize"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"toWxid\": \"34757816141@chatroom\",\n \"emojiMd5\": \"4cc7540a85b5b6cf4ba14e9f4ae08b7c\",\n \"emojiSize\": 102357\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":42,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313333"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"发送appmsg消息","api":{"id":"196794548","method":"post","path":"/message/postAppMsg","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313334","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"toWxid":{"type":"string","description":"接收人的wxid"},"createTime":{"type":"integer","description":"发送时间"},"msgId":{"type":"integer","description":"消息ID"},"newMsgId":{"type":"integer","description":"消息ID"},"type":{"type":"integer","description":"消息类型"}},"required":["toWxid","createTime","msgId","newMsgId","type"],"x-apifox-orders":["toWxid","createTime","msgId","newMsgId","type"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"toWxid\": \"34757816141@chatroom\",\n \"createTime\": 1703842453,\n \"msgId\": 769523712,\n \"newMsgId\": 3090682956820882425,\n \"type\": 0\n }\n}","responseId":495313334,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"toWxid":{"type":"string","description":"好友/群的ID"},"appmsg":{"type":"string","description":"回调消息中的appmsg节点内容"}},"x-apifox-orders":["appId","toWxid","appmsg"],"required":["appId","toWxid","appmsg"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"toWxid\": \"34757816141@chatroom\",\n \"appmsg\": \"\\n\\t\\t一审宣判!蔡鄂生被判死缓\\n\\t\\t\\n\\t\\t\\n\\t\\t5\\n\\t\\t0\\n\\t\\t0\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t0\\n\\t\\thttp://mp.weixin.qq.com/s?__biz=MjM5MjAxNDM4MA==&mid=2666774093&idx=1&sn=aa405094dd00034d004f6e8287f86e9b&chksm=bcc9d903635a9c284591edda1f027c467245d922d7d66c32d3cd2c6af1c969a7ea0896aa7639&scene=0&xtrack=1#rd\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\t0\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t3057020100044b304902010002048399cc8402032f57ed02041388e6720204658e922d042462666538346165322d303035382d343262322d616538322d3337306231346630323534360204051408030201000405004c53d900\\n\\t\\t\\tea3d5e8d4059cb4db0a3c39c789f2d6f\\n\\t\\t\\t93065\\n\\t\\t\\t1080\\n\\t\\t\\t459\\n\\t\\t\\t849df42ab37c8cadb324fe94ba46d76e\\n\\t\\t\\t849df42ab37c8cadb324fe94ba46d76e\\n\\t\\t\\t0\\n\\t\\t\\n\\t\\t\\n\\t\\tgh_363b924965e9\\n\\t\\t人民日报\\n\\t\\thttps://mmbiz.qpic.cn/sz_mmbiz_jpg/xrFYciaHL08DCJtwQefqrH8JcohbOHhTpyCPab8IgDibkTv3Pspicjw8TRHnoic2tmiafBtUHg7ObZznpWocwkCib6Tw/640?wxtype=jpeg&wxfrom=0\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\t0\\n\\t\\t\\n\\t\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"#### 注意\n本接口可用于发送所有包含节点的消息,例如:音乐分享、视频号、引用消息等等","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":48,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313334"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"发送小程序消息","api":{"id":"196794549","method":"post","path":"/message/postMiniApp","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313335","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"toWxid":{"type":"string","description":"接收人的wxid"},"createTime":{"type":"integer","description":"发送时间"},"msgId":{"type":"integer","description":"消息ID"},"newMsgId":{"type":"integer","description":"消息ID"},"type":{"type":"integer","description":"消息类型"}},"required":["toWxid","createTime","msgId","newMsgId","type"],"x-apifox-orders":["toWxid","createTime","msgId","newMsgId","type"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"toWxid\": \"34757816141@chatroom\",\n \"createTime\": 1704162674,\n \"msgId\": 769533691,\n \"newMsgId\": 3190424380344821399,\n \"type\": 33\n }\n}","responseId":495313335,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"toWxid":{"type":"string","description":"好友/群的ID"},"miniAppId":{"type":"string","description":"小程序ID"},"displayName":{"type":"string","description":"小程序名称"},"pagePath":{"type":"string","description":"小程序打开的地址"},"coverImgUrl":{"type":"string","description":"小程序封面图链接"},"title":{"type":"string","description":"小程序标题"},"userName":{"type":"string","description":"归属的用户ID"}},"x-apifox-orders":["appId","toWxid","miniAppId","displayName","pagePath","coverImgUrl","title","userName"],"required":["appId","toWxid","miniAppId","userName","title","coverImgUrl","pagePath","displayName"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"toWxid\": \"34757816141@chatroom\",\n \"miniAppId\": \"wx1f9ea355b47256dd\",\n \"userName\": \"gh_690acf47ea05@app\",\n \"title\": \"最快29分钟 好吃水果送到家\",\n \"coverImgUrl\": \"https://che-static.vzhimeng.com/img/2023/10/30/67d55942-e43c-4fdb-8396-506794ddbdbc.jpg\",\n \"pagePath\": \"pages/homeDelivery/index.html\",\n \"displayName\": \"百果园+\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":54,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313335"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"转发文件","api":{"id":"196794550","method":"post","path":"/message/forwardFile","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313336","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"toWxid":{"type":"string","description":"接收人的wxid"},"createTime":{"type":"integer","description":"发送时间"},"msgId":{"type":"integer","description":"消息ID"},"newMsgId":{"type":"integer","description":"消息ID"},"type":{"type":"integer","description":"消息类型"}},"required":["toWxid","createTime","msgId","newMsgId","type"],"x-apifox-orders":["toWxid","createTime","msgId","newMsgId","type"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"toWxid\": \"34757816141@chatroom\",\n \"createTime\": 1704162866,\n \"msgId\": 769533740,\n \"newMsgId\": 6455486805605396889,\n \"type\": 6\n }\n}","responseId":495313336,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"toWxid":{"type":"string","description":"好友/群的ID"},"xml":{"type":"string","description":"文件消息的xml"}},"x-apifox-orders":["appId","toWxid","xml"],"required":["appId","toWxid","xml"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"toWxid\": \"34757816141@chatroom\",\n \"xml\": \"\\n\\n\\t\\n\\t\\tinfo.json\\n\\t\\t\\n\\t\\t\\n\\t\\t6\\n\\t\\t0\\n\\t\\t0\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t0\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\t63\\n\\t\\t\\t@cdn_3057020100044b304902010002043904752002032f7d6d02046bb5bade02046593760c042433653765306131612d646138622d346662322d383239362d3964343665623766323061370204051400050201000405004c53d900_f46be643aa0dc009ae5fb63bbc73335d_1\\n\\t\\t\\t\\n\\t\\t\\tjson\\n\\t\\t\\t3057020100044b304902010002043904752002032f7d6d02046bb5bade02046593760c042433653765306131612d646138622d346662322d383239362d3964343665623766323061370204051400050201000405004c53d900\\n\\t\\t\\tf46be643aa0dc009ae5fb63bbc73335d\\n\\t\\t\\t0\\n\\t\\t\\t594239960546299206\\n\\t\\t\\tv1_0bgfyCkUmoZYYyvXys0cCiJdd2R/pKPdD2TNi9IY6FOt+Tvlhp3ijUoupZHzyB2Lp7xYgdVFaUGL4iu3Pm9/YACCt20egPGpT+DKe+VymOzD7tJfsS8YW7JObTbN8eVoFEetU5HSRWTgS/48VVsPZMoDF6Gz1XJDLN/dWRxvzrbOzVGGNvmY4lpXb0kRwXkSxwL+dO4=\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\td16070253eee7173e467dd7237d76f60\\n\\t\\t\\n\\t\\n\\tzhangchuan2288\\n\\t0\\n\\t\\n\\t\\t1\\n\\t\\t\\n\\t\\n\\t\\n\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":60,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313336"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"转发图片","api":{"id":"196794551","method":"post","path":"/message/forwardImage","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313337","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"toWxid":{"type":"string","description":"接收人的wxid"},"createTime":{"type":"integer","description":"发送时间"},"msgId":{"type":"integer","description":"消息ID"},"newMsgId":{"type":"integer","description":"消息ID"},"type":{"type":"null","description":"消息类型"},"aesKey":{"type":"string","description":"cdn相关的aeskey"},"fileId":{"type":"string","description":"cdn相关的fileid"},"length":{"type":"integer","description":"图片文件大小"},"width":{"type":"integer","description":"图片宽度"},"height":{"type":"integer","description":"图片高度"},"md5":{"type":"string","description":"图片md5"}},"required":["toWxid","createTime","msgId","newMsgId","type","aesKey","fileId","length","width","height","md5"],"x-apifox-orders":["toWxid","createTime","msgId","newMsgId","type","aesKey","fileId","length","width","height","md5"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"toWxid\": \"34757816141@chatroom\",\n \"createTime\": 0,\n \"msgId\": 769533749,\n \"newMsgId\": 7003061792458480517,\n \"type\": null,\n \"aesKey\": \"294774c8ac2ca8f8114e4d58d2ba78a5\",\n \"fileId\": \"3057020100044b304902010002043904752002032f7d6d02046bb5bade020465937656042436626431373937632d613430642d346137662d626230352d3832613335353935333130630204051818020201000405004c543d00\",\n \"length\": null,\n \"width\": null,\n \"height\": null,\n \"md5\": null\n }\n}","responseId":495313337,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"toWxid":{"type":"string","description":"好友/群的ID"},"xml":{"type":"string","description":"文件消息的xml"}},"x-apifox-orders":["appId","toWxid","xml"],"required":["appId","toWxid","xml"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"toWxid\": \"34757816141@chatroom\",\n \"xml\": \"\\n\\n\\t\\n\\t\\n\\t\\n\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"#### 注意\n若通过发送图片消息获取cdn信息后可替换xml中的aeskey、cdnthumbaeskey、cdnthumburl、cdnmidimgurl、length、md5等参数来进行转发","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":66,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313337"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"转发视频","api":{"id":"196794552","method":"post","path":"/message/forwardVideo","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313338","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"toWxid":{"type":"string","description":"接收人的wxid"},"createTime":{"type":"null","description":"发送时间"},"msgId":{"type":"integer","description":"消息ID"},"newMsgId":{"type":"integer","description":"消息ID"},"type":{"type":"null","description":"消息类型"},"aesKey":{"type":"string","description":"cdn相关的aeskey"},"fileId":{"type":"string","description":"cdn相关的fileid"},"length":{"type":"integer","description":"视频文件大小"}},"required":["toWxid","createTime","msgId","newMsgId","type","aesKey","fileId","length"],"x-apifox-orders":["toWxid","createTime","msgId","newMsgId","type","aesKey","fileId","length"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"toWxid\": \"34757816141@chatroom\",\n \"createTime\": null,\n \"msgId\": 769533762,\n \"newMsgId\": 2099537549112929261,\n \"type\": null,\n \"aesKey\": \"5c5163d06757faae44eacc2146ba0575\",\n \"fileId\": null,\n \"length\": 490566\n }\n}","responseId":495313338,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"toWxid":{"type":"string","description":"好友/群的ID"},"xml":{"type":"string","description":"文件消息的xml"}},"x-apifox-orders":["appId","toWxid","xml"],"required":["appId","toWxid","xml"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"toWxid\": \"34757816141@chatroom\",\n \"xml\": \"\\n\\n\\t\\n\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"#### 注意\n若通过发送视频消息获取cdn信息后可替换xml中的aeskey、cdnthumbaeskey、cdnvideourl、cdnthumburl、length等参数来进行转发","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":72,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313338"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"转发链接","api":{"id":"196794553","method":"post","path":"/message/forwardUrl","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313339","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"toWxid":{"type":"string","description":"接收人的wxid"},"createTime":{"type":"integer","description":"发送时间"},"msgId":{"type":"integer","description":"消息ID"},"newMsgId":{"type":"integer","description":"消息ID"},"type":{"type":"integer","description":"消息类型"}},"required":["toWxid","createTime","msgId","newMsgId","type"],"x-apifox-orders":["toWxid","createTime","msgId","newMsgId","type"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"toWxid\": \"34757816141@chatroom\",\n \"createTime\": 1704163083,\n \"msgId\": 769533781,\n \"newMsgId\": 1947412320722133720,\n \"type\": 5\n }\n}","responseId":495313339,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"toWxid":{"type":"string","description":"好友/群的ID"},"xml":{"type":"string","description":"文件消息的xml"}},"x-apifox-orders":["appId","toWxid","xml"],"required":["appId","toWxid","xml"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"toWxid\": \"34757816141@chatroom\",\n \"xml\": \"\\n\\n\\t\\n\\t\\t“李在明遇袭,颈部出血”\\n\\t\\t\\n\\t\\t\\n\\t\\t5\\n\\t\\t0\\n\\t\\t0\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t0\\n\\t\\thttp://mp.weixin.qq.com/s?__biz=MjM5MzI5NTU3MQ==&mid=2652294920&idx=1&sn=ad415f5d83e1471b845b2cb3fca7c3ce&chksm=bce58367ee6ae84b711255705422d1554ee96b92d75648751316639d4aa09289d7827ff1cc85&scene=0&xtrack=1#rd\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\t0\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t3057020100044b304902010002048399cc8402032f7d6d020468b5bade0204659376ec042463663234636366642d323736612d343533342d623734342d3864623065633235636135390204051808030201000405004c56f900\\n\\t\\t\\t8e32cafa882f9b4f7c51fb568c0c4f8e\\n\\t\\t\\t38637\\n\\t\\t\\t658\\n\\t\\t\\t280\\n\\t\\t\\taccc71cbe8ff795a94583fc514d198a8\\n\\t\\t\\taccc71cbe8ff795a94583fc514d198a8\\n\\t\\t\\t0\\n\\t\\t\\n\\t\\t\\n\\t\\tgh_d29e0d22a6f9\\n\\t\\t澎湃新闻\\n\\t\\thttps://mmbiz.qpic.cn/mmbiz_jpg/yl6JkZAE3SibWvw5icQJpv87X084SRJOVeS3k7KMscRzov1nwicjMYzicyBIpRdJchWKTGPf4eN2H07Jicl11zMK2Pw/640?wxtype=jpeg&wxfrom=0\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\t0\\n\\t\\t\\n\\t\\n\\tzhangchuan2288\\n\\t0\\n\\t\\n\\t\\t1\\n\\t\\t\\n\\t\\n\\t\\n\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":78,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313339"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"转发小程序","api":{"id":"196794554","method":"post","path":"/message/forwardMiniApp","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313340","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"toWxid":{"type":"string","description":"接收人的wxid"},"createTime":{"type":"integer","description":"发送时间"},"msgId":{"type":"integer","description":"消息ID"},"newMsgId":{"type":"integer","description":"消息ID"},"type":{"type":"integer","description":"消息类型"}},"required":["toWxid","createTime","msgId","newMsgId","type"],"x-apifox-orders":["toWxid","createTime","msgId","newMsgId","type"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"toWxid\": \"34757816141@chatroom\",\n \"createTime\": 1704163145,\n \"msgId\": 769533801,\n \"newMsgId\": 5271007655758710001,\n \"type\": 33\n }\n}","responseId":495313340,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"toWxid":{"type":"string","description":"好友/群的ID"},"xml":{"type":"string","description":"文件消息的xml"},"coverImgUrl":{"type":"string","description":"小程序封面图链接"}},"x-apifox-orders":["appId","toWxid","xml","coverImgUrl"],"required":["appId","toWxid","xml","coverImgUrl"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"toWxid\": \"34757816141@chatroom\",\n \"xml\": \"\\n\\n\\t\\n\\t\\t👇晒出新年第一杯,点赞赢饮茶月卡\\n\\t\\t\\n\\t\\t\\n\\t\\t33\\n\\t\\t0\\n\\t\\t0\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t0\\n\\t\\thttps://mp.weixin.qq.com/mp/waerrpage?appid=wxafec6f8422cb357b&type=upgrade&upgradetype=3#wechat_redirect\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\t0\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t3057020100044b30490201000204573515c902032f7d6d020416b7bade020465922a53042437383139393934652d323662652d346430662d396466362d3466303137346139616362390204051408030201000405004c53d900\\n\\t\\t\\t33cf0a1101e7f8cd3057cd417a691f0b\\n\\t\\t\\t96673\\n\\t\\t\\t600\\n\\t\\t\\t500\\n\\t\\t\\t6f3098f2ee8b351b6cc9b1818d580356\\n\\t\\t\\t6f3098f2ee8b351b6cc9b1818d580356\\n\\t\\t\\t0\\n\\t\\t\\n\\t\\t\\n\\t\\tgh_e9d25e745aae@app\\n\\t\\t霸王茶姬\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t2\\n\\t\\t\\t193\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\t0\\n\\t\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t0\\n\\t\\t\\n\\t\\n\\tzhangchuan2288\\n\\t0\\n\\t\\n\\t\\t1\\n\\t\\t\\n\\t\\n\\t\\n\",\n \"coverImgUrl\": \"http://dummyimage.com/400x400\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":84,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313340"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"撤回消息","api":{"id":"196794555","method":"post","path":"/message/revokeMsg","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313341","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495313341,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"toWxid":{"type":"string","description":"好友/群的ID"},"msgId":{"type":"string","description":"发送类接口返回的msgId"},"newMsgId":{"type":"string","description":"发送类接口返回的newMsgId"},"createTime":{"type":"string","description":"发送类接口返回的createTime"}},"x-apifox-orders":["appId","toWxid","msgId","newMsgId","createTime"],"required":["appId","toWxid","msgId","newMsgId","createTime"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"toWxid\": \"34757816141@chatroom\",\n \"msgId\": \"769533801\",\n \"newMsgId\": \"5271007655758710001\",\n \"createTime\": \"1704163145\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":90,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313341"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}}]},{"name":"标签模块","id":38391009,"auth":{},"securityScheme":{},"parentId":38391003,"serverId":"","description":"","identityPattern":{"httpApi":{"type":"inherit","bodyType":"","fields":[]}},"shareSettings":{},"visibility":"INHERITED","preProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"postProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"inheritPostProcessors":{},"inheritPreProcessors":{},"items":[{"name":"添加标签","api":{"id":"196794583","method":"post","path":"/label/add","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313369","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"labelName":{"type":"string","description":"标签名称"},"labelId":{"type":"integer","description":"标签ID"}},"required":["labelName","labelId"],"x-apifox-orders":["labelName","labelId"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"labelName\": \"testtest\",\n \"labelId\": 31\n }\n}","responseId":495313369,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"labelName":{"type":"string","description":"标签名称"}},"x-apifox-orders":["appId","labelName"],"required":["appId","labelName"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"labelName\": \"testtest\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"#### 注意\n标签名称不存在则是添加标签,如果标签名称已经存在,此接口会直接返回标签名及ID","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":0,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313369"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"删除标签","api":{"id":"196794584","method":"post","path":"/label/delete","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313370","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495313370,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"labelIds":{"type":"string","description":"标签ID,多个逗号分隔"}},"x-apifox-orders":["appId","labelIds"],"required":["appId","labelIds"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"labelIds\": \"31\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":6,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313370"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"标签列表","api":{"id":"196794585","method":"post","path":"/label/list","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313371","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"labelList":{"type":"array","items":{"type":"object","properties":{"labelName":{"type":"string","description":"标签名称"},"labelId":{"type":"integer","description":"标签ID"}},"x-apifox-orders":["labelName","labelId"]}}},"required":["labelList"],"x-apifox-orders":["labelList"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"labelList\": [\n {\n \"labelName\": \"朋友\",\n \"labelId\": 1\n }\n ]\n }\n}","responseId":495313371,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false}},"x-apifox-orders":["appId"],"required":["appId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":12,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313371"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"修改好友标签","api":{"id":"196794586","method":"post","path":"/label/modifyMemberList","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313372","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495313372,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"labelIds":{"type":"string","description":"标签ID,多个逗号分隔"},"wxIds":{"type":"array","items":{"type":"string"},"description":"修改的好友wxid"}},"x-apifox-orders":["appId","labelIds","wxIds"],"required":["appId","wxIds","labelIds"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"labelIds\": \"15\",\n \"wxIds\": [\n \"zhangchuan2288\"\n ]\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"#### 注意\n由于好友标签信息存储在用户客户端,因此每次在修改时都需要进行全量修改。举例来说,考虑好友A(wxid_asdfaihp123),该好友已经被标记为标签ID为1和2。\n\n在添加标签ID为3时,传递的参数如下:labelIds:1,2,3,wxIds:[wxid_asdfaihp123]。这表示要给好友A添加标签ID为3,同时保留已有的标签ID 1和2。\n\n而在删除标签ID为1时,传递的参数如下:labelIds:2,3 ,wxIds:[wxid_asdfaihp123]。这表示要将好友A的标签ID 1删除,而保留标签ID 2。","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":18,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313372"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}}]},{"name":"个人模块","id":38391010,"auth":{},"securityScheme":{},"parentId":38391003,"serverId":"","description":"","identityPattern":{"httpApi":{"type":"inherit","bodyType":"","fields":[]}},"shareSettings":{},"visibility":"INHERITED","preProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"postProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"inheritPostProcessors":{},"inheritPreProcessors":{},"items":[{"name":"获取个人资料","api":{"id":"196794587","method":"post","path":"/personal/getProfile","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313373","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"alias":{"type":"string","description":"微信号"},"wxid":{"type":"string","description":"微信ID"},"nickName":{"type":"string","description":"昵称"},"mobile":{"type":"string","description":"绑定的手机号"},"uin":{"type":"integer","description":"uin"},"sex":{"type":"integer","description":"性别"},"province":{"type":"string","description":"省份"},"city":{"type":"string","description":"城市"},"signature":{"type":"string","description":"签名"},"country":{"type":"string","description":"国家"},"bigHeadImgUrl":{"type":"string","description":"大尺寸头像"},"smallHeadImgUrl":{"type":"string","description":"小尺寸头像"},"regCountry":{"type":"string","description":"注册国家"},"snsBgImg":{"type":"string","description":"朋友圈背景图"}},"required":["alias","wxid","nickName","mobile","uin","sex","province","city","signature","country","bigHeadImgUrl","smallHeadImgUrl","regCountry","snsBgImg"],"x-apifox-orders":["alias","wxid","nickName","mobile","uin","sex","province","city","signature","country","bigHeadImgUrl","smallHeadImgUrl","regCountry","snsBgImg"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"alias\": null,\n \"wxid\": \"zhangchuan2288\",\n \"nickName\": \"朝夕。\",\n \"mobile\": \"18761670817\",\n \"uin\": 1042679712,\n \"sex\": 1,\n \"province\": \"Jiangsu\",\n \"city\": \"Xuzhou\",\n \"signature\": \".......\",\n \"country\": \"CN\",\n \"bigHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/REoLX7KfdibFAgDbtoeXGNjE6sGa8NCib8UaiazlekKjuLneCvicM4xQpuEbZWjjQooSicsKEbKdhqCOCpTHWtnBqdJicJ0I3CgZumwJ6SxR3ibuNs/0\",\n \"smallHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/REoLX7KfdibFAgDbtoeXGNjE6sGa8NCib8UaiazlekKjuLneCvicM4xQpuEbZWjjQooSicsKEbKdhqCOCpTHWtnBqdJicJ0I3CgZumwJ6SxR3ibuNs/132\",\n \"regCountry\": \"CN\",\n \"snsBgImg\": \"http://shmmsns.qpic.cn/mmsns/FzeKA69P5uIdqPfQxp59LvOohoE2iaiaj86IBH1jl0F76aGvg8AlU7giaMtBhQ3bPibunbhVLb3aEq4/0\"\n }\n}","responseId":495313373,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false}},"x-apifox-orders":["appId"],"required":["appId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"proxyIp\": \"\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":0,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313373"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"获取自己的二维码","api":{"id":"196794588","method":"post","path":"/personal/getQrCode","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313374","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"qrCode":{"type":"string","description":"二维码图片的base64"}},"required":["qrCode"],"x-apifox-orders":["qrCode"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"qrCode\": \"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAIAAgADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD5kooor8XP6jCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK1tP03biWUc9lPb61+7FfUYXIaten7SpLlv0tf9UfAZhxdQwlZ0aFP2lt3eyv5aO5+CNFfvdRXZ/q5/wBPv/Jf+CeZ/rv/ANQ3/k//ANqfgjRX73UUf6uf9Pv/ACX/AIIf67/9Q3/k/wD9qfgjRX73UUf6uf8AT7/yX/gh/rv/ANQ3/k//ANqfgjRX73UUf6uf9Pv/ACX/AIIf67/9Q3/k/wD9qfgjRX73UUf6uf8AT7/yX/gh/rv/ANQ3/k//ANqfgjRX73UUf6uf9Pv/ACX/AIIf67/9Q3/k/wD9qfgjRX73UUf6uf8AT7/yX/gh/rv/ANQ3/k//ANqfgjRX73UUf6uf9Pv/ACX/AIIf67/9Q3/k/wD9qfgjRX73UUf6uf8AT7/yX/gh/rv/ANQ3/k//ANqfgjRX73UUf6uf9Pv/ACX/AIIf67/9Q3/k/wD9qfgjRX73UUf6uf8AT7/yX/gh/rv/ANQ3/k//ANqfgjRX73UUf6uf9Pv/ACX/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\"\n }\n}","responseId":495313374,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false}},"x-apifox-orders":["appId"],"required":["appId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"proxyIp\": \"\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":6,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313374"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"获取设备记录","api":{"id":"196794589","method":"post","path":"/personal/getSafetyInfo","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313375","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"list":{"type":"array","items":{"type":"object","properties":{"uuid":{"type":"string","description":"设备ID"},"deviceName":{"type":"string","description":"设备名称"},"deviceType":{"type":"string","description":"设备类型"},"lastTime":{"type":"integer","description":"最后操作时间"}},"required":["uuid","deviceName","deviceType","lastTime"],"x-apifox-orders":["uuid","deviceName","deviceType","lastTime"]},"description":"设备记录"}},"required":["list"],"x-apifox-orders":["list"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"list\": [\n {\n \"uuid\": \"087b139951b776e0416b5015d0b98109\",\n \"deviceName\": \"iPhone 13 Pro\",\n \"deviceType\": \"iPhone iOS17.2\",\n \"lastTime\": 1703218815\n },\n {\n \"uuid\": \"f7e4bda161f7a6a7361ca62141cded23\",\n \"deviceName\": \"张传的MacBook Pro\",\n \"deviceType\": \"iMac MacBookPro17,1 OSX OSX 13.3.1 build(22E261)\",\n \"lastTime\": 1703206819\n },\n {\n \"uuid\": \"80d6218be93f570a971d8c605fa542c3\",\n \"deviceName\": \"iPad\",\n \"deviceType\": \"iPad iOS14.5.1\",\n \"lastTime\": 1703065642\n },\n {\n \"uuid\": \"197e97585d02c9cd6e6de68c74c81780\",\n \"deviceName\": \"iPad\",\n \"deviceType\": \"iPad iOS14.5.1\",\n \"lastTime\": 1701300706\n },\n {\n \"uuid\": \"bf5eb4d8498f4affac1cbfb8aa936d2a\",\n \"deviceName\": \"iPad\",\n \"deviceType\": \"iPad iPadOS14.3\",\n \"lastTime\": 1696729849\n },\n {\n \"uuid\": \"33ac7f39ed3d7115d9c15f07981a264a\",\n \"deviceName\": \"iPad\",\n \"deviceType\": \"iPad iPadOS14.5.1\",\n \"lastTime\": 1695050733\n }\n ]\n }\n}","responseId":495313375,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false}},"x-apifox-orders":["appId"],"required":["appId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"proxyIp\": \"\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":12,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313375"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"隐私设置","api":{"id":"196794590","method":"post","path":"/personal/privacySettings","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313376","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495313376,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"option":{"type":"integer","description":"隐私设置的选项\n 4: 加我为朋友时需要验证\n 7: 向我推荐通讯录朋友\n 8: 添加我的方式 手机号\n 25: 添加我的方式 微信号\n 38: 添加我的方式 群聊\n 39: 添加我的方式 我的二维码\n 40: 添加我的方式 名片"},"open":{"type":"boolean","description":"开关"}},"x-apifox-orders":["appId","option","open"],"required":["appId","open"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"open\": true,\n \"option\": 4\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"**option 说明**\n- 4: 加我为朋友时需要验证\n- 7: 向我推荐通讯录朋友\n- 8: 添加我的方式 手机号\n- 25: 添加我的方式 微信号\n- 38: 添加我的方式 群聊\n- 39: 添加我的方式 我的二维码\n- 40: 添加我的方式 名片","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":18,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313376"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"修改个人信息","api":{"id":"196794591","method":"post","path":"/personal/updateProfile","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313377","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495313377,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"city":{"type":"string","description":"城市"},"country":{"type":"string","description":"国家","mock":{"mock":"@county"}},"nickName":{"type":"string","description":"昵称"},"province":{"type":"string","description":"省份"},"sex":{"type":"string","description":"性别 1:男 2:女"},"signature":{"type":"string","description":"签名"}},"x-apifox-orders":["appId","city","country","nickName","province","sex","signature"],"required":["appId","country","nickName","signature","sex","province"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"city\": \"\",\n \"country\": \"\",\n \"nickName\": \"\",\n \"province\": \"\",\n \"sex\": 1,\n \"signature\": \"......\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"**注意** 修改个人信息需要单独设置每一项\n比如修改昵称则参数仅传appId和nickName\n修改地区则参数可传appId、country、province、city\n","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":24,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313377"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"修改头像","api":{"id":"196794592","method":"post","path":"/personal/updateHeadImg","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313378","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495313378,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"headImgUrl":{"type":"string","description":"头像的图片地址","mock":{"mock":"@image"}}},"x-apifox-orders":["appId","headImgUrl"],"required":["appId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"headImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/REoLX7KfdibFAgDbtoeXGNjE6sGa8NCib8UaiazlekKjuLneCvicM4xQpuEbZWjjQooSicsKEbKdhqCOCpTHWtnBqdJicJ0I3CgZumwJ6SxR3ibuNs/0\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"**注意** 修改头像后需要将手机的微信进程关掉,然后重启查看最新头像","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":30,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313378"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}}]},{"name":"收藏夹模块","id":38391011,"auth":{},"securityScheme":{},"parentId":38391003,"serverId":"","description":"","identityPattern":{"httpApi":{"type":"inherit","bodyType":"","fields":[]}},"shareSettings":{},"visibility":"INHERITED","preProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"postProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"inheritPostProcessors":{},"inheritPreProcessors":{},"items":[{"name":"同步收藏夹","api":{"id":"196794593","method":"post","path":"/favor/sync","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313379","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"syncKey":{"type":"string","description":"翻页key"},"list":{"type":"array","items":{"type":"object","properties":{"favId":{"type":"integer","description":"收藏夹ID"},"type":{"type":"integer","description":"收藏内容类型"},"flag":{"type":"integer","description":"收藏夹标识"},"updateTime":{"type":"integer","description":"收藏时间"}},"required":["favId","type","flag","updateTime"],"x-apifox-orders":["favId","type","flag","updateTime"]}}},"required":["syncKey","list"],"x-apifox-orders":["syncKey","list"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"syncKey\": \"CAESCAgBEJyi9e4C\",\n \"list\": [\n {\n \"favId\": 2,\n \"type\": 1,\n \"flag\": 1,\n \"updateTime\": 1448465918\n },\n {\n \"favId\": 1,\n \"type\": 2,\n \"flag\": 1,\n \"updateTime\": 1448465922\n }\n ]\n }\n}","responseId":495313379,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"syncKey":{"type":"string","description":"翻页key,首次传空,获取下一页传接口返回的syncKey"}},"x-apifox-orders":["appId","syncKey"],"required":["appId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"syncKey\": \"\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"#### 注意:\n响应结果中会包含已删除的的收藏夹记录,通过flag=1来判断已删除\n","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":0,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313379"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"获取收藏夹内容","api":{"id":"196794594","method":"post","path":"/favor/getContent","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313380","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"object","properties":{"favId":{"type":"integer","description":"收藏夹ID"},"status":{"type":"integer","description":"状态"},"flag":{"type":"integer","description":"收藏夹标识"},"updateTime":{"type":"integer","description":"更新时间"},"content":{"type":"string","description":"收藏的内容"}},"required":["favId","status","flag","updateTime","content"],"x-apifox-orders":["favId","status","flag","updateTime","content"]}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"favId\": 179,\n \"status\": 0,\n \"flag\": 0,\n \"updateTime\": 1703235210,\n \"content\": \"没说呢1703217521wxid_cy6buf12nf6921zhangchuan22881838546569535807562127\"\n }\n}","responseId":495313380,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"favId":{"type":"integer","description":"收藏夹ID"}},"x-apifox-orders":["appId","favId"],"required":["appId","favId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"favId\": 179\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":6,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313380"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"删除收藏夹","api":{"id":"196794595","method":"post","path":"/favor/delete","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313383","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495313383,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false},"favId":{"type":"integer","description":"收藏夹ID"}},"x-apifox-orders":["appId","favId"],"required":["appId","favId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\",\n \"favId\": 179\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":12,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313383"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}}]},{"name":"账号管理","id":38391013,"auth":{},"securityScheme":{},"parentId":38391003,"serverId":"","description":"","identityPattern":{"httpApi":{"type":"inherit","bodyType":"","fields":[]}},"shareSettings":{},"visibility":"INHERITED","preProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"postProcessors":[{"id":"inheritProcessors","type":"inheritProcessors","data":{}}],"inheritPostProcessors":{},"inheritPreProcessors":{},"items":[{"name":"断线重连","api":{"id":"196794628","method":"post","path":"/login/reconnection","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"SGfUmgXqCS","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","schema":{"type":"string"},"enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313418","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"扫码但未点确认时的响应","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495313418,"ordering":1},{"name":"登录成功","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": {\n \"uuid\": \"4YHmGvoXvgmS1MqWVtQ2\",\n \"headImgUrl\": \"http://wx.qlogo.cn/mmhead/ver_1/ZYUmcl1UNzyB2onM08Ij901TaUOLIjHj2UicK3XGDsjEWl4XgQN5IjodunHicBVsZiaZc1iaGCRfluAxkzyibbiau3WBfFj2nprzKp2KryicMjGIvDbWOQGmibwVK648a3o4A8hD/0\",\n \"nickName\": \"G\",\n \"expiredTime\": 230,\n \"status\": 2,\n \"loginInfo\": {\n \"uin\": 4077276085,\n \"wxid\": \"wxid_0xsqb3o0tsvz22\",\n \"nickName\": \"G\",\n \"mobile\": \"17114312382\",\n \"alias\": null\n }\n }\n}","responseId":495313418,"ordering":2}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false}},"required":["appId"],"x-apifox-orders":["appId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"- 当系统返回账号已离线,但是手机顶部还显示ipad在线,可用此接口尝试重连,若返回错误/失败则必须重新调用[步骤一登录](https://apifox.com/apidoc/shared-69ba62ca-cb7d-437e-85e4-6f3d3df271b1/api-196794502)\n- 本接口非常用接口,可忽略","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":0,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{}},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313418"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"退出","api":{"id":"196794630","method":"post","path":"/login/logout","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313420","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"}},"required":["ret","msg"],"x-apifox-orders":["ret","msg"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\"\n}","responseId":495313420,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false}},"x-apifox-orders":["appId"],"required":["appId"]},"examples":[{"value":"{\n \"appId\": \"\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":12,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313420"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}},{"name":"检查是否在线","api":{"id":"196794631","method":"post","path":"/login/checkOnline","parameters":{"query":[],"path":[],"cookie":[],"header":[{"id":"ntFeMCw9GJ","name":"X-GEWE-TOKEN","required":true,"description":"","example":"{{gewe-token}}","type":"string","enable":true}]},"auth":{},"securityScheme":{},"commonParameters":{"query":[],"body":[],"cookie":[],"header":[]},"responses":[{"id":"495313421","code":200,"name":"成功","jsonSchema":{"type":"object","properties":{"ret":{"type":"integer"},"msg":{"type":"string"},"data":{"type":"boolean"}},"required":["ret","msg","data"],"x-apifox-orders":["ret","msg","data"]},"contentType":"json"}],"responseExamples":[{"name":"成功示例","data":"{\n \"ret\": 200,\n \"msg\": \"操作成功\",\n \"data\": true\n}","responseId":495313421,"ordering":1}],"requestBody":{"type":"application/json","parameters":[],"jsonSchema":{"type":"object","properties":{"appId":{"type":"string","description":"设备ID","additionalProperties":false}},"x-apifox-orders":["appId"],"required":["appId"]},"examples":[{"value":"{\n \"appId\": \"{{appid}}\"\n}","mediaType":"application/json","description":""}],"oasExtensions":""},"description":"响应结果的data=true则是在线,反之为离线","tags":[],"status":"released","serverId":"","operationId":"","sourceUrl":"","ordering":18,"cases":[],"mocks":[],"customApiFields":"{}","advancedSettings":{"disabledSystemHeaders":{},"isDefaultUrlEncoding":1},"mockScript":{},"codeSamples":[],"commonResponseStatus":{},"responseChildren":["BLANK.495313421"],"visibility":"INHERITED","oasExtensions":null,"preProcessors":[],"postProcessors":[],"inheritPostProcessors":{},"inheritPreProcessors":{}}}]}]}]}],"docCollection":[{"name":"根目录","children":[{"name":"基础API","children":[{"name":"消息模块","children":[],"items":[{"id":4801171,"name":"回调消息详解","sidebarTitle":"","content":"### 回调消息常见问题\n\nQ. **微信在线为什么没有消息推送?**\n```\n当回调消息未能通过 HTTP POST/JSON 方式成功推送至接收方时,请考虑使用 Apifox 向接收地址发送一条测试消息。如果仍然未能接收到消息,请检查接收地址的可用性。反之,若能成功接收测试消息,请联系客服,我们将协助您进行进一步的问题排查。\n```\n\nQ. **如何判断是否是自己发送的消息?**\n```\n可通过消息发送人($.Data.FromUserName.string)与所属微信($.Wxid)是否一致进行判断。\n```\n\nQ. **为什么同一条消息会重复回调?**\n```\n因服务重启、同步历史消息、失败重试等原因,同一条消息可能会重复推送,接收方需根据$.Appid+$.Data.NewMsgId字段做消息排重,以防消息重复处理。\n```\n\n---\n\n#### 文本消息\n```json\n {\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356095, 消息ID\n \"FromUserName\":\n {\n \"string\": \"wxid_phyyedw9xap22\" 消息发送人的wxid\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 1, 消息类型 1是文本消息\n \"Content\":\n {\n \"string\": \"123\" # 消息内容\n },\n \"Status\": 3,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705043418, 消息发送时间\n \"MsgSource\": \"\\n\\t\\n\\t\\t1\\n\\t\\n\\tv1_volHXhv4\\n\\t\\n\\t\\t\\n\\t\\n\\n\", \n \"PushContent\": \"朝夕。 : 123\", 消息通知内容 \n \"NewMsgId\": 7773749793478223190, 消息ID\n \"MsgSeq\": 640356095\n }\n }\n```\n\n\n#### 图片消息\n```json\n{\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356099, 消息ID\n \"FromUserName\":\n {\n \"string\": \"wxid_phyyedw9xap22\" 消息发送人的wxid\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 3, 消息类型 3是图片消息\n \"Content\":\n {\n \"string\": \"\\n\\n\\t\\n\\t\\n\\t\\n\\n\" 图片的cdn信息,可用此字段做转发图片\n },\n \"Status\": 3,\n \"ImgStatus\": 2,\n \"ImgBuf\":\n {\n \"iLen\": 2146,\n \"buffer\": \"/9j/4AAQSkZJRgABAQAASABIAAD/4QBM...\" # 缩略图的base64\n },\n \"CreateTime\": 1705043678, 消息发送时间\n \"MsgSource\": \"\\n\\t\\n\\t\\t2\\n\\t\\n\\t\\n\\t\\t5b04ea0181f86c7f3d126e9a7fe5038b_\\n\\t\\n\\tv1_5WGxwSEj\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"PushContent\": \"朝夕。 : [图片]\", 消息通知内容\n \"NewMsgId\": 6906713067183447582, 消息ID\n \"MsgSeq\": 640356099\n }\n}\n```\n\n#### 语音消息\n```json\n{\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356100, 消息ID\n \"FromUserName\":\n {\n \"string\": \"wxid_phyyedw9xap22\" 消息发送人的wxid\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 34, 消息类型,34是语音消息\n \"Content\":\n {\n \"string\": \"\" 语音消息的下载信息,可用于下载语音文件\n },\n \"Status\": 3,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 3600,\n \"buffer\": \"AiMhU0lMS19WMxMApzi9JA+qToPB...\" 语音文件的base64,并非所有语音消息都有本字段\n },\n \"CreateTime\": 1705043782, 消息发送时间\n \"MsgSource\": \"\\n\\tv1_j+rf/Jnp\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"PushContent\": \"朝夕。 : [语音]\", 消息通知内容\n \"NewMsgId\": 1428830975092239121, 消息ID\n \"MsgSeq\": 640356100\n }\n}\n```\n\n#### 视频消息\n```json\n{\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356101, 消息ID\n \"FromUserName\":\n {\n \"string\": \"wxid_phyyedw9xap22\" 消息发送人的wxid\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 43, 消息类型,43是视频消息\n \"Content\":\n {\n \"string\": \"\\n\\n\\t\\n\\n\" 视频消息的cdn信息,可用此字段做转发视频\n },\n \"Status\": 3,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705043879, 消息发送时间\n \"MsgSource\": \"\\n\\t0\\n\\t\\n\\t\\tce3ebc6d2893c7a2669ac5d2eaa4aadf_\\n\\t\\n\\tv1_kk/psF9W\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"PushContent\": \"朝夕。 : [视频]\", 消息通知内容\n \"NewMsgId\": 6628526085342711793, 消息ID\n \"MsgSeq\": 640356101\n }\n}\n```\n\n#### emoji表情\n```json\n{\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356102, 消息ID\n \"FromUserName\":\n {\n \"string\": \"wxid_phyyedw9xap22\" 消息发送人的wxid\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 47, 消息类型,47是emoji消息\n \"Content\":\n {\n \"string\": \" \" 可解析xml中的md5用与发送emoji消息\n },\n \"Status\": 3,\n \"ImgStatus\": 2,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705043947, 消息发送时间\n \"MsgSource\": \"\\n\\tv1_vy/xC7WS\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"PushContent\": \"朝夕。 : [动画表情]\", 消息通知内容\n \"NewMsgId\": 6674256223577965652, 消息ID\n \"MsgSeq\": 640356102\n }\n}\n```\n\n#### 公众号链接\n- 判断链接消息的逻辑:\\$.Data.MsgType=49 并且 解析\\$.Data.Content.string中的xml msg.appmsg.type=5,按此逻辑会匹配到两种消息,链接消息及邀请进群的通知,可依据xml msg.appmsg.title做区分\n```json\n{\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356105, 消息ID\n \"FromUserName\":\n {\n \"string\": \"wxid_phyyedw9xap22\" 消息发送人的wxid\n }, \n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 49,\n \"Content\":\n {\n \"string\": \"\\n\\n\\t\\n\\t\\t尔滨,又有好消息!\\n\\t\\t\\n\\t\\t\\n\\t\\t5\\n\\t\\t0\\n\\t\\t0\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t0\\n\\t\\thttp://mp.weixin.qq.com/s?__biz=MzA4NDI3NjcyNA==&mid=2650011300&idx=1&sn=52739c3d39c030394da972e3d83efc98&chksm=86ed931f730a3e19a5edc840896d9bf1ad1f8b60cdccafea6a9e7a38a0a33f261877d334622b&scene=0&xtrack=1#rd\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\t0\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t3057020100044b304902010002048399cc8402032f7e350204a810d83a020465a0e829042462343663343435612d333737392d346230612d616434622d6263383038633562643562340204051408030201000405004c53d900\\n\\t\\t\\tadd1b4bcf9cc50c6a8f14ff334bc3d5c\\n\\t\\t\\t83741\\n\\t\\t\\t1000\\n\\t\\t\\t426\\n\\t\\t\\t37889a1e22c1e58ebd4e6589b999f63e\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\tgh_6651e07e4b2d\\n\\t\\t新华社\\n\\t\\thttps://mmbiz.qpic.cn/mmbiz_jpg/azXQmS1HA7mOP6LHArYqZ5ypK4iajvBdfhNxzyANcQ1eW7ec6yZVj7tv8Lt6tWftSNckDz3j4FqkP04TxARG8dQ/640?wxtype=jpeg&wxfrom=0\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\t0\\n\\t\\t\\n\\t\\n\\twxid_phyyedw9xap22\\n\\t0\\n\\t\\n\\t\\t1\\n\\t\\t\\n\\t\\n\\t\\n\\n\" 可用此字段做转发链接\n },\n \"Status\": 3,\n \"ImgStatus\": 2,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705044033, 消息发送时间\n \"MsgSource\": \"\\n\\t\\n\\t\\t\\n\\t\\n\\t\\n\\t\\t4\\n\\t\\n\\t\\n\\t\\tba15c632e8fa89ed84bd027f09495591_\\n\\t\\n\\tv1_ptaEL1bv\\n\\n\",\n \"PushContent\": \"朝夕。 : [链接]尔滨,又有好消息!\", 消息通知内容\n \"NewMsgId\": 1623411326098221490, 消息ID\n \"MsgSeq\": 640356105\n }\n}\n```\n\n#### 文件消息(发送文件的通知)\n- **注意**:收到本条消息仅代表对方在向你发送文件,并不可以用本条做转发及下载\n- 判断此类消息的逻辑:\\$.Data.MsgType=49 并且 解析\\$.Data.Content.string中的xml msg.appmsg.type=74\n```json\n{\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356106, 消息ID\n \"FromUserName\":\n {\n \"string\": \"wxid_phyyedw9xap22\" 消息发送人的wxid\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 49,\n \"Content\":\n {\n \"string\": \"\\n \\n <![CDATA[hhh.xlsx]]>\\n 74\\n 0\\n \\n 8939\\n \\n v1_paVQtd+CWGr2I3eOg71E6KBpQf0yY9RFQkqDPwT4yMnnbawqveao1vAE0qCOhWcIPkMGZavimUTDFcImr+SaManD8pKVQbBPTUvSmA6UsXgZWqQDOT00VLx7U/hoP3/CwveN2Lk56nxcef/XJiGKrOpAHKHcZvccaGk9/68wsBCOyanya/9xgdHTYxyQp4IadiSe\\n 0\\n \\n \\n \\n \\n wxid_phyyedw9xap22\\n\"\n },\n \"Status\": 3,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705044119, 消息发送时间\n \"MsgSource\": \"\\n\\tv1_WyLyIcy+\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"PushContent\": \"朝夕。 : [文件]hhh.xlsx\", 消息通知内容\n \"NewMsgId\": 1789783684714859663, 消息ID\n \"MsgSeq\": 640356106\n }\n}\n```\n\n#### 文件消息(文件发送完成)\n- **注意**:收到本条消息表示对方给你的文件发送完成,可用本条消息做转发及下载\n- 判断此类消息的逻辑:\\$.Data.MsgType=49 并且 解析\\$.Data.Content.string中的xml msg.appmsg.type=6\n```json\n{\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356107, 消息ID\n \"FromUserName\":\n {\n \"string\": \"wxid_phyyedw9xap22\" 消息发送人的wxid\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 49,\n \"Content\":\n {\n \"string\": \"\\n\\n\\t\\n\\t\\thhh.xlsx\\n\\t\\t\\n\\t\\t\\n\\t\\t6\\n\\t\\t0\\n\\t\\t0\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t0\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\t8939\\n\\t\\t\\t@cdn_3057020100044b304902010002043904752002032f7e350204aa0dd83a020465a0e897042430373538386564322d353866642d343234342d386563652d6236353536306438623936610204011800050201000405004c56f900_3f28b0cbd65a86c3a980f3e22808c0fe_1\\n\\t\\t\\t\\n\\t\\t\\txlsx\\n\\t\\t\\t3057020100044b304902010002043904752002032f7e350204aa0dd83a020465a0e897042430373538386564322d353866642d343234342d386563652d6236353536306438623936610204011800050201000405004c56f900\\n\\t\\t\\t3f28b0cbd65a86c3a980f3e22808c0fe\\n\\t\\t\\t0\\n\\t\\t\\t1789783684714859663\\n\\t\\t\\tv1_paVQtd+CWGr2I3eOg71E6KBpQf0yY9RFQkqDPwT4yMnnbawqveao1vAE0qCOhWcIPkMGZavimUTDFcImr+SaManD8pKVQbBPTUvSmA6UsXgZWqQDOT00VLx7U/hoP3/CwveN2Lk56nxcef/XJiGKrOpAHKHcZvccaGk9/68wsBCOyanya/9xgdHTYxyQp4IadiSe\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t84c6737fe9549270c9b3ca4f6fc88f6f\\n\\t\\t\\n\\t\\n\\twxid_phyyedw9xap22\\n\\t0\\n\\t\\n\\t\\t1\\n\\t\\t\\n\\t\\n\\t\\n\\n\"\n },\n \"Status\": 3,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705044119, 消息发送时间\n \"MsgSource\": \"\\n\\t\\n\\t\\t3\\n\\t\\n\\t\\n\\t\\t896374a2b5979141804d509256c22f0b_\\n\\t\\n\\tv1_n7kZ01bp\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"PushContent\": \"朝夕。 : [文件]hhh.xlsx\", 消息通知内容\n \"NewMsgId\": 3617029648443513152, 消息ID\n \"MsgSeq\": 640356107\n }\n}\n```\n\n#### 名片消息\n```json\n {\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356108, 消息ID\n \"FromUserName\":\n {\n \"string\": \"wxid_phyyedw9xap22\" 消息发送人的wxid\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 42, 消息类型,42是名片消息\n \"Content\":\n {\n \"string\": \"\\n\\n\" 名片中微信号的基本信息,可用于添加好友\n },\n \"Status\": 3,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705044829, 消息发送时间\n \"MsgSource\": \"\\n\\t0\\n\\t\\n\\t\\t2\\n\\t\\n\\tv1_bawbB33Z\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"PushContent\": \"朝夕。 : [名片]Ashley\", 消息通知内容\n \"NewMsgId\": 766322251431765776, 消息ID\n \"MsgSeq\": 640356108\n }\n }\n```\n\n#### 好友添加请求通知\n```json\n{\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356166, 消息ID\n \"FromUserName\":\n {\n \"string\": \"fmessage\" 消息发送人的wxid\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 37, 消息类型,37是好友添加请求通知\n \"Content\":\n {\n \"string\": \"\" 请求添加好友微信号的基本信息,可用于添加好友\n },\n \"Status\": 3,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705045979, 消息发送时间\n \"MsgSource\": \"\\n\\tv1_GOrHWRNL\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"NewMsgId\": 1109510141823131559, 消息ID\n \"MsgSeq\": 640356166\n }\n}\n```\n\n#### 好友通过验证及好友资料变更的通知消息\n```json\n{\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\",\n \"TypeName\": \"ModContacts\",\n \"Data\":\n {\n \"UserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\"\n },\n \"NickName\":\n {\n \"string\": \"chaoxi。\"\n },\n \"PyInitial\":\n {\n \"string\": \"CX\"\n },\n \"QuanPin\":\n {\n \"string\": \"chaoxi\"\n },\n \"Sex\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"BitMask\": 4294967295,\n \"BitVal\": 3,\n \"ImgFlag\": 1,\n \"Remark\":\n {},\n \"RemarkPyinitial\":\n {},\n \"RemarkQuanPin\":\n {},\n \"ContactType\": 0,\n \"RoomInfoCount\": 0,\n \"DomainList\": [\n {}],\n \"ChatRoomNotify\": 0,\n \"AddContactScene\": 0,\n \"Province\": \"Jiangsu\",\n \"City\": \"Nanjing\",\n \"Signature\": \"......\",\n \"PersonalCard\": 0,\n \"HasWeiXinHdHeadImg\": 1,\n \"VerifyFlag\": 0,\n \"Level\": 6,\n \"Source\": 14,\n \"WeiboFlag\": 0,\n \"AlbumStyle\": 0,\n \"AlbumFlag\": 3,\n \"SnsUserInfo\":\n {\n \"SnsFlag\": 1,\n \"SnsBgimgId\": \"http://shmmsns.qpic.cn/mmsns/FzeKA69P5uIdqPfQxp59LvOohoE2iaiaj86IBH1jl0F76aGvg8AlU7giaMtBhQ3bPibunbhVLb3aEq4/0\",\n \"SnsBgobjectId\": 14216284872728580667,\n \"SnsFlagEx\": 7297\n },\n \"Country\": \"CN\",\n \"BigHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/qqncCu2avRYruPcQbav3PrwaGSS31QgN6dqW8q1XuDKjgiaAuwoFPw3kN8Cj3zIBL36M93R2Xwib0IddUK3gqbFeezEiaA8K2mMdibT5VUDDrbn7F7M1Mxicmows9cdYNOicjI/0\",\n \"SmallHeadImgUrl\": \"https://wx.qlogo.cn/mmhead/ver_1/qqncCu2avRYruPcQbav3PrwaGSS31QgN6dqW8q1XuDKjgiaAuwoFPw3kN8Cj3zIBL36M93R2Xwib0IddUK3gqbFeezEiaA8K2mMdibT5VUDDrbn7F7M1Mxicmows9cdYNOicjI/132\",\n \"CustomizedInfo\":\n {\n \"BrandFlag\": 0\n },\n \"EncryptUserName\": \"v3_020b3826fd03010000000000feba078fc1e760000000501ea9a3dba12f95f6b60a0536a1adb6f6352c38d0916c9c74045d85aa602efa2d81b84adde05d285124e8a54b9fcd039f725d6ac0d3bd651c7c74503a@stranger\",\n \"AdditionalContactList\":\n {\n \"LinkedinContactItem\":\n {}\n },\n \"ChatroomMaxCount\": 0,\n \"DeleteFlag\": 0,\n \"Description\": \"\\b\\u0000\\u0018\\u0000\\\"\\u0000(\\u00008\\u0000\",\n \"ChatroomStatus\": 0,\n \"Extflag\": 0,\n \"ChatRoomBusinessType\": 0\n }\n}\n```\n\n\n#### 小程序消息\n- 判断此类消息的逻辑:\\$.Data.MsgType=49 并且 解析\\$.Data.Content.string中的xml msg.appmsg.type=33/36\n```json\n{\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356109, 消息ID\n \"FromUserName\":\n { \n \"string\": \"wxid_phyyedw9xap22\" 消息发送人的wxid\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 49,\n \"Content\":\n {\n \"string\": \"\\n\\n\\t\\n\\t\\t腾讯云助手\\n\\t\\t腾讯云助手\\n\\t\\t33\\n\\t\\thttps://mp.weixin.qq.com/mp/waerrpage?appid=wxe2039b83454e49ed&type=upgrade&upgradetype=3#wechat_redirect\\n\\t\\t\\n\\t\\t\\t3057020100044b304902010002048399cc8402032df731020414e461b4020465a0eb8f042463626430353633382d376263632d346161642d396234372d3435613131336339326231640204051808030201000405004c550500\\n\\t\\t\\te1284d4ae13ebd9bb2cde5251cdd05e4\\n\\t\\t\\t52357\\n\\t\\t\\t720\\n\\t\\t\\t576\\n\\t\\t\\td4142726bc730088f0fa44c9161a0992\\n\\t\\t\\td4142726bc730088f0fa44c9161a0992\\n\\t\\t\\t0\\n\\t\\t\\twxid_0xsqb3o0tsvz22_38_1705044879\\n\\t\\t\\n\\t\\tgh_44fc2ced7f87@app\\n\\t\\t腾讯云助手\\n\\t\\te1284d4ae13ebd9bb2cde5251cdd05e4\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t2\\n\\t\\t\\t594\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t0\\n\\t\\t\\t0\\n\\t\\t\\t538\\n\\t\\t\\t0\\n\\t\\t\\t0\\n\\t\\t\\t0\\n\\t\\t\\t0\\n\\t\\t\\n\\t\\n\\twxid_phyyedw9xap22\\n\\t0\\n\\t\\n\\t\\t1\\n\\t\\t\\n\\t\\n\\t\\n\\n\"\n },\n \"Status\": 3,\n \"ImgStatus\": 2,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705044879, 消息发送时间\n \"MsgSource\": \"\\n\\t0\\n\\t\\n\\t\\t2\\n\\t\\n\\t\\n\\t\\tdb46d46fe0a926c4b571dfe9d8096bfa_\\n\\t\\n\\tv1_DkelOoZN\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"PushContent\": \"朝夕。 : [小程序]腾讯云助手\", 消息通知内容\n \"NewMsgId\": 572974861799389774, 消息ID\n \"MsgSeq\": 640356109\n }\n}\n```\n\n#### 引用消息\n- 判断此类消息的逻辑:\\$.Data.MsgType=49 并且 解析\\$.Data.Content.string中的xml msg.appmsg.type=57\n```json\n{\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356110, 消息ID\n \"FromUserName\":\n {\n \"string\": \"wxid_phyyedw9xap22\" 消息发送人的wxid\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 49,\n \"Content\":\n {\n \"string\": \"\\n\\n\\t\\n\\t\\t看看这个\\n\\t\\t\\n\\t\\t\\n\\t\\t57\\n\\t\\t0\\n\\t\\t0\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t0\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\t0\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\t49\\n\\t\\t\\t3617029648443513152\\n\\t\\t\\twxid_phyyedw9xap22\\n\\t\\t\\twxid_phyyedw9xap22\\n\\t\\t\\t朝夕。\\n\\t\\t\\t<msg><appmsg appid=\\\"\\\" sdkver=\\\"0\\\"><title>hhh.xlsx</title><des></des><action></action><type>6</type><showtype>0</showtype><soundtype>0</soundtype><mediatagname></mediatagname><messageext></messageext><messageaction></messageaction><content></content><contentattr>0</contentattr><url></url><lowurl></lowurl><dataurl></dataurl><lowdataurl></lowdataurl><appattach><totallen>8939</totallen><attachid>@cdn_3057020100044b304902010002043904752002032f7e350204aa0dd83a020465a0e897042430373538386564322d353866642d343234342d386563652d6236353536306438623936610204011800050201000405004c56f900_3f28b0cbd65a86c3a980f3e22808c0fe_1</attachid><emoticonmd5></emoticonmd5><fileext>xlsx</fileext><cdnattachurl>3057020100044b304902010002043904752002032f7e350204aa0dd83a020465a0e897042430373538386564322d353866642d343234342d386563652d6236353536306438623936610204011800050201000405004c56f900</cdnattachurl><aeskey>3f28b0cbd65a86c3a980f3e22808c0fe</aeskey><encryver>0</encryver><overwrite_newmsgid>1789783684714859663</overwrite_newmsgid><fileuploadtoken>v1_paVQtd+CWGr2I3eOg71E6KBpQf0yY9RFQkqDPwT4yMnnbawqveao1vAE0qCOhWcIPkMGZavimUTDFcImr+SaManD8pKVQbBPTUvSmA6UsXgZWqQDOT00VLx7U/hoP3/CwveN2Lk56nxcef/XJiGKrOpAHKHcZvccaGk9/68wsBCOyanya/9xgdHTYxyQp4IadiSe</fileuploadtoken></appattach><extinfo></extinfo><sourceusername></sourceusername><sourcedisplayname></sourcedisplayname><thumburl></thumburl><md5>84c6737fe9549270c9b3ca4f6fc88f6f</md5><statextstr></statextstr></appmsg><fromusername></fromusername><appinfo><version>0</version><appname></appname><isforceupdate>1</isforceupdate></appinfo></msg>\\n\\t\\t\\t<msgsource>\\n\\t<alnode>\\n\\t\\t<cf>3</cf>\\n\\t</alnode>\\n\\t<sec_msg_node>\\n\\t\\t<uuid>896374a2b5979141804d509256c22f0b_</uuid>\\n\\t</sec_msg_node>\\n</msgsource>\\n\\n\\t\\t\\n\\t\\n\\twxid_phyyedw9xap22\\n\\t0\\n\\t\\n\\t\\t1\\n\\t\\t\\n\\t\\n\\t\\n\\n\"\n },\n \"Status\": 3,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705044946, 消息发送时间\n \"MsgSource\": \"\\n\\t\\n\\t\\tea25ade83dc4b9ec91060ca3e1a0f5a2_\\n\\t\\n\\tv1_oTWRYdd1\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"PushContent\": \"看看这个\", 消息通知内容\n \"NewMsgId\": 4334300109515885085, 消息ID\n \"MsgSeq\": 640356110\n }\n}\n```\n\n#### 转账消息\n- 判断此类消息的逻辑:\\$.Data.MsgType=49 并且 解析\\$.Data.Content.string中的xml msg.appmsg.type=2000\n```json\n {\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356112, 消息ID\n \"FromUserName\":\n {\n \"string\": \"wxid_phyyedw9xap22\" 消息发送人的wxid\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 49,\n \"Content\":\n {\n \"string\": \"\\n\\n<![CDATA[微信转账]]>\\n\\n\\n2000\\n\\n\\n\\n\\n\\n\\n\\n1\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\"\n },\n \"Status\": 3,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705044984, 消息发送时间\n \"MsgSource\": \"\\n\\tv1_eDcIna+F\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"PushContent\": \"朝夕。 : [转账]\", 消息通知内容\n \"NewMsgId\": 7290406378327063279, 消息ID\n \"MsgSeq\": 640356112\n }\n }\n```\n\n#### 红包消息\n- 判断此类消息的逻辑:\\$.Data.MsgType=49 并且 解析\\$.Data.Content.string中的xml msg.appmsg.type=2001\n```json\n {\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356113, 消息ID\n \"FromUserName\":\n {\n \"string\": \"wxid_phyyedw9xap22\" 消息发送人的wxid\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 49,\n \"Content\":\n {\n \"string\": \"\\n\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t<![CDATA[微信红包]]>\\n\\t\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t微信红包\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\n\\t\\n\\n\"\n },\n \"Status\": 3,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705045011, 消息发送时间\n \"MsgSource\": \"\\n\\t\\n\\t\\n\\tv1_Js6wJde/\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"PushContent\": \"朝夕。 : [红包]恭喜发财,大吉大利\", 消息通知内容\n \"NewMsgId\": 5517720959405775296, 消息ID\n \"MsgSeq\": 640356113\n }\n }\n```\n\n#### 视频号消息\n- 判断此类消息的逻辑:\\$.Data.MsgType=49 并且 解析\\$.Data.Content.string中的xml msg.appmsg.type=51\n```json\n {\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356115, 消息ID\n \"FromUserName\":\n {\n \"string\": \"wxid_phyyedw9xap22\" 消息发送人的wxid\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 49,\n \"Content\":\n {\n \"string\": \"\\n\\n\\t\\n\\t\\t当前微信版本不支持展示该内容,请升级至最新版本。\\n\\t\\t\\n\\t\\t\\n\\t\\t51\\n\\t\\t0\\n\\t\\t0\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t0\\n\\t\\thttps://support.weixin.qq.com/update/\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\t0\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\n\\t\\t\\t14264358459626428566\\n\\t\\t\\t4\\n\\t\\t\\t国风锦鲤\\n\\t\\t\\thttps://wx.qlogo.cn/finderhead/ver_1/x2LxetmLmgoo9jp69R3wcrtZ0LBLdjVv9vrK9HmPNGEdD1iawdrPffPvMmFUez8pWqRIfs7DtgPiaV5C7DZpibH8b3y0jG178aIict6uPf0Vht4/0\\n\\t\\t\\t还招人么?我不要工资#逆水寒cos\\n\\t\\t\\t1\\n\\t\\t\\t8046877030770906689_0_0_0_0_0\\n\\t\\t\\t0\\n\\t\\t\\tv2_060000231003b20faec8cae08b19c7d2c702e834b077fb74f482543ff67f0cc66363057a5443@finder\\n\\t\\t\\t\\n\\t\\t\\t0\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t4\\n\\t\\t\\t\\t\\thttp://wxapp.tc.qq.com/251/20302/stodownload?encfilekey=Cvvj5Ix3eez3Y79SxtvVL0L7CkPM6dFibFeI6caGYwFFDAZJzcvicKz3jic4UfNeiaWTwH9gTlYiafAxVkMZRXicBUBk2Ms7lauAj6SArUu0P9ddKiaa8IWZzYaaKLf1WddH4G8T0KicxQV3hQPH3pQgEMTscw&a=1&bizid=1023&dotrans=0&hy=SH&idx=1&m=4c4c7f3ed03a14a6b99d0d19176c12ac&upid=290110\\n\\t\\t\\t\\t\\thttp://wxapp.tc.qq.com/251/20304/stodownload?encfilekey=oibeqyX228riaCwo9STVsGLPj9UYCicgttvO59vjtcQ7Jviaia0q4bnpVP2ia7ibqzacPo0z4nIRtWom80ZXwL64icZO2q6ibVBQLZQftMwU3SHj5uplsIFroHeF0QNcCkXX3RtibaWCHJQjfqZUk&bizid=1023&dotrans=0&hy=SH&idx=1&m=7522250b4d15e5df866bf23da9f117d6&token=oA9SZ4icv8IssuhLtacX13nAzXiaf8y52juKW4ibUDN7a2vn71bbrCR0LZiabddvTsLLMvnELnuAwNxViclRT7wT9IyibzFw1pq9wdichRYaEmb6Js&ctsc=2-20\\n\\t\\t\\t\\t\\t1080\\n\\t\\t\\t\\t\\t1920\\n\\t\\t\\t\\t\\thttp://wxapp.tc.qq.com/251/20304/stodownload?encfilekey=oibeqyX228riaCwo9STVsGLPj9UYCicgttvO59vjtcQ7Jviaia0q4bnpVP2ia7ibqzacPo0z4nIRtWom80ZXwL64icZO2q6ibVBQLZQftMwU3SHj5uplsIFroHeF0QNcCkXX3RtibaWCHJQjfqZUk&bizid=1023&dotrans=0&hy=SH&idx=1&m=7522250b4d15e5df866bf23da9f117d6&token=oA9SZ4icv8IssuhLtacX13nAzXiaf8y52juKW4ibUDN7a2vn71bbrCR0LZiabddvTsLLMvnELnuAwNxViclRT7wT9IyibzFw1pq9wdichRYaEmb6Js&ctsc=2-20\\n\\t\\t\\t\\t\\thttp://wxapp.tc.qq.com/251/20350/stodownload?encfilekey=oibeqyX228riaCwo9STVsGLPj9UYCicgttv1FCQXwResqN75zI4n65zY5tkAficEPWbbClq2VcicqMYaSLK7nrAVMasrIhvsCXJib5cOLib98JgWPr4SP92W6YEkVN5Uv0TKAdyRryQ3Qxk7jU&bizid=1023&dotrans=0&hy=SH&idx=1&m=731b89683dd3cb866cdf96dab70ac183&token=KkOFht0mCXlnmicFbJnvymIJOEfZgzia8PY0ZzOdaIYTJXwfblvK4U1ibntribm1beupHwictGWs9hpMiclyhfSb6766Lnb3ib0j14bENm6u1tHpeo&ctsc=3-20\\n\\t\\t\\t\\t\\t10>>\\n\\t\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\n\\twxid_phyyedw9xap22\\n\\t0\\n\\t\\n\\t\\t1\\n\\t\\t\\n\\t\\n\\t\\n\\n\"\n },\n \"Status\": 3,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705045057, 消息发送时间\n \"MsgSource\": \"\\n\\t\\n\\t\\t\\n\\t\\n\\t\\n\\t\\t4\\n\\t\\n\\t\\n\\t\\tbb2cbd9d3290e7a3d35f183eaade2213_\\n\\t\\n\\tv1_+Tfo41HS\\n\\n\",\n \"PushContent\": \"你收到了一条消息\", 消息通知内容\n \"NewMsgId\": 5576224237104747184, 消息ID\n \"MsgSeq\": 640356115\n }\n }\n```\n\n#### 撤回消息\n- 判断此类消息的逻辑:\\$.Data.MsgType=10002 并且 解析\\$.Data.Content.string中的xml sysmsg.type=revokemsg\n```json\n {\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356116, 消息ID\n \"FromUserName\":\n {\n \"string\": \"wxid_phyyedw9xap22\" 消息发送人的wxid\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 10002,\n \"Content\":\n {\n \"string\": \"wxid_phyyedw9xap2210403561155576224237104747184\"\n },\n \"Status\": 3,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705045083, 消息发送时间\n \"MsgSource\": \"\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"NewMsgId\": 1968256046, 消息ID\n \"MsgSeq\": 640356116\n }\n }\n```\n\n#### 拍一拍消息\n- 判断此类消息的逻辑:\\$.Data.MsgType=10002 并且 解析\\$.Data.Content.string中的xml sysmsg.type=pat\n```json\n{\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356117, 消息ID\n \"FromUserName\":\n {\n \"string\": \"wxid_phyyedw9xap22\" 消息发送人的wxid\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 10002,\n \"Content\":\n {\n \"string\": \"\\n\\n wxid_phyyedw9xap22\\n wxid_0xsqb3o0tsvz22\\n wxid_0xsqb3o0tsvz22\\n \\n 0\\n\\n\\n\\n\\n \\n\\n\\n\\n\\n\\n\"\n },\n \"Status\": 3,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705045115, 消息发送时间\n \"MsgSource\": \"\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"NewMsgId\": 5709690173850254331, 消息ID\n \"MsgSeq\": 640356117\n }\n}\n```\n\n#### 地理位置\n```json\n{\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356118, 消息ID\n \"FromUserName\":\n {\n \"string\": \"wxid_phyyedw9xap22\" 消息发送人的wxid\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 48, 消息类型,48是地理位置消息\n \"Content\":\n {\n \"string\": \"\\n\\n\\t\\n\\n\"\n },\n \"Status\": 3,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705045153, 消息发送时间\n \"MsgSource\": \"\\n\\t0\\n\\tv1_KgQA8C+H\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"PushContent\": \"朝夕。分享了一个地理位置\", 消息通知内容\n \"NewMsgId\": 2112726776406556053, 消息ID\n \"MsgSeq\": 640356118\n }\n}\n```\n\n#### 群聊邀请\n- 判断此类消息的逻辑:\\$.Data.MsgType=49 并且 解析\\$.Data.Content.string中的xml msg.appmsg.title=邀请你加入群聊(根据手机设置的系统语言title会有调整,不同语言关键字不同)\n```json\n{\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356119, 消息ID\n \"FromUserName\":\n {\n \"string\": \"wxid_phyyedw9xap22\" 消息发送人的wxid\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 49, \n \"Content\": \n {\n \"string\": \"<![CDATA[邀请你加入群聊]]>view500\"\n },\n \"Status\": 3,\n \"ImgStatus\": 0,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705045206, 消息发送时间\n \"MsgSource\": \"\\n\\tv1_uHiWbihr\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"NewMsgId\": 2331390497668538400, 消息ID\n \"MsgSeq\": 640356119\n }\n}\n```\n\n#### 被移除群聊通知\n- 判断此类消息的逻辑:\\$.Data.MsgType=10000 并且 \\$.Data.Content.string内容为移除群聊的通知内容\n```json\n{\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356153, 消息ID\n \"FromUserName\":\n {\n \"string\": \"39238473509@chatroom\" 所在群聊的ID\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 10000,\n \"Content\":\n {\n \"string\": \"你被\\\"朝夕。\\\"移出群聊\"\n },\n \"Status\": 4,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705045790, 消息发送时间\n \"MsgSource\": \"\\n\\tv1_f7Xny9H/\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"NewMsgId\": 5759605552965664254, 消息ID\n \"MsgSeq\": 640356153\n }\n}\n```\n\n#### 踢出群聊通知\n- 判断此类消息的逻辑:\\$.Data.MsgType=10002 并且 解析\\$.Data.Content.string中的xml sysmsg.type=sysmsgtemplate 并且 template中的内容为“你将xxx移出了群聊”(根据手机设置的系统语言template会有调整,不同语言关键字不同)\n```json\n{\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356143, 消息ID\n \"FromUserName\":\n {\n \"string\": \"34757816141@chatroom\" 所在群聊的ID\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 10002,\n \"Content\":\n {\n \"string\": \"34757816141@chatroom:\\n\\n\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\n\\n\"\n },\n \"Status\": 4,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705045666, 消息发送时间\n \"MsgSource\": \"\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"NewMsgId\": 7100572668516374210, 消息ID\n \"MsgSeq\": 640356143\n }\n}\n```\n\n#### 解散群聊通知\n- 判断此类消息的逻辑:\\$.Data.MsgType=10002 并且 解析\\$.Data.Content.string中的xml sysmsg.type=sysmsgtemplate 并且 template中的内容为“群主xxx已解散该群聊”(根据手机设置的系统语言template会有调整,不同语言关键字不同)\n```json\n{\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356158, 消息ID\n \"FromUserName\":\n {\n \"string\": \"39238473509@chatroom\" 所在群聊的ID\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 10002,\n \"Content\":\n {\n \"string\": \"39238473509@chatroom:\\n\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n\"\n },\n \"Status\": 4,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705045834, 消息发送时间\n \"MsgSource\": \"\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"NewMsgId\": 6869316888754169027, 消息ID\n \"MsgSeq\": 640356158\n }\n}\n```\n\n#### 修改群名称\n- 判断此类消息的逻辑:\\$.Data.MsgType=10000 并且 \\$.Data.Content.string为修改群名的通知内容\n```json\n{\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356129, 消息ID\n \"FromUserName\":\n {\n \"string\": \"34757816141@chatroom\" 所在群聊的ID\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 10000,\n \"Content\":\n {\n \"string\": \"你修改群名为“GeWe test1”\"\n },\n \"Status\": 4,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705045517, 消息发送时间\n \"MsgSource\": \"\\n\\tv1_3uPmlxJG\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"NewMsgId\": 6984814725261047392, 消息ID\n \"MsgSeq\": 640356129\n }\n}\n```\n\n#### 更换群主通知\n- 判断此类消息的逻辑:\\$.Data.MsgType=10000 并且 \\$.Data.Content.string为更换群主的通知内容\n```json\n {\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356125, 消息ID\n \"FromUserName\":\n {\n \"string\": \"34757816141@chatroom\" 所在群聊的ID\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 消息接收人的wxid\n },\n \"MsgType\": 10000,\n \"Content\":\n {\n \"string\": \"你已成为新群主\"\n },\n \"Status\": 4,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705045441, 消息发送时间\n \"MsgSource\": \"\\n\\tv1_iqIx6JkV\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"NewMsgId\": 7268255507978211143, 消息ID\n \"MsgSeq\": 640356125\n }\n }\n```\n\n#### 群信息变更通知\n```json\n{\n \"TypeName\": \"ModContacts\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"UserName\":\n {\n \"string\": \"34757816141@chatroom\" 所在群聊的ID\n },\n \"NickName\":\n {\n \"string\": \"GeWe test\"\n },\n \"PyInitial\":\n {\n \"string\": \"GEWETEST\"\n },\n \"QuanPin\":\n {\n \"string\": \"GeWetest\"\n },\n \"Sex\": 0,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"BitMask\": 4294967295,\n \"BitVal\": 2,\n \"ImgFlag\": 1,\n \"Remark\":\n {},\n \"RemarkPyinitial\":\n {},\n \"RemarkQuanPin\":\n {},\n \"ContactType\": 0,\n \"RoomInfoCount\": 0,\n \"DomainList\": [\n {}],\n \"ChatRoomNotify\": 1,\n \"AddContactScene\": 0,\n \"PersonalCard\": 0,\n \"HasWeiXinHdHeadImg\": 0,\n \"VerifyFlag\": 0,\n \"Level\": 0,\n \"Source\": 0,\n \"ChatRoomOwner\": \"wxid_0xsqb3o0tsvz22\",\n \"WeiboFlag\": 0,\n \"AlbumStyle\": 0,\n \"AlbumFlag\": 0,\n \"SnsUserInfo\":\n {\n \"SnsFlag\": 0,\n \"SnsBgobjectId\": 0,\n \"SnsFlagEx\": 0\n },\n \"CustomizedInfo\":\n {\n \"BrandFlag\": 0\n },\n \"AdditionalContactList\":\n {\n \"LinkedinContactItem\":\n {}\n },\n \"ChatroomMaxCount\": 700000019,\n \"DeleteFlag\": 2,\n \"Description\": \"\\b\\u0004\\u0012\\u0017\\n\\u000Ewxid_phyyedw9xap220\\u0001@\\u0000�\\u0001\\u0000\\u0012\\u001B\\n\\u0012wxid_phyyedw9xap220\\u0001@\\u0000�\\u0001\\u0000\\u0012\\u001C\\n\\u0013wxid_0xsqb3o0tsvz220\\u0001@\\u0000�\\u0001\\u0000\\u0012\\u001D\\n\\u0013wxid_8pvka4jg6qzt220�\\u0010@\\u0000�\\u0001\\u0000\\u0018\\u0001\\\"\\u0000(\\u00008\\u0000\",\n \"ChatroomStatus\": 27,\n \"Extflag\": 0,\n \"ChatRoomBusinessType\": 0\n }\n}\n``` \n\n#### 发布群公告\n- 判断此类消息的逻辑:\\$.Data.MsgType=10002 并且 解析\\$.Data.Content.string中的xml sysmsg.type=mmchatroombarannouncememt\n```json\n{\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356133, 消息ID\n \"FromUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\" 发布人的wxid\n },\n \"ToUserName\":\n {\n \"string\": \"34757816141@chatroom\" 所在群聊的ID\n },\n \"MsgType\": 10002,\n \"Content\":\n {\n \"string\": \"\\n \\n \\n \\n\\t1705045558\\n\\t127\\n\\t1\\n\\t\\n\\t\\twxid_0xsqb3o0tsvz22\\n\\t\\t34757816141@chatroom\\n\\t\\t7c79fed82a0037648954bba6d5ca2025\\n\\t\\n\\t\\n\\t\\t\\n\\t\\t\\t.htm\\n\\t\\t\\thttp://wxapp.tc.qq.com/264/20303/stodownload?m=145a874d4eb1bb0b85af928331a168aa&filekey=3033020101041f301d02020108040253480410145a874d4eb1bb0b85af928331a168aa020120040d00000004627466730000000132&hy=SH&storeid=265a0ee36000a9c94f3064bb50000010800004f4f534825960b01e676a0b3b&bizid=1023\\n\\t\\t\\t24808ae91ac7d636c99a1b340a1f9253\\n\\t\\t\\t8fac8374ded0d5e8d5038b1ec2b77a62\\n\\t\\t\\tef033738f28bb3c80cd5e7290fdbfdcf\\n\\t\\t\\tef033738f28bb3c80cd5e7290fdbfdcf\\n\\t\\t\\t20\\n\\t\\t\\n\\t\\t\\n\\t\\t\\t群公告哈1\\n\\t\\t\\t\\n\\t\\t\\n\\t\\n\\t\\n\\t\\t\\n\\t\\t\\t-1\\n\\t\\t\\n\\t\\n\\twxid_0xsqb3o0tsvz22_34757816141@chatroom_1705045558_2028281562\\n\\n]]>\\n \\n \\n\"\n },\n \"Status\": 3,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705045559, 消息发送时间\n \"MsgSource\": \"\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"NewMsgId\": 8056409355261218186, 消息ID\n \"MsgSeq\": 640356133\n }\n}\n```\n\n#### 群待办\n- 判断此类消息的逻辑:\\$.Data.MsgType=10002 并且 解析\\$.Data.Content.string中的xml sysmsg.type=roomtoolstips\n```json\n {\n \"TypeName\": \"AddMsg\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"MsgId\": 1040356135, 消息ID\n \"FromUserName\":\n {\n \"string\": \"34757816141@chatroom\" 所在群聊的ID\n },\n \"ToUserName\":\n {\n \"string\": \"wxid_0xsqb3o0tsvz22\"\n },\n \"MsgType\": 10002,\n \"Content\":\n {\n \"string\": \"34757816141@chatroom:\\n\\n\\n 0\\n\\n \\n \\n \\n \\n \\n <![CDATA[群公告]]>\\n \\n \\n \\n 0\\n \\n \\n \\n \\n\\n\\n \\n\\n\\n \\n \\n \\n \\n \\n \\n \\n\\n \\n\\n \\n\\n\\n\"\n },\n \"Status\": 4,\n \"ImgStatus\": 1,\n \"ImgBuf\":\n {\n \"iLen\": 0\n },\n \"CreateTime\": 1705045591, 消息发送时间\n \"MsgSource\": \"\\n\\t\\n\\t\\t\\n\\t\\n\\n\",\n \"NewMsgId\": 1765700414095721113, 消息ID\n \"MsgSeq\": 640356135\n }\n }\n```\n\n#### 删除好友通知\n```json\n{\n \"TypeName\": \"DelContacts\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"UserName\":\n {\n \"string\": \"wxid_phyyedw9xap22\" 删除的好友wxid\n },\n \"DeleteContactScen\": 0\n }\n}\n```\n\n#### 退出群聊\n```json\n{\n \"TypeName\": \"DelContacts\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\", 所属微信的wxid\n \"Data\":\n {\n \"UserName\":\n {\n \"string\": \"34559815390@chatroom\" 退出的群聊ID\n },\n \"DeleteContactScen\": 0\n }\n}\n```\n\n#### 掉线通知\n```json\n{\n \"TypeName\": \"Offline\", 消息类型\n \"Appid\": \"wx_wR_U4zPj2M_OTS3BCyoE4\", 设备ID\n \"Wxid\": \"wxid_phyyedw9xap22\" 掉线号的wxid\n}\n```\n","folderId":38391007,"type":"","tags":[],"visibility":"INHERITED"}]}],"items":[]}],"items":[]}],"webSocketCollection":[],"socketIOCollection":[],"responseCollection":[],"schemaCollection":[],"securitySchemeCollection":[],"requestCollection":[{"name":"根目录","children":[],"ordering":["requestFolder.3591746","requestFolder.5085392"],"items":[]}],"environments":[],"globalVariables":[],"commonParameters":null,"customFunctions":[],"projectAssociations":[]} \ No newline at end of file diff --git a/gewechat/call_back_message/Gewechat.md b/gewechat/call_back_message/Gewechat.md deleted file mode 100644 index 99ab43b..0000000 --- a/gewechat/call_back_message/Gewechat.md +++ /dev/null @@ -1,4616 +0,0 @@ ---- -title: Gewechat -language_tabs: - - shell: Shell - - http: HTTP - - javascript: JavaScript - - ruby: Ruby - - python: Python - - php: PHP - - java: Java - - go: Go -toc_footers: [] -includes: [] -search: true -code_clipboard: true -highlight_theme: darkula -headingLevel: 2 -generator: "@tarslib/widdershins v4.0.30" - ---- - -# Gewechat - -Base URLs: - -# Authentication - -# 基础API/登录模块 - -## POST 获取登录二维码(步骤2) - -POST /login/getLoginQrCode - -- appId参数为设备ID,首次登录传空,会自动触发创建设备,掉线后重新登录则必须传接口返回的appId,注意**同一个号避免重复创建设备**,以免触发官方风控 -- **取码时传的appId需要与上次登录扫码的微信一致,否则会导致登录失败** -- 响应结果中的qrImgBase64为微信二维码图片的base64,前端需要**将二维码图片展示给用户并进行手机扫码操作**(PS: **扫码后调用步骤2,手机上才显示登录**)。(或使用响应结果中的qrData生成二维码) - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID,首次登录传空,之后传接口返回的appId| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "appId": "wx_wR_U4zPj2M_OTS3BCyoE4", - "qrData": "http://weixin.qq.com/x/4dmHZZMtoLbHoLZwd1wE", - "qrImgBase64": "data:image/jpg;base64,XXX", - "uuid": "4dmHZZMtoLbHoLZwd1wE" - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||响应数据| -|»» qrData|string|true|none||二维码内包含的信息(可用二维码生成工具结合值生成可扫描的微信二维码)| -|»» appId|string|true|none||设备ID| -|»» qrImgBase64|string|true|none||二维码图片base64| -|»» uuid|string|true|none||二维码的uuid| - -## POST 获取Token(步骤1) - -POST /tools/getTokenId - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": "" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|string|true|none||token| - -## POST 执行登录(步骤3) - -POST /login/checkLogin - -- 获取到登录二维码后需每间隔5s调用本接口来判断是否登录成功 -- 新设备登录平台,次日凌晨会掉线一次,重新登录时需调用[获取二维码且传appId取码](/apidoc/shared-69ba62ca-cb7d-437e-85e4-6f3d3df271b1/api-196794502),登录成功后则可以长期在线 -- 登录成功后请保存appId与wxid的对应关系,后续接口中会用到 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "uuid": "IZDexGAEu9_6JkDX0pX-" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» uuid|body|string| 是 |取码返回的uuid| -|» captchCode|body|string| 是 |扫码后手机提示输入的验证码| - -> 返回示例 - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "uuid": "AZ0yN8d1wJmiNfQBKFgu", - "headImgUrl": "http://wx.qlogo.cn/mmhead/ver_1/ZYUmcl1UNzyB2onM08Ij901TaUOLIjHj2UicK3XGDsjEWl4XgQN5IjodunHicBVsZiaZc1iaGCRfluAxkzyibbiau3WBfFj2nprzKp2KryicMjGIvDbWOQGmibwVK648a3o4A8hD/0", - "nickName": "G", - "expiredTime": 225, - "status": 1, - "loginInfo": null - } -} -``` - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "uuid": "4YHmGvoXvgmS1MqWVtQ2", - "headImgUrl": "http://wx.qlogo.cn/mmhead/ver_1/ZYUmcl1UNzyB2onM08Ij901TaUOLIjHj2UicK3XGDsjEWl4XgQN5IjodunHicBVsZiaZc1iaGCRfluAxkzyibbiau3WBfFj2nprzKp2KryicMjGIvDbWOQGmibwVK648a3o4A8hD/0", - "nickName": "G", - "expiredTime": 230, - "status": 2, - "loginInfo": { - "uin": 4077276085, - "wxid": "wxid_0xsqb3o0tsvz22", - "nickName": "G", - "mobile": "17114312382", - "alias": null - } - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||响应数据| -|»» uuid|string|true|none||二维码的uuid| -|»» headImgUrl|string|true|none||头像地址| -|»» nickName|string|true|none||昵称| -|»» expiredTime|integer|true|none||二维码超时时间| -|»» status|integer|true|none||状态| -|»» loginInfo|object|true|none||登录成功信息| -|»»» uin|integer|true|none||uin| -|»»» wxid|string|true|none||微信ID,返回此值则是登录成功| -|»»» nickName|string|true|none||昵称| -|»»» mobile|string|true|none||绑定的手机号| -|»»» alias|string|true|none||微信号| - -## POST 设置消息回调地址 - -POST /tools/setCallback - -> Body 请求参数 - -```json -{ - "token": "{{gewe-token}}", - "callbackUrl": "http://www.baidu.com" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» token|body|string| 是 |token| -|» callbackUrl|body|string| 是 |回调接收地址| - -> 返回示例 - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "uuid": "4YHmGvoXvgmS1MqWVtQ2", - "headImgUrl": "http://wx.qlogo.cn/mmhead/ver_1/ZYUmcl1UNzyB2onM08Ij901TaUOLIjHj2UicK3XGDsjEWl4XgQN5IjodunHicBVsZiaZc1iaGCRfluAxkzyibbiau3WBfFj2nprzKp2KryicMjGIvDbWOQGmibwVK648a3o4A8hD/0", - "nickName": "G", - "expiredTime": 230, - "status": 2, - "loginInfo": { - "uin": 4077276085, - "wxid": "wxid_0xsqb3o0tsvz22", - "nickName": "G", - "mobile": "17114312382", - "alias": null - } - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 查看设备列表 - -POST /login/deviceList - -> Body 请求参数 - -```json -{} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| - -> 返回示例 - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": [ - "wx_YQFamjNEfV1LFFl9TRYVb" - ] -} -``` - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "uuid": "4YHmGvoXvgmS1MqWVtQ2", - "headImgUrl": "http://wx.qlogo.cn/mmhead/ver_1/ZYUmcl1UNzyB2onM08Ij901TaUOLIjHj2UicK3XGDsjEWl4XgQN5IjodunHicBVsZiaZc1iaGCRfluAxkzyibbiau3WBfFj2nprzKp2KryicMjGIvDbWOQGmibwVK648a3o4A8hD/0", - "nickName": "G", - "expiredTime": 230, - "status": 2, - "loginInfo": { - "uin": 4077276085, - "wxid": "wxid_0xsqb3o0tsvz22", - "nickName": "G", - "mobile": "17114312382", - "alias": null - } - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|[string]|true|none||none| - -# 基础API/联系人模块 - -## POST 获取通讯录列表 - -POST /contacts/fetchContactsList - -- 本接口为长耗时接口,耗时时间根据好友数量递增,若接口返回超时可通过[获取通讯录列表缓存接口](https://apifox.com/apidoc/shared-69ba62ca-cb7d-437e-85e4-6f3d3df271b1/api-196794505)获取响应结果 -- 本接口返回的群聊仅为[保存到通讯录中的群聊](https://zhidao.baidu.com/question/144774265918920605/answer/4326874247.html),若想获取会话列表中的所有群聊,需要通过[消息订阅](https://apifox.com/apidoc/shared-69ba62ca-cb7d-437e-85e4-6f3d3df271b1/api-196884570)做二次处理。原因:当未获取的群有成员在群内发消息的话会有消息回调, 开发者此刻调用[获取群详情接口](https://apifox.com/apidoc/shared-69ba62ca-cb7d-437e-85e4-6f3d3df271b1/api-196794513)查询群信息入库保存即可,比如说手机上三年前不说话的群,侧滑删除了,用户手机上也不会看到被删除的群聊的 ,但是有群成员说了话他会显示,原理就是各个终端(Android、IOS、桌面版微信)取得了消息回调,又去获取群详情信息,本地数据库缓存了下来,显示的手机群聊,让用户感知的。 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "friends": [ - "tmessage", - "medianote", - "qmessage", - "qqmail", - "wxid_910acevfm2nb21", - "qqsafe", - "wxid_9299552988412", - "weixin", - "exmail_tool", - "wxid_mp05xmje0ctn22", - "wxid_09oq4f4j4wg912", - "wxid_6bfguz79h8n122", - "wxid_lyuq4hr4lrjq22", - "wxid_a1zqyljsrsdu12", - "wxid_lv3pb3zhna3522", - "wxid_k2biq6fuinsr22", - "wxid_ujredjhxz9y712", - "wxid_uwb7989u0jea12", - "wxid_in46ey732vxu12", - "wxid_3rvervwohj6921", - "wxid_4wkls7tu62ua12", - "wxid_g0bdknnotx2f12", - "wxid_ce5fgp0icb3y21", - "wxid_1482424825211", - "wxid_vw3p4f6jy7bm12", - "wxid_o2m8xm71c23522", - "wxid_bclqpc2ho6o412", - "wxid_98pjjzpiisi721", - "wxid_noq2wsn5c8h222" - ], - "chatrooms": [ - "2180313478@chatroom", - "14358945067@chatroom", - "17362526147@chatroom", - "11685224357@chatroom", - "17522822550@chatroom" - ], - "ghs": [ - "gh_7aac992b0363", - "gh_d7293b5f14f4", - "gh_f51ce3ef83a4", - "gh_7d20df86e26b", - "gh_69bfb92a3e43" - ] - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» friends|[string]|true|none||好友的wxid| -|»» chatrooms|[string]|true|none||保存到通讯录中群聊的ID| -|»» ghs|[string]|true|none||关注的公众号ID| - -## POST 获取通讯录列表缓存 - -POST /contacts/fetchContactsListCache - -通讯录列表数据缓存10分钟,超时则需要重新调用[获取通讯录列表接口](https://apifox.com/apidoc/shared-69ba62ca-cb7d-437e-85e4-6f3d3df271b1/api-196794504) - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 搜索好友 - -POST /contacts/search - -搜索的联系人信息若已经是好友,响应结果的v3则为好友的wxid -本接口返回的数据可通过[添加联系人接口](https://apifox.com/apidoc/shared-69ba62ca-cb7d-437e-85e4-6f3d3df271b1/api-196794507)发送添加好友请求 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "contactsInfo": "zhangch" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» contactsInfo|body|string| 是 |搜索的联系人信息,微信号、手机号...| - -> 返回示例 - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "v3": "v3_020b3826fd030100000000006c20217514f7f2000000501ea9a3dba12f95f6b60a0536a1adb690dcccc9bf58cc80765e6eb16bc2678a36a0ed264e1b22596f787de6acc71a4beb20b69ab88bfd6d71aa1858b3@stranger", - "nickName": "zhang", - "sex": 1, - "signature": "学习、成长、锻炼", - "bigHeadImgUrl": "http://wx.qlogo.cn/mmhead/ver_1/yoYJGtDmGicz9QGOFRb71Ns6onQO63bnfJibicBwEmO73m18N7BicrGzeYsdxOrUf5qwJq9mMaQbDwEBA92uPOuibZg/0", - "smallHeadImgUrl": "http://wx.qlogo.cn/mmhead/ver_1/yoYJGtDmGicz9QGOFRb71Ns6onQO63bnfJibicBwEmO73m18N7BicrGzeYsdxOrUf5qwJq9mMaQbDwEBA92uPOuibZg/132", - "v4": "v4_000b708f0b04000001000000000056d3690365e0eefe00ef467a8e651000000050ded0b020927e3c97896a09d47e6e9ec65e1f9d32b06f86df4790587a6308149b3c8a90185e824efccd5b41bd75f6240ab020f9dd4b5915a083c6784a5cfcb806f53ca340b4c95b24f474d6e3fc0661301b3b3b741aac3eb5@stranger" - } -} -``` - -```json -{ - "ret": 500, - "msg": "搜索联系人失败", - "data": { - "code": "-4", - "msg": "用户不存在" - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» v3|string|true|none||搜索好友的v3,添加好友时使用| -|»» nickName|string|true|none||搜索好友的昵称| -|»» sex|integer|true|none||搜索好友的性别| -|»» signature|null|true|none||搜索好友的签名| -|»» bigHeadImgUrl|string|true|none||搜索好友的大尺寸头像| -|»» smallHeadImgUrl|string|true|none||搜索好友的小尺寸头像| -|»» v4|string|true|none||搜索好友的v4,添加好友时使用| - -## POST 添加联系人/同意添加好友 - -POST /contacts/addContacts - -本接口建议在线3天后再进行调用。 -好友添加成功后,会通过回调消息推送一条包含v3的消息,可用于判断好友是否添加成功。 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "scene": 3, - "content": "hallo", - "v4": "v4_000b708f0b04000001000000000054a9e826263634356493c57b8e651000000050ded0b020927e3c97896a09d47e6e9e455d674c2544e251e77c7cba08cc6cef8f7df9e52d2bd4a3cef771c8661331fa1939fbe54f4e479d6d9d4522d70aeba057ffd0dd82398730da44ee57332a7bdea4862304d4799758ba@stranger", - "v3": "v3_020b3826fd030100000000003a070e7757675c000000501ea9a3dba12f95f6b60a0536a1adb690dcccc9bf58cc80765e6eb16bffa5996420bb1b2577634516ff82090419d8bdcd5689df8dfb21d40af93d286f72c3a0e8cfa6dcb68afed39226f008c6@stranger", - "option": 2 -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» scene|body|integer| 是 |添加来源,同意添加好友时传回调消息xml中的scene值。| -|» option|body|integer| 是 |操作类型,2添加好友 3同意好友 4拒绝好友| -|» v3|body|string| 是 |通过搜索或回调消息获取到的v3| -|» v4|body|string| 是 |通过搜索或回调消息获取到的v4| -|» content|body|string| 是 |添加好友时的招呼语| - -#### 详细说明 - -**» scene**: 添加来源,同意添加好友时传回调消息xml中的scene值。 -添加好友时的枚举值如下: -3 :微信号搜索 -4 :QQ好友 -8 :来自群聊 -15:手机号 - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 删除好友 - -POST /contacts/deleteFriend - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "wxid": "wxid_phyyedw9xap22" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» wxid|body|string| 是 |删除好友的wxid| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 上传手机通讯录 - -POST /contacts/uploadPhoneAddressList - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "phones": [ - "18616561632", - "18134173174" - ], - "opType": 1 -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» phones|body|[string]| 是 |需要上传的手机号| -|» opType|body|integer| 是 |操作类型,1:上传 2:删除| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 获取群/好友简要信息 - -POST /contacts/getBriefInfo - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "wxids": [ - "wxid_phyyedw9xap22" - ] -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» wxids|body|[string]| 是 |好友的wxid| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "获取联系人信息成功", - "data": [ - { - "userName": "wxid_phyyedw9xap22", - "nickName": "Ashley", - "pyInitial": "ASHLEY", - "quanPin": "Ashley", - "sex": 2, - "remark": "", - "remarkPyInitial": "", - "remarkQuanPin": "", - "signature": null, - "alias": "zero-one_200906", - "snsBgImg": null, - "country": "AD", - "bigHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/buiaXybHTBK3BuGr1edN72zBDermWVFJ7YC8Jib2RcCSdiauAtZcPgUQpdhE9KY5NsumDAWD16fsg3A6OKuhdEr97VAHdTGgk6R1Eibuj7ZNwJ4/0", - "smallHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/buiaXybHTBK3BuGr1edN72zBDermWVFJ7YC8Jib2RcCSdiauAtZcPgUQpdhE9KY5NsumDAWD16fsg3A6OKuhdEr97VAHdTGgk6R1Eibuj7ZNwJ4/132", - "description": null, - "cardImgUrl": null, - "labelList": "", - "province": "", - "city": "", - "phoneNumList": null - } - ] -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|[object]|true|none||none| -|»» userName|string|false|none||none| -|»» nickName|string|false|none||none| -|»» pyInitial|string|false|none||none| -|»» quanPin|string|false|none||none| -|»» sex|integer|false|none||none| -|»» remark|string|false|none||none| -|»» remarkPyInitial|string|false|none||none| -|»» remarkQuanPin|string|false|none||none| -|»» signature|null|false|none||none| -|»» alias|string|false|none||none| -|»» snsBgImg|null|false|none||none| -|»» country|string|false|none||none| -|»» bigHeadImgUrl|string|false|none||none| -|»» smallHeadImgUrl|string|false|none||none| -|»» description|null|false|none||none| -|»» cardImgUrl|null|false|none||none| -|»» labelList|string|false|none||none| -|»» province|string|false|none||none| -|»» city|string|false|none||none| -|»» phoneNumList|null|false|none||none| - -## POST 获取群/好友详细信息 - -POST /contacts/getDetailInfo - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "wxids": [ - "yc-081726" - ] -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» wxids|body|[string]| 是 |好友的wxid| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "获取联系人信息成功", - "data": [ - { - "userName": "wxid_phyyedw9xap22", - "nickName": "Ashley", - "pyInitial": null, - "quanPin": "Ashley", - "sex": 2, - "remark": null, - "remarkPyInitial": null, - "remarkQuanPin": null, - "signature": "山林不向四季起誓 枯荣随缘。", - "alias": "zero-one_200906", - "snsBgImg": "http://shmmsns.qpic.cn/mmsns/UaAfqYic92wm7ZCrsEwlQMXSmBLs8dpwBzrXnrOyyP3B8bDibCCFInJ9PicC9LPYY17uWH1yIOmBYQ/0", - "country": "AD", - "bigHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/buiaXybHTBK3BuGr1edN72zBDermWVFJ7YC8Jib2RcCSdiauAtZcPgUQpdhE9KY5NsumDAWD16fsg3A6OKuhdEr97VAHdTGgk6R1Eibuj7ZNwJ4/0", - "smallHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/buiaXybHTBK3BuGr1edN72zBDermWVFJ7YC8Jib2RcCSdiauAtZcPgUQpdhE9KY5NsumDAWD16fsg3A6OKuhdEr97VAHdTGgk6R1Eibuj7ZNwJ4/132", - "description": null, - "cardImgUrl": null, - "labelList": null, - "province": null, - "city": null, - "phoneNumList": null - } - ] -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|[object]|true|none||none| -|»» userName|string|false|none||好友的wxid| -|»» nickName|string|false|none||好友的昵称| -|»» pyInitial|null|false|none||好友昵称的拼音首字母| -|»» quanPin|string|false|none||好友昵称的全拼| -|»» sex|integer|false|none||好友的性别| -|»» remark|null|false|none||好友备注| -|»» remarkPyInitial|null|false|none||好友备注的拼音首字母| -|»» remarkQuanPin|null|false|none||好友备注的全拼| -|»» signature|string|false|none||好友的签名| -|»» alias|string|false|none||好友的微信号| -|»» snsBgImg|string|false|none||朋友圈背景图链接| -|»» country|string|false|none||国家| -|»» bigHeadImgUrl|string|false|none||大尺寸头像链接| -|»» smallHeadImgUrl|string|false|none||小尺寸头像链接| -|»» description|null|false|none||好友的描述| -|»» cardImgUrl|null|false|none||好友描述的图片链接| -|»» labelList|null|false|none||好友的标签ID| -|»» province|null|false|none||省份| -|»» city|null|false|none||城市| -|»» phoneNumList|null|false|none||好友的手机号码| - -## POST 设置好友仅聊天 - -POST /contacts/setFriendPermissions - -设置完好友仅聊天后若发现手机展示不是设置的结果,可能是手机缓存未刷新,重新进入页面刷新查看 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "wxid": "wxid_phyyedw9xap22", - "onlyChat": true -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» wxid|body|string| 是 |好友的wxid| -|» onlyChat|body|boolean| 是 |设置好友是否仅聊天| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "设置好友权限成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 设置好友备注 - -POST /contacts/setFriendRemark - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "wxid": "wxid_phyyedw9xap22", - "remark": "备注" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» wxid|body|string| 是 |好友的wxid| -|» remark|body|string| 是 |备注的备注| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "设置好友权限成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 获取手机通讯录 - -POST /contacts/getPhoneAddressList - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "phones": [] -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» phones|body|[string]| 否 |获取哪些手机号的好友详情,不传获取所有| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "获取手机通讯录成功", - "data": [ - { - "userName": "wxid_ddgsghdfafaphh22", - "v4": null, - "nickName": null, - "sex": 1, - "phoneMd5": "d36f4cc1c8bca1ef41b93d2215133cdb", - "signature": "......", - "alias": null, - "country": "CN", - "bigHeadImgUrl": "http://wx.qlogo.cn/mmhead/ver_1/vwGdLRK5jtpXagA7dfXlUiaU9VayWNSqia1c2Wib7icJNhPd6WHhqMIVuYuNDfEqPRC2TnmlRSkfYrib9fHyYONwdccv17gibCls7ia8elaunvgMmYicAw22wUJQ3CDw0Cm5ibrOT/0", - "smallHeadImgUrl": "http://wx.qlogo.cn/mmhead/ver_1/vwGdLRK5jtpXagA7dfXlUiaU9VayWNSqia1c2Wib7icJNhPd6WHhqMIVuYuNDfEqPRC2TnmlRSkfYrib9fHyYONwdccv17gibCls7ia8elaunvgMmYicAw22wUJQ3CDw0Cm5ibrOT/132", - "province": "Jiangsu", - "city": "Xuzhou", - "personalCard": 0 - } - ] -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|[object]|true|none||none| -|»» userName|string|false|none||none| -|»» v4|null|false|none||none| -|»» nickName|null|false|none||none| -|»» sex|integer|false|none||none| -|»» phoneMd5|string|false|none||none| -|»» signature|string|false|none||none| -|»» alias|null|false|none||none| -|»» country|string|false|none||none| -|»» bigHeadImgUrl|string|false|none||none| -|»» smallHeadImgUrl|string|false|none||none| -|»» province|string|false|none||none| -|»» city|string|false|none||none| -|»» personalCard|integer|false|none||none| - -# 基础API/群模块 - -## POST 创建微信群 - -POST /group/createChatroom - -创建微信群时最少要选择两位微信好友 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "wxids": [ - "wxid_0xsqb3o0tsvz22", - "wxid_phyyedw9xap22" - ] -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» wxids|body|[string]| 是 |好友的wxid列表| - -> 返回示例 - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "headImgBase64": "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", - "chatroomId": "34757816141@chatroom" - } -} -``` - -```json -{ - "ret": 500, - "msg": "创建群聊失败", - "data": { - "code": "0", - "msg": "MemberList are wrong" - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» headImgBase64|string|true|none||群头像的base64图片| -|»» chatroomId|string|true|none||群ID| - -## POST 修改群名称 - -POST /group/modifyChatroomName - -修改完群名称后若发现手机未展示修改后的名称,可能是手机缓存未刷新,手机聊天框多切换几次会刷新。 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "chatroomName": "GeWe test", - "chatroomId": "34757816141@chatroom" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» chatroomName|body|string| 是 |群名称| -|» chatroomId|body|string| 是 |群ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 修改群备注 - -POST /group/modifyChatroomRemark - -群备注仅自己可见 -修改完群备注后若发现手机未展示修改后的备注,可能是手机缓存未刷新,手机聊天框多切换几次会刷新。 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "chatroomRemark": "GeWe test private", - "chatroomId": "34757816141@chatroom" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» chatroomRemark|body|string| 是 |群备注| -|» chatroomId|body|string| 是 |群ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 修改我在群内的昵称 - -POST /group/modifyChatroomNickNameForSelf - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "nickName": "廖静", - "chatroomId": "34757816141@chatroom" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» nickName|body|string| 是 |群昵称| -|» chatroomId|body|string| 是 |群ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 邀请/添加 进群 - -POST /group/inviteMember - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "wxids": "wxid_8pvka4jg6qzt22", - "chatroomId": "34757816141@chatroom", - "reason": "" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» wxids|body|string| 是 |邀请进群的好友wxid,多个英文逗号分隔| -|» chatroomId|body|string| 是 |群ID| -|» reason|body|string| 是 |邀请进群的说明| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 删除群成员 - -POST /group/removeMember - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "wxids": "wxid_8pvka4jg6qzt22", - "chatroomId": "34757816141@chatroom" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» wxids|body|string| 是 |删除的群成员wxid,多个英文逗号分隔| -|» chatroomId|body|string| 是 |群ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 退出群聊 - -POST /group/quitChatroom - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "chatroomId": "21425161836@chatroom" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» chatroomId|body|string| 是 |群ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 解散群聊 - -POST /group/disbandChatroom - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "chatroomId": "21425161836@chatroom" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» chatroomId|body|string| 是 |群ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 获取群信息 - -POST /group/getChatroomInfo - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "chatroomId": "34757816141@chatroom" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» chatroomId|body|string| 是 |群ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "chatroomId": "34757816141@chatroom", - "nickName": "GeWe test", - "pyInitial": "GEWETEST", - "quanPin": "GeWetest", - "sex": 0, - "remark": "GeWe test private", - "remarkPyInitial": "GEWETESTPRIVATE", - "remarkQuanPin": "GeWetestprivate", - "chatRoomNotify": 1, - "chatRoomOwner": "zhangchuan2288", - "smallHeadImgUrl": "https://wx.qlogo.cn/mmcrhead/PiajxSqBRaEJEIII6n6NUHudK1r5a29cMDlW0Ef7b1ibzksfrwIcRkTicPRoWm7Km3ZQIpq8xp65nD6yUm8BHxzqhV1ic1jQvvnv/0", - "memberList": [ - { - "wxid": "zhangchuan2288", - "nickName": "朝夕。", - "inviterUserName": null, - "memberFlag": 1, - "displayName": null, - "bigHeadImgUrl": null, - "smallHeadImgUrl": null - }, - { - "wxid": "wxid_phyyedw9xap22", - "nickName": "Ashley", - "inviterUserName": "zhangchuan2288", - "memberFlag": 1, - "displayName": null, - "bigHeadImgUrl": null, - "smallHeadImgUrl": null - }, - { - "wxid": "wxid_0xsqb3o0tsvz22", - "nickName": "G", - "inviterUserName": "zhangchuan2288", - "memberFlag": 1, - "displayName": null, - "bigHeadImgUrl": null, - "smallHeadImgUrl": null - } - ] - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» chatroomId|string|true|none||群ID| -|»» nickName|string|true|none||群名称| -|»» pyInitial|string|true|none||群名称的拼音首字母| -|»» quanPin|string|true|none||群名称的全拼| -|»» sex|integer|true|none||none| -|»» remark|string|true|none||群备注,仅自己可见| -|»» remarkPyInitial|string|true|none||群备注的拼音首字母| -|»» remarkQuanPin|string|true|none||群备注的全拼| -|»» chatRoomNotify|integer|true|none||群消息是否提醒| -|»» chatRoomOwner|string|true|none||群主的wxid| -|»» smallHeadImgUrl|string|true|none||群头像链接| -|»» memberList|[object]|true|none||群成员列表| -|»»» wxid|string|true|none||群成员的wxid| -|»»» nickName|string|true|none||群成员的昵称| -|»»» inviterUserName|string¦null|true|none||邀请人的wxid| -|»»» memberFlag|integer|true|none||标识| -|»»» displayName|null|true|none||在本群内的昵称| -|»»» bigHeadImgUrl|null|true|none||大尺寸头像| -|»»» smallHeadImgUrl|null|true|none||小尺寸头像| - -## POST 获取群成员列表 - -POST /group/getChatroomMemberList - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "chatroomId": "34757816141@chatroom" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» chatroomId|body|string| 是 |群ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "memberList": [ - { - "wxid": "zhangchuan2288", - "nickName": "朝夕。", - "inviterUserName": null, - "memberFlag": 1, - "displayName": null, - "bigHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/T0MtLBu618rUlZqaAiaWfucmVibiawiciaSibPfz11siaLZr0qSxQTAR9lu7YicDwYAHNia1je79icxul6bzQ4LLZopiaM9EdYAEublPCLV29QKLv26ictBHjWsWnE0lvYGjibB9DkE6q/0", - "smallHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/T0MtLBu618rUlZqaAiaWfucmVibiawiciaSibPfz11siaLZr0qSxQTAR9lu7YicDwYAHNia1je79icxul6bzQ4LLZopiaM9EdYAEublPCLV29QKLv26ictBHjWsWnE0lvYGjibB9DkE6q/132" - }, - { - "wxid": "wxid_phyyedw9xap22", - "nickName": "Ashley", - "inviterUserName": "zhangchuan2288", - "memberFlag": 1, - "displayName": null, - "bigHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/5ibSibfNKwpv0TLLuSFv2hibEBqShib4BKsaxHZ2v10y9F93ibO5lK4bwib47qtuwsLZD8HY7fVicibWlWvehCLDCdicy38NaIbVupuMZMDwiaXozjUhk/0", - "smallHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/5ibSibfNKwpv0TLLuSFv2hibEBqShib4BKsaxHZ2v10y9F93ibO5lK4bwib47qtuwsLZD8HY7fVicibWlWvehCLDCdicy38NaIbVupuMZMDwiaXozjUhk/132" - }, - { - "wxid": "wxid_0xsqb3o0tsvz22", - "nickName": "G", - "inviterUserName": "zhangchuan2288", - "memberFlag": 2049, - "displayName": "G1", - "bigHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/FMkteDauMN35F3lhfavibDYpGibfHqrsMICtqBbWDfwfQOnIYfgHBpOJLLbac0Wf3odowXcePFHMzj954EeFOiaKcsgIaMedw5KWZhBpaLsFfSK5HNAE7AQODQ1FfrPiaTCh/0", - "smallHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/FMkteDauMN35F3lhfavibDYpGibfHqrsMICtqBbWDfwfQOnIYfgHBpOJLLbac0Wf3odowXcePFHMzj954EeFOiaKcsgIaMedw5KWZhBpaLsFfSK5HNAE7AQODQ1FfrPiaTCh/132" - }, - { - "wxid": "wxid_8pvka4jg6qzt22", - "nickName": "白开水加糖", - "inviterUserName": "wxid_phyyedw9xap22", - "memberFlag": 2049, - "displayName": null, - "bigHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/3d34Q9DWL6pHiaASIBMIG3J9deRhwz4yKpZxGibDqiaRGmF6XckV0VSeRTGHSTq55bSwK1qF4Sy1JVXIkB7tYHpR4qPh3ECcodpkqRQjSwKUa4/0", - "smallHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/3d34Q9DWL6pHiaASIBMIG3J9deRhwz4yKpZxGibDqiaRGmF6XckV0VSeRTGHSTq55bSwK1qF4Sy1JVXIkB7tYHpR4qPh3ECcodpkqRQjSwKUa4/132" - } - ], - "chatroomOwner": "zhangchuan2288", - "adminWxid": [ - "wxid_8pvka4jg6qzt22" - ] - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» memberList|[object]|true|none||群成员列表| -|»»» wxid|string|true|none||群成员的wxid| -|»»» nickName|string|true|none||群成员昵称| -|»»» inviterUserName|string¦null|true|none||邀请人的wxid| -|»»» memberFlag|integer|true|none||标识| -|»»» displayName|string¦null|true|none||在本群内的昵称| -|»»» bigHeadImgUrl|string|true|none||大尺寸头像| -|»»» smallHeadImgUrl|string|true|none||小尺寸头像| -|»» chatroomOwner|null|true|none||群主的wxid| -|»» adminWxid|null|true|none||管理的wxid| - -## POST 获取群成员详情 - -POST /group/getChatroomMemberDetail - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "chatroomId": "34757816141@chatroom", - "memberWxids": [ - "wxid_0xsqb3o0tsvz22", - "wxid_phyyedw9xap22" - ] -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» chatroomId|body|string| 是 |群ID| -|» memberWxids|body|[string]| 是 |none| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": [ - { - "userName": "wxid_0xsqb3o0tsvz22", - "nickName": "G", - "pyInitial": "G", - "quanPin": "G", - "sex": 0, - "remark": null, - "remarkPyInitial": null, - "remarkQuanPin": null, - "chatRoomNotify": 0, - "signature": null, - "alias": null, - "snsBgImg": "http://shmmsns.qpic.cn/mmsns/s5BUfupeMYsJx3WHf6RyTxAqLUpGZPsgD9l68D5iaf7qibkcjz08RwNwDxj9ToFvnaicFD2X8CtPe4/0", - "bigHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/tmlG7SpZJMJEh0dA14icl4CWnliaI8pKvVicEMaowRywgVpljBK3nmBib0jHG4eVo5hiaqS7Gg0p7GwCuHopGYqdNBu9WVtxMB8icSFGUjibCDPoGXicPic1r3gx3PQ4YMf3GPfXj/0", - "smallHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/tmlG7SpZJMJEh0dA14icl4CWnliaI8pKvVicEMaowRywgVpljBK3nmBib0jHG4eVo5hiaqS7Gg0p7GwCuHopGYqdNBu9WVtxMB8icSFGUjibCDPoGXicPic1r3gx3PQ4YMf3GPfXj/132", - "description": null, - "cardImgUrl": null, - "labelList": null, - "country": "CN", - "province": "Guangdong", - "city": "Foshan", - "phoneNumList": null, - "friendUserName": "wxid_0xsqb3o0tsvz22", - "inviterUserName": "zhangchuan2288", - "memberFlag": 0 - }, - { - "userName": "wxid_phyyedw9xap22", - "nickName": "Ashley", - "pyInitial": "ASHLEY", - "quanPin": "Ashley", - "sex": 2, - "remark": "小号", - "remarkPyInitial": "XH", - "remarkQuanPin": "xiaohao", - "chatRoomNotify": 0, - "signature": "山林不向四季起誓 枯荣随缘。", - "alias": "zero-one_200906", - "snsBgImg": "http://shmmsns.qpic.cn/mmsns/UaAfqYic92wm7ZCrsEwlQMXSmBLs8dpwBzrXnrOyyP3B8bDibCCFInJ9PicC9LPYY17uWH1yIOmBYQ/0", - "bigHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/buiaXybHTBK3BuGr1edN72zBDermWVFJ7YC8Jib2RcCSdiauAtZcPgUQpdhE9KY5NsumDAWD16fsg3A6OKuhdEr97VAHdTGgk6R1Eibuj7ZNwJ4/0", - "smallHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/buiaXybHTBK3BuGr1edN72zBDermWVFJ7YC8Jib2RcCSdiauAtZcPgUQpdhE9KY5NsumDAWD16fsg3A6OKuhdEr97VAHdTGgk6R1Eibuj7ZNwJ4/132", - "description": null, - "cardImgUrl": null, - "labelList": "27", - "country": "AD", - "province": null, - "city": null, - "phoneNumList": [ - "\n\u000b14752126220" - ], - "friendUserName": "wxid_phyyedw9xap22", - "inviterUserName": null, - "memberFlag": null - } - ] -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|[object]|true|none||none| -|»» userName|string|true|none||群成员的wxid| -|»» nickName|string|true|none||群成员的昵称| -|»» pyInitial|string|true|none||群成员昵称的拼音首字母| -|»» quanPin|string|true|none||群成员昵称的全拼| -|»» sex|integer|true|none||性别| -|»» remark|string¦null|true|none||备注| -|»» remarkPyInitial|string¦null|true|none||备注的拼音首字母| -|»» remarkQuanPin|string¦null|true|none||备注的全拼| -|»» chatRoomNotify|integer|true|none||消息通知| -|»» signature|string¦null|true|none||签名| -|»» alias|string¦null|true|none||微信号| -|»» snsBgImg|string|true|none||朋友圈背景图链接| -|»» bigHeadImgUrl|string|true|none||大尺寸头像| -|»» smallHeadImgUrl|string|true|none||小尺寸头像| -|»» description|null|true|none||描述| -|»» cardImgUrl|null|true|none||描述的图片链接| -|»» labelList|string¦null|true|none||标签列表,多个英文逗号分隔| -|»» country|string|true|none||国家| -|»» province|string¦null|true|none||省份| -|»» city|string¦null|true|none||城市| -|»» phoneNumList|[string]|true|none||手机号码| -|»» friendUserName|string|true|none||好友的wxid| -|»» inviterUserName|string¦null|true|none||邀请人的wxid| -|»» memberFlag|integer¦null|true|none||标识| - -## POST 获取群公告 - -POST /group/getChatroomAnnouncement - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "chatroomId": "34757816141@chatroom" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» chatroomId|body|string| 是 |群ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "announcement": "群公告哈", - "announcementEditor": "zhangchuan2288", - "publishTime": 1703839509 - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» announcement|string|true|none||群公告内容| -|»» announcementEditor|string|true|none||群公告作者的wxid| -|»» publishTime|integer|true|none||群公告发布时间| - -## POST 设置群公告 - -POST /group/setChatroomAnnouncement - -仅群主或管理员可以发布群公告 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "chatroomId": "34757816141@chatroom", - "content": "群公告哈" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» chatroomId|body|string| 是 |群ID| -|» content|body|string| 是 |公告内容| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 同意进群 - -POST /group/agreeJoinRoom - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "url": "https://support.weixin.qq.com/cgi-bin/mmsupport-bin/addchatroombyinvite?ticket=A%2FtYjg2L%2FGB%2FHYqOwzWNMQ%3D%3D" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» url|body|string| 是 |邀请进群回调消息中的url| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "chatroomId": "19189253160@chatroom" - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» chatroomId|string|true|none||群ID| - -## POST 添加群成员为好友 - -POST /group/addGroupMemberAsFriend - -添加群成员为好友,若对方关闭从群聊添加的权限则添加失败 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "chatroomId": "34757816141@chatroom", - "content": "hallo", - "memberWxid": "wxid_phyyedw9xap22" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» chatroomId|body|string| 是 |群ID| -|» memberWxid|body|string| 是 |群成员的wxid| -|» content|body|string| 是 |加好友的招呼语| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "v3": "v3_020b3826fd030100000000003a070e7757675c000000501ea9a3dba12f95f6b60a0536a1adb690dcccc9bf58cc80765e6eb16bffa5996420bb1b2577634516ff82090419d8bdcd5689df8dfb21d40af93d286f72c3a0e8cfa6dcb68afed39226f008c6@stranger" - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» v3|string|true|none||添加群成员的v3,通过好友后会通过回调消息返回此值| - -## POST 获取群二维码 - -POST /group/getChatroomQrCode - -### 注意 -- 在新设备登录后的1-3天内,无法使用本功能。在此期间,如果尝试进行获取,您将收到来自微信团队的提醒。请注意遵守相关规定。 -- 生成的群二维码图片7天有效 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "chatroomId": "34757816141@chatroom" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» chatroomId|body|string| 是 |群ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "qrBase64": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/wAALCAG4AbgBAREA/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/9oACAEBAAA/AP1Tooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooor+Veiiiiiiv6qK/lXr+qiiiv5V6/qor+Vev6qKKKKK/lXoooooor+qiiiv5V6KK/qoor+Veiv6qKKK/lXr+qiv5V6KKKKKK/qoooooor+Vev6qKKKKK/lXr+qiiiv5V6KKKKKK/qor+Veiiiv6qKK/lXor+qiiv5V6K/qoor+Veiv6qKK/lXr+qiv5V6KK/qor+Vev6qKKKKK/lXr+qiiiiiiv5V6/qor+Veiiv6qK/lXr+qiiv5V6K/qoor+Veiiv6qK/lXor+qiv5V6/qoor+Veiv6qK/lXor+qiiv5V6/qor+Veiv6qKKKKK/lXor+qiv5V6/qor+Veiiv6qK/lXr+qiiiiiiv5V6/qor+Veiiv6qK/lXr+qiiv5V6K/qor+Veiiiv6qKK/lXor+qiiv5V6/qor+Veiiiv6qKK/lXr+qiiiiv5V6KK/qor+Vev6qKK/lXr+qiv5V6KK/qor+Vev6qKKKKKK/lXr+qiv5V6KK/qor+Vev6qK/lXr+qiiv5V6K/qooor+Veiiiv6qKK/lXoooor+qiv5V6KK/qor+Vev6qKK/lXoor+qiiiiv5V6/qor+Veiiv6qK/lXr+qiiiiiiv5V6/qooooor+Vev6qK/lXr+qiv5V6K/qoor+Vev6qK/lXr+qiiv5V6/qoor+Vev6qKKK/lXoor+qiv5V6KK/qoor+Veiv6qK/lXr+qiiiv5V6/qooooor+Vev6qKKKKKK/lXoooooor+qiv5V6/qor+Vev6qK/lXr+qiv5V6/qor+Vev6qK/lXr+qiv5V6/qor+Vev6qK/lXr+qiv5V6/qor+Vev6qK/lXr+qiv5V6/qor+Vev6qK/lXr+qiv5V6/qor+Vev6qK/lXoooooor+qiiiiiiiiiiiiiiiiiiiv5V6/qor+Veiiiv6qKKK/lXr+qiiiv5V6/qor+Veiv6qK/lXr+qiv5V6/qor+Veiv6qK/lXor+qiiiiiiiiiiiiiiiiv5V6KKKKKK/qor+Veiiv6qK/lXooooooor+qiv5V6KKKK/qoooooor+Veiv6qK/lXor+qiv5V6/qooor+Veiv6qKKK/lXr+qiiiiiiv5V6KKK/qor+Vev6qK/lXr+qiiv5V6/qor+Vev6qK/lXoor+qiv5V6K/qor+Veiiv6qKKK/lXr+qiv5V6KK/qooor+Veiiv6qKKK/lXor+qiiv5V6/qooooooooor+Vev6qK/lXoor+qiv5V6/qor+Veiiv6qKKK/lXoor+qiiiv5V6KKK/qor+Veiiv6qKK/lXr+qiiv5V6/qoor+Veiv6qKK/lXor+qiv5V6/qor+Veiiiv6qKKKKKKK/lXoor+qiv5V6/qooor+Vev6qKKKK/lXoor+qiiv5V6/qooooor+Vev6qKK/lXr+qiiv5V6/qoor+Veiiv6qKKK/lXooor+qiiiv5V6/qooooooor+Vev6qK/lXr+qiiv5V6K/qor+Vev6qK/lXoor+qiv5V6K/qor+Vev6qKKKK/lXr+qiiv5V6K/qor+Vev6qK/lXor+qiiv5V6KKK/qor+Veiv6qK/lXor+qiiiiv5V6/qoooooor+Vev6qK/lXoor+qiiiv5V6K/qor+Vev6qKKKK/lXor+qiiiiv5V6KKK/qooor+Veiv6qKKKKK/lXor+qiv5V6/qoor+Vev6qKKK/lXr+qiiiiiiiiv5V6K/qor+Vev6qK/lXoor+qiv5V6K/qor+Vev6qKKK/lXr+qiiv5V6/qor+Veiv6qK/lXoor+qiv5V6/qooooor+Veiiv6qKK/lXoor+qiiv5V6KKKK/qooooooor+Veiiv6qK/lXr+qiv5V6/qoooor+Veiv6qK/lXoor+qiv5V6K/qoor+Vev6qKKK/lXr+qiv5V6/qoooor+Veiiiiiiv6qK/lXr+qiv5V6/qor+Veiiv6qKKKKKK/lXr+qiv5V6/qoor+Veiiiv6qK/lXoooor+qiiv5V6K/qor+Veiiv6qK/lXor+qiiv5V6/qoor+Vev6qK/lXooor+qiv5V6/qoor+Veiv6qKK/lXr+qiiiiiiiiiv5V6/qooor+Vev6qKK/lXr+qiiiiv5V6K/qoor+Vev6qKKKKKK/lXr+qiiiiiv5V6/qoor+Vev6qK/lXr+qiv5V6KKK/qoor+Veiv6qK/lXor+qiiiiiiiiiv5V6/qor+Vev6qK/lXoor+qiiiv5V6K/qooooor+Veiiiiv6qK/lXor+qiiv5V6/qor+Vev6qKK/lXr+qiiiiiiiv5V6KKKK/qor+Veiv6qKKKKKKK/lXr+qiiv5V6/qooor+Vev6qK/lXr+qiv5V6/qor+Veiiiv6qK/lXoor+qiiv5V6K/qoor+Veiv6qK/lXoooor+qiv5V6KK/qoor+Veiiv6qKKKKKKKKKKKKKKK/lXoor+qiv5V6/qor+Vev6qKKKKKK/lXor+qiiv5V6K/qor+Vev6qKK/lXr+qiiv5V6/qoooor+Veiiiiv6qK/lXor+qiiv5V6K/qooooooooor+Vev6qK/lXor+qiiv5V6/qoor+Veiiv6qK/lXoor+qiv5V6KKK/qooor+Veiiiiv6qK/lXr+qiiv5V6K/qoooor+Veiv6qKK/lXr+qiiiiiiiiiv5V6KK/qor+Veiiiiiv6qKK/lXor+qiv5V6KKKK/qor+Veiiiiiv6qKK/lXr+qiv5V6/qoor+Vev6qKKK/lXr+qiv5V6KKKK/qor+Veiiv6qKKKKKKKK/lXoor+qiiiv5V6/qoor+Vev6qK/lXor+qiiiv5V6/qor+Vev6qK/lXr+qiiiv5V6/qooor+Vev6qKK/lXr+qiiv5V6/qoor+Veiv6qKKK/lXr+qiiiv5V6/qoooooooooor+Vev6qK/lXr+qiv5V6K/qoor+Veiv6qK/lXr+qiiv5V6/qoor+Veiv6qK/lXr+qiv5V6K/qor+Veiiv6qKKK/lXoor+qiiv5V6/qor+Vev6qK/lXoor+qiiiiiiiiiiiiv5V6/qooor+Veiiiv6qKKK/lXr+qiiv5V6KKKK/qooor+Vev6qKK/lXor+qiv5V6/qoor+Veiiv6qKK/lXr+qiiiv5V6KKKK/qooooooor+Veiiiiiiiiiv6qKK/lXr+qiv5V6/qor+Vev6qK/lXr+qiv5V6KKKKKK/qoor+Vev6qK/lXor+qiiiv5V6/qoor+Veiiiiiiv6qK/lXr+qiiiiiiv5V6/qooor+Veiv6qK/lXoor+qiv5V6/qor+Veiv6qKK/lXoor+qiv5V6/qor+Vev6qK/lXoor+qiiiiv5V6K/qooor+Veiv6qK/lXor+qiv5V6/qor+Vev6qK/lXor+qiiiiiiv5V6K/qor+Veiiiiv6qK/lXor+qiiiiv5V6K/qoor+Veiiiv6qK/lXor+qiiv5V6KKK/qor+Vev6qK/lXoor+qiv5V6KK/qoooor+Vev6qK/lXr+qiiiiiiv5V6KK/qoooor+Veiiv6qKK/lXoor+qiv5V6KKK/qooor+Vev6qKK/lXooooor+qiv5V6/qor+Vev6qK/lXr+qiiiv5V6/qor+Veiiv6qK/lXr+qiiiiiiiiiiiv5V6KKK/qor+Vev6qKKK/lXr+qiiv5V6/qooooor+Vev6qKK/lXor+qiv5V6K/qoor+Vev6qK/lXoooooooor+qiv5V6KK/qor+Vev6qKKKKKK/lXr+qiv5V6/qor+Veiv6qKKK/lXor+qiv5V6/qor+Veiv6qKK/lXr+qiv5V6KK/qoor+Veiiv6qK/lXr+qiiiiv5V6/qor+Vev6qKK/lXor+qiiv5V6K/qooooooooooooor+Vev6qK/lXor+qiiiiv5V6K/qor+Veiv6qKKK/lXr+qiiv5V6K/qoor+Vev6qK/lXooooooor+qiv5V6/qor+Veiiiiiiiiv6qKKKKKKKK/lXr+qiiiv5V6/qor+Veiiv6qK/lXr+qiv5V6/qoor+Vev6qKK/lXr+qiv5V6K/qor+Vev6qKK/lXooor+qiv5V6/qoooor+Vev6qKK/lXr+qiiv5V6/qooor+Vev6qKKKKKKKK/lXoor+qiv5V6KKKK/qor+Vev6qK/lXr+qiiiiiiv5V6KK/qooooor+Vev6qKK/lXoooor+qiiiiiv5V6K/qor+Veiv6qKK/lXr+qiiiiiiiv5V6KKK/qooooor+Vev6qK/lXr+qiv5V6KK/qooooor+Veiv6qK/lXr+qiv5V6/qor+Vev6qK/lXor+qiiiv5V6K/qooooor+Veiv6qKKKKKKKKKK/lXor+qiv5V6K/qor+Vev6qK/lXr+qiiiv5V6K/qor+Vev6qKKK/lXor+qiv5V6/qor+Vev6qKK/lXr+qiv5V6KK/qooor+Veiv6qK/lXoor+qiiv5V6/qor+Veiiv6qKKKKKKKKK/lXr+qiv5V6K/qor+Vev6qK/lXr+qiiiv5V6/qoooor+Veiv6qKK/lXr+qiiv5V6K/qoor+Veiv6qK/lXr+qiiv5V6KK/qoor+Vev6qKK/lXr+qiv5V6/qor+Vev6qKKKKKKKK/lXr+qiiiv5V6KK/qor+Vev6qK/lXoooor+qiiiiiv5V6K/qooor+Veiiv6qKK/lXr+qiiiiv5V6KKKKKKKK/qooor+Vev6qKKKKKKK/lXoor+qiiiv5V6KK/qooor+Vev6qKKK/lXoor+qiiiiiv5V6KKK/qor+Veiiiv6qK/lXr+qiiiiiv5V6/qor+Vev6qK/lXr+qiv5V6K/qoooooor+Veiiv6qKKK/lXor+qiv5V6K/qor+Vev6qKK/lXooor+qiiv5V6KKKKK/qoor+Veiv6qKKKK/lXoor+qiv5V6KKKKK/qooor+Vev6qKKKKKKKKKKKKKK/lXor+qiv5V6/qoor+Veiiiv6qKK/lXoor+qiiiv5V6K/qoor+Veiiiv6qK/lXor+qiiiv5V6/qooor+Vev6qKKKKKKKKKK/lXoooooor+qiv5V6/qoor+Vev6qK/lXor+qiiv5V6KKKKK/qor+Vev6qK/lXoooor+qiv5V6/qoor+Vev6qK/lXr+qiiv5V6/qor+Vev6qK/lXor+qiiv5V6/qoooooor+Vev6qKKKKK/lXr+qiv5V6/qooor+Vev6qKK/lXor+qiv5V6/qooor+Vev6qKKK/lXor+qiiv5V6/qor+Veiiiiiiiiv6qKKK/lXr+qiiv5V6K/qoooooor+Vev6qK/lXoor+qiv5V6/qor+Vev6qK/lXooor+qiv5V6/qor+Veiv6qKKK/lXoooor+qiiv5V6KK/qor+Vev6qK/lXooooooooor+qiv5V6/qor+Vev6qKKKKKK/lXr+qiv5V6KK/qor+Vev6qK/lXor+qiv5V6/qoooooor+Veiv6qK/lXor+qiiiiiv5V6KK/qor+Vev6qKK/lXr+qiv5V6/qor+Vev6qK/lXor+qiv5V6/qor+Veiiv6qKKKKKK/lXr+qiv5V6KK/qor+Vev6qK/lXr+qiv5V6KKKKKKK/qoor+Veiv6qK/lXor+qiv5V6K/qor+Vev6qKKK/lXor+qiv5V6KK/qor+Veiv6qK/lXr+qiiv5V6KK/qoooooor+Vev6qKKKKK/lXr+qiv5V6K/qoor+Vev6qKK/lXoor+qiv5V6K/qor+Vev6qKKKK/lXr+qiv5V6/qoor+Veiv6qK/lXor+qiiv5V6K/qor+Vev6qK/lXr+qiiiv5V6/qoooooor+Veiiiiiiv6qKK/lXr+qiiv5V6KK/qooor+Vev6qKK/lXoor+qiv5V6K/qoooor+Vev6qKKK/lXoor+qiiv5V6/qoooor+Veiiiv6qKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK//2Q==", - "qrTips": "该二维码7天内(1月5日前)有效,重新进入将更新" - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» qrBase64|string|true|none||群二维码图片的base64| -|»» qrTips|string|true|none||群二维码的提示| - -## POST 群保存到通讯录 - -POST /group/saveContractList - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "chatroomId": "34757816141@chatroom", - "operType": 3 -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» chatroomId|body|string| 是 |群ID| -|» operType|body|integer| 是 |操作类型 3保存到通讯录 2从通讯录移除| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 管理员操作 - -POST /group/adminOperate - -添加、删除群管理员,转让群主 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "chatroomId": "34757816141@chatroom", - "operType": 1, - "wxids": [ - "wxid_0xsqb3o0tsvz22" - ] -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» chatroomId|body|string| 是 |群ID| -|» operType|body|integer| 是 |操作类型 1:添加群管理(可添加多个微信号) 2:删除群管理(可删除多个) 3:转让(只能转让一个微信号)| -|» wxids|body|[string]| 是 |none| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 聊天置顶 - -POST /group/pinChat - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "chatroomId": "34757816141@chatroom", - "top": true -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» chatroomId|body|string| 是 |群ID| -|» top|body|boolean| 是 |是否置顶| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 设置消息免打扰 - -POST /group/setMsgSilence - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "chatroomId": "34757816141@chatroom", - "silence": true -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» chatroomId|body|string| 是 |群ID| -|» silence|body|boolean| 是 |是否免打扰| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 扫码进群 - -POST /group/joinRoomUsingQRCode - -qrUrl是通过解析群二维码图片获得的内容 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "qrUrl": "https://weixin.qq.com/g/AwYAALLELoeKLg-qWAtkYtBdyTg_i2TG22w1GS-cL1GFO9J4AemIyZAw7RSuIpZw" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» qrUrl|body|string| 是 |二维码的链接| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "chatroomName": "GeWe-test-room(2)", - "html": null, - "chatroomId": "34559815390@chatroom" - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» chatroomName|string|true|none||群名称| -|»» html|null|true|none||none| -|»» chatroomId|string|true|none||群ID| - -## POST 确认进群申请 - -POST /group/roomAccessApplyCheckApprove - -群聊开启邀请确认后,有人申请进群时群主和管理员会收到进群申请,本接口用于确认进群申请 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "chatroomId": "34757816141@chatroom", - "msgContent": "\n\t\n\t\t \n\t\t \n\t\t\troomaccessapplycheck_approve\n\t\t\t \n\t\t\t \n\t\t\t \n\t\t\t \n\t\t\t\n\t\t\t\t1\n\t\t\t\t\n\t\t\t\t\t \n\t\t\t\t\t \n\t\t\t\t\t \n\t\t\t\t\t \n\t\t\t\t\n\t\t\t\n\t\t\n\t\t \n\t\n", - "newMsgId": "8866462780395237368" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» chatroomId|body|string| 是 |群ID| -|» newMsgId|body|string| 是 |消息ID| -|» msgContent|body|string| 是 |消息内容| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -# 基础API/消息模块 - -## POST 发送文字消息 - -POST /message/postText - -#### 注意 -在群内发送消息@某人时,content中需包含@xxx - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "toWxid": "wxid_tdkou97nquqz22", - "ats": "wxid_phyyedw9xap22", - "content": "@猿猴 我在测试艾特内容" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» toWxid|body|string| 是 |好友/群的ID| -|» content|body|string| 是 |消息内容| -|» ats|body|string| 否 |@的好友,多个英文逗号分隔。群主或管理员@全部的人,则填写'notify@all'| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "toWxid": "34757816141@chatroom", - "createTime": 1703841160, - "msgId": 0, - "newMsgId": 3768973957878705000, - "type": 1 - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» toWxid|string|true|none||接收人的wxid| -|»» createTime|integer|true|none||发送时间| -|»» msgId|integer|true|none||消息ID| -|»» newMsgId|integer|true|none||消息ID| -|»» type|integer|true|none||消息类型| - -## POST 发送文件消息 - -POST /message/postFile - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "toWxid": "34757816141@chatroom", - "fileName": "a909.xls", - "fileUrl": "https://scrm-1308498490.cos.ap-shanghai.myqcloud.com/pkg/a909-99066ce80e03.xls?q-sign-algorithm=sha1&q-ak=AKIDmOkqfDUUDfqjMincBSSAbleGaeQv96mB&q-sign-time=1703841209;1703848409&q-key-time=1703841209;1703848409&q-header-list=&q-url-param-list=&q-signature=2a60b0f8d9169550cd83c4a3ca9cd18138b4bb88" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» toWxid|body|string| 是 |好友/群的ID| -|» fileUrl|body|string| 是 |文件链接| -|» fileName|body|string| 是 |文件名| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "toWxid": "34757816141@chatroom", - "createTime": 1703841225, - "msgId": 769523509, - "newMsgId": 4399037329770756000, - "type": 6 - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» toWxid|string|true|none||接收人的wxid| -|»» createTime|integer|true|none||发送时间| -|»» msgId|integer|true|none||消息ID| -|»» newMsgId|integer|true|none||消息ID| -|»» type|integer|true|none||消息类型| - -## POST 发送图片消息 - -POST /message/postImage - -#### 注意 -发送图片接口会返回cdn相关的信息,如有需求同一张图片发送多次,第二次及以后发送时可使用接口返回的cdn信息拼装xml调用[转发图片接口](https://apifox.com/apidoc/shared-69ba62ca-cb7d-437e-85e4-6f3d3df271b1/api-196794551),这样可以缩短发送时间 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "toWxid": "34757816141@chatroom", - "imgUrl": "http://dummyimage.com/400x400" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» toWxid|body|string| 是 |好友/群的ID| -|» imgUrl|body|string| 是 |图片链接| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "toWxid": "34757816141@chatroom", - "createTime": 0, - "msgId": 640355969, - "newMsgId": 8992614056172360000, - "type": null, - "aesKey": "7678796e6d70626e6b626c6f7375616b", - "fileId": "3052020100044b30490201000204e49785f102033d11fd0204136166b4020465966eea042437646265323234362d653662662d343464392d393363362d3139313661363863646266390204052418020201000400", - "length": 1096, - "width": 400, - "height": 400, - "md5": "e6355eab0393facbd6a2cde3f990ef60" - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» toWxid|string|true|none||接收人的wxid| -|»» createTime|integer|true|none||发送时间| -|»» msgId|integer|true|none||消息ID| -|»» newMsgId|integer|true|none||消息ID| -|»» type|null|true|none||消息类型| -|»» aesKey|string|true|none||cdn相关的aeskey| -|»» fileId|string|true|none||cdn相关的fileid| -|»» length|integer|true|none||图片文件大小| -|»» width|integer|true|none||图片宽度| -|»» height|integer|true|none||图片高度| -|»» md5|string|true|none||图片md5| - -## POST 发送语音消息 - -POST /message/postVoice - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "toWxid": "34757816141@chatroom", - "voiceUrl": "https://scrm-1308498490.cos.ap-shanghai.myqcloud.com/pkg/response.silk?q-sign-algorithm=sha1&q-ak=AKIDmOkqfDUUDfqjMincBSSAbleGaeQv96mB&q-sign-time=1703841529;1703848729&q-key-time=1703841529;1703848729&q-header-list=&q-url-param-list=&q-signature=781831fe71ad4bbb582715bf197a9cf86ec80c97", - "voiceDuration": 2000 -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» toWxid|body|string| 是 |好友/群的ID| -|» voiceUrl|body|string| 是 |语音文件的链接,仅支持silk格式| -|» voiceDuration|body|integer| 是 |语音时长,单位毫秒| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "toWxid": "34757816141@chatroom", - "createTime": 1704357563, - "msgId": 640355967, - "newMsgId": 2321462558768366600, - "type": null - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» toWxid|string|true|none||接收人的wxid| -|»» createTime|integer|true|none||发送时间| -|»» msgId|integer|true|none||消息ID| -|»» newMsgId|integer|true|none||消息ID| -|»» type|integer|true|none||消息类型| - -## POST 发送视频消息 - -POST /message/postVideo - -#### 注意 -发送视频接口会返回cdn相关的信息,如有需求同一个视频发送多次,第二次及以后发送时可使用接口返回的cdn信息拼装xml调用[转发视频接口](https://apifox.com/apidoc/shared-69ba62ca-cb7d-437e-85e4-6f3d3df271b1/api-196794552),这样可以缩短发送时间 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "toWxid": "{{toWxid}}", - "videoUrl": "https://scrm-1308498490.cos.ap-shanghai.myqcloud.com/1/41734f00f3803ca1cd8f5ad6d5f8d559.mp4?q-sign-algorithm=sha1&q-ak=AKIDmOkqfDUUDfqjMincBSSAbleGaeQv96mB&q-sign-time=1724227372;2588140972&q-key-time=1724227372;2588140972&q-header-list=&q-url-param-list=&q-signature=4e18eb97ab165f27afe0444516e54204f506c7e1", - "thumbUrl": "https://scrm-1308498490.cos.ap-shanghai.myqcloud.com/1/logo.jpg?q-sign-algorithm=sha1&q-ak=AKIDmOkqfDUUDfqjMincBSSAbleGaeQv96mB&q-sign-time=1724227462;2588141062&q-key-time=1724227462;2588141062&q-header-list=&q-url-param-list=&q-signature=0bc8b973567d2672e5eaada1b5d466e23ce6b750", - "videoDuration": 10 -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» toWxid|body|string| 是 |好友/群的ID| -|» videoUrl|body|string| 是 |视频的链接| -|» thumbUrl|body|string| 是 |缩略图的链接| -|» videoDuration|body|integer| 是 |视频的播放时长,单位秒| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "toWxid": "34757816141@chatroom", - "createTime": null, - "msgId": 769523567, - "newMsgId": 945590746179451500, - "type": null, - "aesKey": "687a636f627579667a756a7168717968", - "fileId": "3052020100044b304902010002043904752002033d11ff02045dd79b240204658e9072042466633131376136662d366566632d343638662d613633662d3536316139616133383362350204012400040201000400", - "length": 1315979 - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» toWxid|string|true|none||接收人的wxid| -|»» createTime|null|true|none||发送时间| -|»» msgId|integer|true|none||消息ID| -|»» newMsgId|integer|true|none||消息ID| -|»» type|null|true|none||消息类型| -|»» aesKey|string|true|none||cdn相关的aeskey| -|»» fileId|string|true|none||cdn相关的fileid| -|»» length|integer|true|none||视频文件大小| - -## POST 发送链接消息 - -POST /message/postLink - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "toWxid": "34757816141@chatroom", - "title": "澳门这一夜", - "desc": "39岁郭碧婷用珠圆玉润的身材,狠狠打脸了白幼瘦女星", - "linkUrl": "https://mbd.baidu.com/newspage/data/landingsuper?context=%7B%22nid%22%3A%22news_8864265500294006781%22%7D&n_type=-1&p_from=-1", - "thumbUrl": "https://pics3.baidu.com/feed/0824ab18972bd407a9403f336648d15c0db30943.jpeg@f_auto?token=d26f7f142871542956aaa13799ba1946" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» toWxid|body|string| 是 |好友/群的ID| -|» title|body|string| 是 |链接标题| -|» desc|body|string| 是 |链接描述| -|» linkUrl|body|string| 是 |链接地址| -|» thumbUrl|body|string| 是 |链接缩略图地址| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "toWxid": "34757816141@chatroom", - "createTime": 1703841982, - "msgId": 769523572, - "newMsgId": 3358797740318931000, - "type": 5 - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» toWxid|string|true|none||接收人的wxid| -|»» createTime|integer|true|none||发送时间| -|»» msgId|integer|true|none||消息ID| -|»» newMsgId|integer|true|none||消息ID| -|»» type|integer|true|none||消息类型| - -## POST 发送名片消息 - -POST /message/postNameCard - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "toWxid": "34757816141@chatroom", - "nickName": "谭艳", - "nameCardWxid": "wxid_0xsqb3o0tsvz22" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» toWxid|body|string| 是 |好友/群的ID| -|» nickName|body|string| 是 |名片的昵称| -|» nameCardWxid|body|string| 是 |名片的wxid| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "toWxid": "34757816141@chatroom", - "createTime": 1703842036, - "msgId": 0, - "newMsgId": 3285058507819179500, - "type": 42 - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» toWxid|string|true|none||接收人的wxid| -|»» createTime|integer|true|none||发送时间| -|»» msgId|integer|true|none||消息ID| -|»» newMsgId|integer|true|none||消息ID| -|»» type|integer|true|none||消息类型| - -## POST 发送emoji消息 - -POST /message/postEmoji - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "toWxid": "34757816141@chatroom", - "emojiMd5": "4cc7540a85b5b6cf4ba14e9f4ae08b7c", - "emojiSize": 102357 -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» toWxid|body|string| 是 |好友/群的ID| -|» emojiMd5|body|string| 是 |emoji图片的md5| -|» emojiSize|body|integer| 是 |emoji的文件大小| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "toWxid": "34757816141@chatroom", - "createTime": null, - "msgId": 769523643, - "newMsgId": 891398861855787000, - "type": null - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» toWxid|string|true|none||接收人的wxid| -|»» createTime|integer|true|none||发送时间| -|»» msgId|integer|true|none||消息ID| -|»» newMsgId|integer|true|none||消息ID| -|»» type|integer|true|none||消息类型| - -## POST 发送appmsg消息 - -POST /message/postAppMsg - -#### 注意 -本接口可用于发送所有包含节点的消息,例如:音乐分享、视频号、引用消息等等 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "toWxid": "34757816141@chatroom", - "appmsg": "\n\t\t一审宣判!蔡鄂生被判死缓\n\t\t\n\t\t\n\t\t5\n\t\t0\n\t\t0\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t0\n\t\thttp://mp.weixin.qq.com/s?__biz=MjM5MjAxNDM4MA==&mid=2666774093&idx=1&sn=aa405094dd00034d004f6e8287f86e9b&chksm=bcc9d903635a9c284591edda1f027c467245d922d7d66c32d3cd2c6af1c969a7ea0896aa7639&scene=0&xtrack=1#rd\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\t0\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t3057020100044b304902010002048399cc8402032f57ed02041388e6720204658e922d042462666538346165322d303035382d343262322d616538322d3337306231346630323534360204051408030201000405004c53d900\n\t\t\tea3d5e8d4059cb4db0a3c39c789f2d6f\n\t\t\t93065\n\t\t\t1080\n\t\t\t459\n\t\t\t849df42ab37c8cadb324fe94ba46d76e\n\t\t\t849df42ab37c8cadb324fe94ba46d76e\n\t\t\t0\n\t\t\n\t\t\n\t\tgh_363b924965e9\n\t\t人民日报\n\t\thttps://mmbiz.qpic.cn/sz_mmbiz_jpg/xrFYciaHL08DCJtwQefqrH8JcohbOHhTpyCPab8IgDibkTv3Pspicjw8TRHnoic2tmiafBtUHg7ObZznpWocwkCib6Tw/640?wxtype=jpeg&wxfrom=0\n\t\t\n\t\t\n\t\t\n\t\t\t0\n\t\t\n\t" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» toWxid|body|string| 是 |好友/群的ID| -|» appmsg|body|string| 是 |回调消息中的appmsg节点内容| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "toWxid": "34757816141@chatroom", - "createTime": 1703842453, - "msgId": 769523712, - "newMsgId": 3090682956820882400, - "type": 0 - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» toWxid|string|true|none||接收人的wxid| -|»» createTime|integer|true|none||发送时间| -|»» msgId|integer|true|none||消息ID| -|»» newMsgId|integer|true|none||消息ID| -|»» type|integer|true|none||消息类型| - -## POST 发送小程序消息 - -POST /message/postMiniApp - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "toWxid": "34757816141@chatroom", - "miniAppId": "wx1f9ea355b47256dd", - "userName": "gh_690acf47ea05@app", - "title": "最快29分钟 好吃水果送到家", - "coverImgUrl": "https://che-static.vzhimeng.com/img/2023/10/30/67d55942-e43c-4fdb-8396-506794ddbdbc.jpg", - "pagePath": "pages/homeDelivery/index.html", - "displayName": "百果园+" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» toWxid|body|string| 是 |好友/群的ID| -|» miniAppId|body|string| 是 |小程序ID| -|» displayName|body|string| 是 |小程序名称| -|» pagePath|body|string| 是 |小程序打开的地址| -|» coverImgUrl|body|string| 是 |小程序封面图链接| -|» title|body|string| 是 |小程序标题| -|» userName|body|string| 是 |归属的用户ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "toWxid": "34757816141@chatroom", - "createTime": 1704162674, - "msgId": 769533691, - "newMsgId": 3190424380344821000, - "type": 33 - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» toWxid|string|true|none||接收人的wxid| -|»» createTime|integer|true|none||发送时间| -|»» msgId|integer|true|none||消息ID| -|»» newMsgId|integer|true|none||消息ID| -|»» type|integer|true|none||消息类型| - -## POST 转发文件 - -POST /message/forwardFile - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "toWxid": "34757816141@chatroom", - "xml": "\n\n\t\n\t\tinfo.json\n\t\t\n\t\t\n\t\t6\n\t\t0\n\t\t0\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t0\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\t63\n\t\t\t@cdn_3057020100044b304902010002043904752002032f7d6d02046bb5bade02046593760c042433653765306131612d646138622d346662322d383239362d3964343665623766323061370204051400050201000405004c53d900_f46be643aa0dc009ae5fb63bbc73335d_1\n\t\t\t\n\t\t\tjson\n\t\t\t3057020100044b304902010002043904752002032f7d6d02046bb5bade02046593760c042433653765306131612d646138622d346662322d383239362d3964343665623766323061370204051400050201000405004c53d900\n\t\t\tf46be643aa0dc009ae5fb63bbc73335d\n\t\t\t0\n\t\t\t594239960546299206\n\t\t\tv1_0bgfyCkUmoZYYyvXys0cCiJdd2R/pKPdD2TNi9IY6FOt+Tvlhp3ijUoupZHzyB2Lp7xYgdVFaUGL4iu3Pm9/YACCt20egPGpT+DKe+VymOzD7tJfsS8YW7JObTbN8eVoFEetU5HSRWTgS/48VVsPZMoDF6Gz1XJDLN/dWRxvzrbOzVGGNvmY4lpXb0kRwXkSxwL+dO4=\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\td16070253eee7173e467dd7237d76f60\n\t\t\n\t\n\tzhangchuan2288\n\t0\n\t\n\t\t1\n\t\t\n\t\n\t\n" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» toWxid|body|string| 是 |好友/群的ID| -|» xml|body|string| 是 |文件消息的xml| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "toWxid": "34757816141@chatroom", - "createTime": 1704162866, - "msgId": 769533740, - "newMsgId": 6455486805605396000, - "type": 6 - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» toWxid|string|true|none||接收人的wxid| -|»» createTime|integer|true|none||发送时间| -|»» msgId|integer|true|none||消息ID| -|»» newMsgId|integer|true|none||消息ID| -|»» type|integer|true|none||消息类型| - -## POST 转发图片 - -POST /message/forwardImage - -#### 注意 -若通过发送图片消息获取cdn信息后可替换xml中的aeskey、cdnthumbaeskey、cdnthumburl、cdnmidimgurl、length、md5等参数来进行转发 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "toWxid": "34757816141@chatroom", - "xml": "\n\n\t\n\t\n\t\n" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» toWxid|body|string| 是 |好友/群的ID| -|» xml|body|string| 是 |文件消息的xml| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "toWxid": "34757816141@chatroom", - "createTime": 0, - "msgId": 769533749, - "newMsgId": 7003061792458481000, - "type": null, - "aesKey": "294774c8ac2ca8f8114e4d58d2ba78a5", - "fileId": "3057020100044b304902010002043904752002032f7d6d02046bb5bade020465937656042436626431373937632d613430642d346137662d626230352d3832613335353935333130630204051818020201000405004c543d00", - "length": null, - "width": null, - "height": null, - "md5": null - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» toWxid|string|true|none||接收人的wxid| -|»» createTime|integer|true|none||发送时间| -|»» msgId|integer|true|none||消息ID| -|»» newMsgId|integer|true|none||消息ID| -|»» type|null|true|none||消息类型| -|»» aesKey|string|true|none||cdn相关的aeskey| -|»» fileId|string|true|none||cdn相关的fileid| -|»» length|integer|true|none||图片文件大小| -|»» width|integer|true|none||图片宽度| -|»» height|integer|true|none||图片高度| -|»» md5|string|true|none||图片md5| - -## POST 转发视频 - -POST /message/forwardVideo - -#### 注意 -若通过发送视频消息获取cdn信息后可替换xml中的aeskey、cdnthumbaeskey、cdnvideourl、cdnthumburl、length等参数来进行转发 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "toWxid": "34757816141@chatroom", - "xml": "\n\n\t\n" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» toWxid|body|string| 是 |好友/群的ID| -|» xml|body|string| 是 |文件消息的xml| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "toWxid": "34757816141@chatroom", - "createTime": null, - "msgId": 769533762, - "newMsgId": 2099537549112929300, - "type": null, - "aesKey": "5c5163d06757faae44eacc2146ba0575", - "fileId": null, - "length": 490566 - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» toWxid|string|true|none||接收人的wxid| -|»» createTime|null|true|none||发送时间| -|»» msgId|integer|true|none||消息ID| -|»» newMsgId|integer|true|none||消息ID| -|»» type|null|true|none||消息类型| -|»» aesKey|string|true|none||cdn相关的aeskey| -|»» fileId|string|true|none||cdn相关的fileid| -|»» length|integer|true|none||视频文件大小| - -## POST 转发链接 - -POST /message/forwardUrl - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "toWxid": "34757816141@chatroom", - "xml": "\n\n\t\n\t\t“李在明遇袭,颈部出血”\n\t\t\n\t\t\n\t\t5\n\t\t0\n\t\t0\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t0\n\t\thttp://mp.weixin.qq.com/s?__biz=MjM5MzI5NTU3MQ==&mid=2652294920&idx=1&sn=ad415f5d83e1471b845b2cb3fca7c3ce&chksm=bce58367ee6ae84b711255705422d1554ee96b92d75648751316639d4aa09289d7827ff1cc85&scene=0&xtrack=1#rd\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\t0\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t3057020100044b304902010002048399cc8402032f7d6d020468b5bade0204659376ec042463663234636366642d323736612d343533342d623734342d3864623065633235636135390204051808030201000405004c56f900\n\t\t\t8e32cafa882f9b4f7c51fb568c0c4f8e\n\t\t\t38637\n\t\t\t658\n\t\t\t280\n\t\t\taccc71cbe8ff795a94583fc514d198a8\n\t\t\taccc71cbe8ff795a94583fc514d198a8\n\t\t\t0\n\t\t\n\t\t\n\t\tgh_d29e0d22a6f9\n\t\t澎湃新闻\n\t\thttps://mmbiz.qpic.cn/mmbiz_jpg/yl6JkZAE3SibWvw5icQJpv87X084SRJOVeS3k7KMscRzov1nwicjMYzicyBIpRdJchWKTGPf4eN2H07Jicl11zMK2Pw/640?wxtype=jpeg&wxfrom=0\n\t\t\n\t\t\n\t\t\n\t\t\t0\n\t\t\n\t\n\tzhangchuan2288\n\t0\n\t\n\t\t1\n\t\t\n\t\n\t\n" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» toWxid|body|string| 是 |好友/群的ID| -|» xml|body|string| 是 |文件消息的xml| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "toWxid": "34757816141@chatroom", - "createTime": 1704163083, - "msgId": 769533781, - "newMsgId": 1947412320722133800, - "type": 5 - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» toWxid|string|true|none||接收人的wxid| -|»» createTime|integer|true|none||发送时间| -|»» msgId|integer|true|none||消息ID| -|»» newMsgId|integer|true|none||消息ID| -|»» type|integer|true|none||消息类型| - -## POST 转发小程序 - -POST /message/forwardMiniApp - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "toWxid": "34757816141@chatroom", - "xml": "\n\n\t\n\t\t👇晒出新年第一杯,点赞赢饮茶月卡\n\t\t\n\t\t\n\t\t33\n\t\t0\n\t\t0\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t0\n\t\thttps://mp.weixin.qq.com/mp/waerrpage?appid=wxafec6f8422cb357b&type=upgrade&upgradetype=3#wechat_redirect\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\t0\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t3057020100044b30490201000204573515c902032f7d6d020416b7bade020465922a53042437383139393934652d323662652d346430662d396466362d3466303137346139616362390204051408030201000405004c53d900\n\t\t\t33cf0a1101e7f8cd3057cd417a691f0b\n\t\t\t96673\n\t\t\t600\n\t\t\t500\n\t\t\t6f3098f2ee8b351b6cc9b1818d580356\n\t\t\t6f3098f2ee8b351b6cc9b1818d580356\n\t\t\t0\n\t\t\n\t\t\n\t\tgh_e9d25e745aae@app\n\t\t霸王茶姬\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t2\n\t\t\t193\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t0\n\t\t\t\t\n\t\t\t\n\t\t\t0\n\t\t\n\t\n\tzhangchuan2288\n\t0\n\t\n\t\t1\n\t\t\n\t\n\t\n", - "coverImgUrl": "http://dummyimage.com/400x400" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» toWxid|body|string| 是 |好友/群的ID| -|» xml|body|string| 是 |文件消息的xml| -|» coverImgUrl|body|string| 是 |小程序封面图链接| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "toWxid": "34757816141@chatroom", - "createTime": 1704163145, - "msgId": 769533801, - "newMsgId": 5271007655758710000, - "type": 33 - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» toWxid|string|true|none||接收人的wxid| -|»» createTime|integer|true|none||发送时间| -|»» msgId|integer|true|none||消息ID| -|»» newMsgId|integer|true|none||消息ID| -|»» type|integer|true|none||消息类型| - -## POST 撤回消息 - -POST /message/revokeMsg - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "toWxid": "34757816141@chatroom", - "msgId": "769533801", - "newMsgId": "5271007655758710001", - "createTime": "1704163145" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» toWxid|body|string| 是 |好友/群的ID| -|» msgId|body|string| 是 |发送类接口返回的msgId| -|» newMsgId|body|string| 是 |发送类接口返回的newMsgId| -|» createTime|body|string| 是 |发送类接口返回的createTime| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -# 基础API/消息模块/下载 - -## POST 下载图片 - -POST /message/downloadImage - -**注意** 如果下载图片失败,可尝试下载另外两种图片类型,并非所有图片都会有高清、常规图片 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "type": 2, - "xml": "\n\n\t\n\t\n\t\n\t\n\t\t\n\t\t0\n\t\n\n" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» xml|body|string| 是 |回调消息中的XML| -|» type|body|integer| 是 |下载的图片类型 1:高清图片 2:常规图片 3:缩略图| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "fileUrl": "/download/20240720/wx_BTVoJ_o_r6DpxNCNiycFE/0ca5b675-8e2c-4dc1-b288-3c44a40086ec4" - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» fileUrl|string|true|none||图片链接地址,7天有效| - -# 基础API/标签模块 - -## POST 添加标签 - -POST /label/add - -#### 注意 -标签名称不存在则是添加标签,如果标签名称已经存在,此接口会直接返回标签名及ID - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "labelName": "testtest" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» labelName|body|string| 是 |标签名称| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "labelName": "testtest", - "labelId": 31 - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» labelName|string|true|none||标签名称| -|»» labelId|integer|true|none||标签ID| - -## POST 删除标签 - -POST /label/delete - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "labelIds": "31" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» labelIds|body|string| 是 |标签ID,多个逗号分隔| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 标签列表 - -POST /label/list - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "labelList": [ - { - "labelName": "朋友", - "labelId": 1 - } - ] - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» labelList|[object]|true|none||none| -|»»» labelName|string|false|none||标签名称| -|»»» labelId|integer|false|none||标签ID| - -## POST 修改好友标签 - -POST /label/modifyMemberList - -#### 注意 -由于好友标签信息存储在用户客户端,因此每次在修改时都需要进行全量修改。举例来说,考虑好友A(wxid_asdfaihp123),该好友已经被标记为标签ID为1和2。 - -在添加标签ID为3时,传递的参数如下:labelIds:1,2,3,wxIds:[wxid_asdfaihp123]。这表示要给好友A添加标签ID为3,同时保留已有的标签ID 1和2。 - -而在删除标签ID为1时,传递的参数如下:labelIds:2,3 ,wxIds:[wxid_asdfaihp123]。这表示要将好友A的标签ID 1删除,而保留标签ID 2。 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "labelIds": "15", - "wxIds": [ - "zhangchuan2288" - ] -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» labelIds|body|string| 是 |标签ID,多个逗号分隔| -|» wxIds|body|[string]| 是 |修改的好友wxid| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -# 基础API/个人模块 - -## POST 获取个人资料 - -POST /personal/getProfile - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "proxyIp": "" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "alias": null, - "wxid": "zhangchuan2288", - "nickName": "朝夕。", - "mobile": "18761670817", - "uin": 1042679712, - "sex": 1, - "province": "Jiangsu", - "city": "Xuzhou", - "signature": ".......", - "country": "CN", - "bigHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/REoLX7KfdibFAgDbtoeXGNjE6sGa8NCib8UaiazlekKjuLneCvicM4xQpuEbZWjjQooSicsKEbKdhqCOCpTHWtnBqdJicJ0I3CgZumwJ6SxR3ibuNs/0", - "smallHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/REoLX7KfdibFAgDbtoeXGNjE6sGa8NCib8UaiazlekKjuLneCvicM4xQpuEbZWjjQooSicsKEbKdhqCOCpTHWtnBqdJicJ0I3CgZumwJ6SxR3ibuNs/132", - "regCountry": "CN", - "snsBgImg": "http://shmmsns.qpic.cn/mmsns/FzeKA69P5uIdqPfQxp59LvOohoE2iaiaj86IBH1jl0F76aGvg8AlU7giaMtBhQ3bPibunbhVLb3aEq4/0" - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» alias|string|true|none||微信号| -|»» wxid|string|true|none||微信ID| -|»» nickName|string|true|none||昵称| -|»» mobile|string|true|none||绑定的手机号| -|»» uin|integer|true|none||uin| -|»» sex|integer|true|none||性别| -|»» province|string|true|none||省份| -|»» city|string|true|none||城市| -|»» signature|string|true|none||签名| -|»» country|string|true|none||国家| -|»» bigHeadImgUrl|string|true|none||大尺寸头像| -|»» smallHeadImgUrl|string|true|none||小尺寸头像| -|»» regCountry|string|true|none||注册国家| -|»» snsBgImg|string|true|none||朋友圈背景图| - -## POST 获取自己的二维码 - -POST /personal/getQrCode - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "proxyIp": "" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "qrCode": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAIAAgADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD5kooor8XP6jCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK1tP03biWUc9lPb61+7FfUYXIaten7SpLlv0tf9UfAZhxdQwlZ0aFP2lt3eyv5aO5+CNFfvdRXZ/q5/wBPv/Jf+CeZ/rv/ANQ3/k//ANqfgjRX73UUf6uf9Pv/ACX/AIIf67/9Q3/k/wD9qfgjRX73UUf6uf8AT7/yX/gh/rv/ANQ3/k//ANqfgjRX73UUf6uf9Pv/ACX/AIIf67/9Q3/k/wD9qfgjRX73UUf6uf8AT7/yX/gh/rv/ANQ3/k//ANqfgjRX73UUf6uf9Pv/ACX/AIIf67/9Q3/k/wD9qfgjRX73UUf6uf8AT7/yX/gh/rv/ANQ3/k//ANqfgjRX73UUf6uf9Pv/ACX/AIIf67/9Q3/k/wD9qfgjRX73UUf6uf8AT7/yX/gh/rv/ANQ3/k//ANqfgjRX73UUf6uf9Pv/ACX/AIIf67/9Q3/k/wD9qfgjRX73UUf6uf8AT7/yX/gh/rv/ANQ3/k//ANqfgjRX73UUf6uf9Pv/ACX/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" - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» qrCode|string|true|none||二维码图片的base64| - -## POST 获取设备记录 - -POST /personal/getSafetyInfo - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "proxyIp": "" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "list": [ - { - "uuid": "087b139951b776e0416b5015d0b98109", - "deviceName": "iPhone 13 Pro", - "deviceType": "iPhone iOS17.2", - "lastTime": 1703218815 - }, - { - "uuid": "f7e4bda161f7a6a7361ca62141cded23", - "deviceName": "张传的MacBook Pro", - "deviceType": "iMac MacBookPro17,1 OSX OSX 13.3.1 build(22E261)", - "lastTime": 1703206819 - }, - { - "uuid": "80d6218be93f570a971d8c605fa542c3", - "deviceName": "iPad", - "deviceType": "iPad iOS14.5.1", - "lastTime": 1703065642 - }, - { - "uuid": "197e97585d02c9cd6e6de68c74c81780", - "deviceName": "iPad", - "deviceType": "iPad iOS14.5.1", - "lastTime": 1701300706 - }, - { - "uuid": "bf5eb4d8498f4affac1cbfb8aa936d2a", - "deviceName": "iPad", - "deviceType": "iPad iPadOS14.3", - "lastTime": 1696729849 - }, - { - "uuid": "33ac7f39ed3d7115d9c15f07981a264a", - "deviceName": "iPad", - "deviceType": "iPad iPadOS14.5.1", - "lastTime": 1695050733 - } - ] - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» list|[object]|true|none||设备记录| -|»»» uuid|string|true|none||设备ID| -|»»» deviceName|string|true|none||设备名称| -|»»» deviceType|string|true|none||设备类型| -|»»» lastTime|integer|true|none||最后操作时间| - -## POST 隐私设置 - -POST /personal/privacySettings - -**option 说明** -- 4: 加我为朋友时需要验证 -- 7: 向我推荐通讯录朋友 -- 8: 添加我的方式 手机号 -- 25: 添加我的方式 微信号 -- 38: 添加我的方式 群聊 -- 39: 添加我的方式 我的二维码 -- 40: 添加我的方式 名片 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "open": true, - "option": 4 -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» option|body|integer| 否 |隐私设置的选项| -|» open|body|boolean| 是 |开关| - -#### 详细说明 - -**» option**: 隐私设置的选项 - 4: 加我为朋友时需要验证 - 7: 向我推荐通讯录朋友 - 8: 添加我的方式 手机号 - 25: 添加我的方式 微信号 - 38: 添加我的方式 群聊 - 39: 添加我的方式 我的二维码 - 40: 添加我的方式 名片 - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 修改个人信息 - -POST /personal/updateProfile - -**注意** 修改个人信息需要单独设置每一项 -比如修改昵称则参数仅传appId和nickName -修改地区则参数可传appId、country、province、city - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "city": "", - "country": "", - "nickName": "", - "province": "", - "sex": 1, - "signature": "......" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» city|body|string| 否 |城市| -|» country|body|string| 是 |国家| -|» nickName|body|string| 是 |昵称| -|» province|body|string| 是 |省份| -|» sex|body|string| 是 |性别 1:男 2:女| -|» signature|body|string| 是 |签名| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 修改头像 - -POST /personal/updateHeadImg - -**注意** 修改头像后需要将手机的微信进程关掉,然后重启查看最新头像 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "headImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/REoLX7KfdibFAgDbtoeXGNjE6sGa8NCib8UaiazlekKjuLneCvicM4xQpuEbZWjjQooSicsKEbKdhqCOCpTHWtnBqdJicJ0I3CgZumwJ6SxR3ibuNs/0" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» headImgUrl|body|string| 否 |头像的图片地址| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -# 基础API/收藏夹模块 - -## POST 同步收藏夹 - -POST /favor/sync - -#### 注意: -响应结果中会包含已删除的的收藏夹记录,通过flag=1来判断已删除 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "syncKey": "" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» syncKey|body|string| 否 |翻页key,首次传空,获取下一页传接口返回的syncKey| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "syncKey": "CAESCAgBEJyi9e4C", - "list": [ - { - "favId": 2, - "type": 1, - "flag": 1, - "updateTime": 1448465918 - }, - { - "favId": 1, - "type": 2, - "flag": 1, - "updateTime": 1448465922 - } - ] - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» syncKey|string|true|none||翻页key| -|»» list|[object]|true|none||none| -|»»» favId|integer|true|none||收藏夹ID| -|»»» type|integer|true|none||收藏内容类型| -|»»» flag|integer|true|none||收藏夹标识| -|»»» updateTime|integer|true|none||收藏时间| - -## POST 获取收藏夹内容 - -POST /favor/getContent - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "favId": 179 -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» favId|body|integer| 是 |收藏夹ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "favId": 179, - "status": 0, - "flag": 0, - "updateTime": 1703235210, - "content": "没说呢1703217521wxid_cy6buf12nf6921zhangchuan22881838546569535807562127" - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|object|true|none||none| -|»» favId|integer|true|none||收藏夹ID| -|»» status|integer|true|none||状态| -|»» flag|integer|true|none||收藏夹标识| -|»» updateTime|integer|true|none||更新时间| -|»» content|string|true|none||收藏的内容| - -## POST 删除收藏夹 - -POST /favor/delete - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}", - "favId": 179 -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| -|» favId|body|integer| 是 |收藏夹ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -# 基础API/账号管理 - -## POST 断线重连 - -POST /login/reconnection - -- 当系统返回账号已离线,但是手机顶部还显示ipad在线,可用此接口尝试重连,若返回错误/失败则必须重新调用[步骤一登录](https://apifox.com/apidoc/shared-69ba62ca-cb7d-437e-85e4-6f3d3df271b1/api-196794502) -- 本接口非常用接口,可忽略 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| - -> 返回示例 - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": { - "uuid": "4YHmGvoXvgmS1MqWVtQ2", - "headImgUrl": "http://wx.qlogo.cn/mmhead/ver_1/ZYUmcl1UNzyB2onM08Ij901TaUOLIjHj2UicK3XGDsjEWl4XgQN5IjodunHicBVsZiaZc1iaGCRfluAxkzyibbiau3WBfFj2nprzKp2KryicMjGIvDbWOQGmibwVK648a3o4A8hD/0", - "nickName": "G", - "expiredTime": 230, - "status": 2, - "loginInfo": { - "uin": 4077276085, - "wxid": "wxid_0xsqb3o0tsvz22", - "nickName": "G", - "mobile": "17114312382", - "alias": null - } - } -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 退出 - -POST /login/logout - -> Body 请求参数 - -```json -{ - "appId": "" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功" -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| - -## POST 检查是否在线 - -POST /login/checkOnline - -响应结果的data=true则是在线,反之为离线 - -> Body 请求参数 - -```json -{ - "appId": "{{appid}}" -} -``` - -### 请求参数 - -|名称|位置|类型|必选|说明| -|---|---|---|---|---| -|X-GEWE-TOKEN|header|string| 是 |none| -|body|body|object| 否 |none| -|» appId|body|string| 是 |设备ID| - -> 返回示例 - -> 200 Response - -```json -{ - "ret": 200, - "msg": "操作成功", - "data": true -} -``` - -### 返回结果 - -|状态码|状态码含义|说明|数据模型| -|---|---|---|---| -|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline| - -### 返回数据结构 - -状态码 **200** - -|名称|类型|必选|约束|中文名|说明| -|---|---|---|---|---|---| -|» ret|integer|true|none||none| -|» msg|string|true|none||none| -|» data|boolean|true|none||none| - -# 数据模型 - diff --git a/gewechat/call_back_message/model.md b/gewechat/call_back_message/model.md deleted file mode 100644 index 2bf724a..0000000 --- a/gewechat/call_back_message/model.md +++ /dev/null @@ -1,1200 +0,0 @@ -# 回调消息详解 - -### 回调消息常见问题 - -Q. **微信在线为什么没有消息推送?** -``` -当回调消息未能通过 HTTP POST/JSON 方式成功推送至接收方时,请考虑使用 Apifox 向接收地址发送一条测试消息。如果仍然未能接收到消息,请检查接收地址的可用性。反之,若能成功接收测试消息,请联系客服,我们将协助您进行进一步的问题排查。 -``` - -Q. **如何判断是否是自己发送的消息?** -``` -可通过消息发送人($.Data.FromUserName.string)与所属微信($.Wxid)是否一致进行判断。 -``` - -Q. **为什么同一条消息会重复回调?** -``` -因服务重启、同步历史消息、失败重试等原因,同一条消息可能会重复推送,接收方需根据$.Appid+$.Data.NewMsgId字段做消息排重,以防消息重复处理。 -``` - ---- - -#### 文本消息 -```json - { - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356095, 消息ID - "FromUserName": - { - "string": "wxid_phyyedw9xap22" 消息发送人的wxid - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 1, 消息类型 1是文本消息 - "Content": - { - "string": "123" # 消息内容 - }, - "Status": 3, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705043418, 消息发送时间 - "MsgSource": "\n\t\n\t\t1\n\t\n\tv1_volHXhv4\n\t\n\t\t\n\t\n\n", - "PushContent": "朝夕。 : 123", 消息通知内容 - "NewMsgId": 7773749793478223190, 消息ID - "MsgSeq": 640356095 - } - } -``` - - -#### 图片消息 -```json -{ - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356099, 消息ID - "FromUserName": - { - "string": "wxid_phyyedw9xap22" 消息发送人的wxid - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 3, 消息类型 3是图片消息 - "Content": - { - "string": "\n\n\t\n\t\n\t\n\n" 图片的cdn信息,可用此字段做转发图片 - }, - "Status": 3, - "ImgStatus": 2, - "ImgBuf": - { - "iLen": 2146, - "buffer": "/9j/4AAQSkZJRgABAQAASABIAAD/4QBM..." # 缩略图的base64 - }, - "CreateTime": 1705043678, 消息发送时间 - "MsgSource": "\n\t\n\t\t2\n\t\n\t\n\t\t5b04ea0181f86c7f3d126e9a7fe5038b_\n\t\n\tv1_5WGxwSEj\n\t\n\t\t\n\t\n\n", - "PushContent": "朝夕。 : [图片]", 消息通知内容 - "NewMsgId": 6906713067183447582, 消息ID - "MsgSeq": 640356099 - } -} -``` - -#### 语音消息 -```json -{ - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356100, 消息ID - "FromUserName": - { - "string": "wxid_phyyedw9xap22" 消息发送人的wxid - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 34, 消息类型,34是语音消息 - "Content": - { - "string": "" 语音消息的下载信息,可用于下载语音文件 - }, - "Status": 3, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 3600, - "buffer": "AiMhU0lMS19WMxMApzi9JA+qToPB..." 语音文件的base64,并非所有语音消息都有本字段 - }, - "CreateTime": 1705043782, 消息发送时间 - "MsgSource": "\n\tv1_j+rf/Jnp\n\t\n\t\t\n\t\n\n", - "PushContent": "朝夕。 : [语音]", 消息通知内容 - "NewMsgId": 1428830975092239121, 消息ID - "MsgSeq": 640356100 - } -} -``` - -#### 视频消息 -```json -{ - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356101, 消息ID - "FromUserName": - { - "string": "wxid_phyyedw9xap22" 消息发送人的wxid - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 43, 消息类型,43是视频消息 - "Content": - { - "string": "\n\n\t\n\n" 视频消息的cdn信息,可用此字段做转发视频 - }, - "Status": 3, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705043879, 消息发送时间 - "MsgSource": "\n\t0\n\t\n\t\tce3ebc6d2893c7a2669ac5d2eaa4aadf_\n\t\n\tv1_kk/psF9W\n\t\n\t\t\n\t\n\n", - "PushContent": "朝夕。 : [视频]", 消息通知内容 - "NewMsgId": 6628526085342711793, 消息ID - "MsgSeq": 640356101 - } -} -``` - -#### emoji表情 -```json -{ - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356102, 消息ID - "FromUserName": - { - "string": "wxid_phyyedw9xap22" 消息发送人的wxid - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 47, 消息类型,47是emoji消息 - "Content": - { - "string": " " 可解析xml中的md5用与发送emoji消息 - }, - "Status": 3, - "ImgStatus": 2, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705043947, 消息发送时间 - "MsgSource": "\n\tv1_vy/xC7WS\n\t\n\t\t\n\t\n\n", - "PushContent": "朝夕。 : [动画表情]", 消息通知内容 - "NewMsgId": 6674256223577965652, 消息ID - "MsgSeq": 640356102 - } -} -``` - -#### 公众号链接 -- 判断链接消息的逻辑:\$.Data.MsgType=49 并且 解析\$.Data.Content.string中的xml msg.appmsg.type=5,按此逻辑会匹配到两种消息,链接消息及邀请进群的通知,可依据xml msg.appmsg.title做区分 -```json -{ - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356105, 消息ID - "FromUserName": - { - "string": "wxid_phyyedw9xap22" 消息发送人的wxid - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 49, - "Content": - { - "string": "\n\n\t\n\t\t尔滨,又有好消息!\n\t\t\n\t\t\n\t\t5\n\t\t0\n\t\t0\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t0\n\t\thttp://mp.weixin.qq.com/s?__biz=MzA4NDI3NjcyNA==&mid=2650011300&idx=1&sn=52739c3d39c030394da972e3d83efc98&chksm=86ed931f730a3e19a5edc840896d9bf1ad1f8b60cdccafea6a9e7a38a0a33f261877d334622b&scene=0&xtrack=1#rd\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\t0\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t3057020100044b304902010002048399cc8402032f7e350204a810d83a020465a0e829042462343663343435612d333737392d346230612d616434622d6263383038633562643562340204051408030201000405004c53d900\n\t\t\tadd1b4bcf9cc50c6a8f14ff334bc3d5c\n\t\t\t83741\n\t\t\t1000\n\t\t\t426\n\t\t\t37889a1e22c1e58ebd4e6589b999f63e\n\t\t\t\n\t\t\n\t\t\n\t\tgh_6651e07e4b2d\n\t\t新华社\n\t\thttps://mmbiz.qpic.cn/mmbiz_jpg/azXQmS1HA7mOP6LHArYqZ5ypK4iajvBdfhNxzyANcQ1eW7ec6yZVj7tv8Lt6tWftSNckDz3j4FqkP04TxARG8dQ/640?wxtype=jpeg&wxfrom=0\n\t\t\n\t\t\n\t\t\n\t\t\t0\n\t\t\n\t\n\twxid_phyyedw9xap22\n\t0\n\t\n\t\t1\n\t\t\n\t\n\t\n\n" 可用此字段做转发链接 - }, - "Status": 3, - "ImgStatus": 2, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705044033, 消息发送时间 - "MsgSource": "\n\t\n\t\t\n\t\n\t\n\t\t4\n\t\n\t\n\t\tba15c632e8fa89ed84bd027f09495591_\n\t\n\tv1_ptaEL1bv\n\n", - "PushContent": "朝夕。 : [链接]尔滨,又有好消息!", 消息通知内容 - "NewMsgId": 1623411326098221490, 消息ID - "MsgSeq": 640356105 - } -} -``` - -#### 文件消息(发送文件的通知) -- **注意**:收到本条消息仅代表对方在向你发送文件,并不可以用本条做转发及下载 -- 判断此类消息的逻辑:\$.Data.MsgType=49 并且 解析\$.Data.Content.string中的xml msg.appmsg.type=74 -```json -{ - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356106, 消息ID - "FromUserName": - { - "string": "wxid_phyyedw9xap22" 消息发送人的wxid - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 49, - "Content": - { - "string": "\n \n <![CDATA[hhh.xlsx]]>\n 74\n 0\n \n 8939\n \n v1_paVQtd+CWGr2I3eOg71E6KBpQf0yY9RFQkqDPwT4yMnnbawqveao1vAE0qCOhWcIPkMGZavimUTDFcImr+SaManD8pKVQbBPTUvSmA6UsXgZWqQDOT00VLx7U/hoP3/CwveN2Lk56nxcef/XJiGKrOpAHKHcZvccaGk9/68wsBCOyanya/9xgdHTYxyQp4IadiSe\n 0\n \n \n \n \n wxid_phyyedw9xap22\n" - }, - "Status": 3, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705044119, 消息发送时间 - "MsgSource": "\n\tv1_WyLyIcy+\n\t\n\t\t\n\t\n\n", - "PushContent": "朝夕。 : [文件]hhh.xlsx", 消息通知内容 - "NewMsgId": 1789783684714859663, 消息ID - "MsgSeq": 640356106 - } -} -``` - -#### 文件消息(文件发送完成) -- **注意**:收到本条消息表示对方给你的文件发送完成,可用本条消息做转发及下载 -- 判断此类消息的逻辑:\$.Data.MsgType=49 并且 解析\$.Data.Content.string中的xml msg.appmsg.type=6 -```json -{ - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356107, 消息ID - "FromUserName": - { - "string": "wxid_phyyedw9xap22" 消息发送人的wxid - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 49, - "Content": - { - "string": "\n\n\t\n\t\thhh.xlsx\n\t\t\n\t\t\n\t\t6\n\t\t0\n\t\t0\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t0\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\t8939\n\t\t\t@cdn_3057020100044b304902010002043904752002032f7e350204aa0dd83a020465a0e897042430373538386564322d353866642d343234342d386563652d6236353536306438623936610204011800050201000405004c56f900_3f28b0cbd65a86c3a980f3e22808c0fe_1\n\t\t\t\n\t\t\txlsx\n\t\t\t3057020100044b304902010002043904752002032f7e350204aa0dd83a020465a0e897042430373538386564322d353866642d343234342d386563652d6236353536306438623936610204011800050201000405004c56f900\n\t\t\t3f28b0cbd65a86c3a980f3e22808c0fe\n\t\t\t0\n\t\t\t1789783684714859663\n\t\t\tv1_paVQtd+CWGr2I3eOg71E6KBpQf0yY9RFQkqDPwT4yMnnbawqveao1vAE0qCOhWcIPkMGZavimUTDFcImr+SaManD8pKVQbBPTUvSmA6UsXgZWqQDOT00VLx7U/hoP3/CwveN2Lk56nxcef/XJiGKrOpAHKHcZvccaGk9/68wsBCOyanya/9xgdHTYxyQp4IadiSe\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t84c6737fe9549270c9b3ca4f6fc88f6f\n\t\t\n\t\n\twxid_phyyedw9xap22\n\t0\n\t\n\t\t1\n\t\t\n\t\n\t\n\n" - }, - "Status": 3, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705044119, 消息发送时间 - "MsgSource": "\n\t\n\t\t3\n\t\n\t\n\t\t896374a2b5979141804d509256c22f0b_\n\t\n\tv1_n7kZ01bp\n\t\n\t\t\n\t\n\n", - "PushContent": "朝夕。 : [文件]hhh.xlsx", 消息通知内容 - "NewMsgId": 3617029648443513152, 消息ID - "MsgSeq": 640356107 - } -} -``` - -#### 名片消息 -```json - { - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356108, 消息ID - "FromUserName": - { - "string": "wxid_phyyedw9xap22" 消息发送人的wxid - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 42, 消息类型,42是名片消息 - "Content": - { - "string": "\n\n" 名片中微信号的基本信息,可用于添加好友 - }, - "Status": 3, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705044829, 消息发送时间 - "MsgSource": "\n\t0\n\t\n\t\t2\n\t\n\tv1_bawbB33Z\n\t\n\t\t\n\t\n\n", - "PushContent": "朝夕。 : [名片]Ashley", 消息通知内容 - "NewMsgId": 766322251431765776, 消息ID - "MsgSeq": 640356108 - } - } -``` - -#### 好友添加请求通知 -```json -{ - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356166, 消息ID - "FromUserName": - { - "string": "fmessage" 消息发送人的wxid - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 37, 消息类型,37是好友添加请求通知 - "Content": - { - "string": "" 请求添加好友微信号的基本信息,可用于添加好友 - }, - "Status": 3, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705045979, 消息发送时间 - "MsgSource": "\n\tv1_GOrHWRNL\n\t\n\t\t\n\t\n\n", - "NewMsgId": 1109510141823131559, 消息ID - "MsgSeq": 640356166 - } -} -``` - -#### 好友通过验证及好友资料变更的通知消息 -```json -{ - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", - "TypeName": "ModContacts", - "Data": - { - "UserName": - { - "string": "wxid_0xsqb3o0tsvz22" - }, - "NickName": - { - "string": "chaoxi。" - }, - "PyInitial": - { - "string": "CX" - }, - "QuanPin": - { - "string": "chaoxi" - }, - "Sex": 1, - "ImgBuf": - { - "iLen": 0 - }, - "BitMask": 4294967295, - "BitVal": 3, - "ImgFlag": 1, - "Remark": - {}, - "RemarkPyinitial": - {}, - "RemarkQuanPin": - {}, - "ContactType": 0, - "RoomInfoCount": 0, - "DomainList": [ - {}], - "ChatRoomNotify": 0, - "AddContactScene": 0, - "Province": "Jiangsu", - "City": "Nanjing", - "Signature": "......", - "PersonalCard": 0, - "HasWeiXinHdHeadImg": 1, - "VerifyFlag": 0, - "Level": 6, - "Source": 14, - "WeiboFlag": 0, - "AlbumStyle": 0, - "AlbumFlag": 3, - "SnsUserInfo": - { - "SnsFlag": 1, - "SnsBgimgId": "http://shmmsns.qpic.cn/mmsns/FzeKA69P5uIdqPfQxp59LvOohoE2iaiaj86IBH1jl0F76aGvg8AlU7giaMtBhQ3bPibunbhVLb3aEq4/0", - "SnsBgobjectId": 14216284872728580667, - "SnsFlagEx": 7297 - }, - "Country": "CN", - "BigHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/qqncCu2avRYruPcQbav3PrwaGSS31QgN6dqW8q1XuDKjgiaAuwoFPw3kN8Cj3zIBL36M93R2Xwib0IddUK3gqbFeezEiaA8K2mMdibT5VUDDrbn7F7M1Mxicmows9cdYNOicjI/0", - "SmallHeadImgUrl": "https://wx.qlogo.cn/mmhead/ver_1/qqncCu2avRYruPcQbav3PrwaGSS31QgN6dqW8q1XuDKjgiaAuwoFPw3kN8Cj3zIBL36M93R2Xwib0IddUK3gqbFeezEiaA8K2mMdibT5VUDDrbn7F7M1Mxicmows9cdYNOicjI/132", - "CustomizedInfo": - { - "BrandFlag": 0 - }, - "EncryptUserName": "v3_020b3826fd03010000000000feba078fc1e760000000501ea9a3dba12f95f6b60a0536a1adb6f6352c38d0916c9c74045d85aa602efa2d81b84adde05d285124e8a54b9fcd039f725d6ac0d3bd651c7c74503a@stranger", - "AdditionalContactList": - { - "LinkedinContactItem": - {} - }, - "ChatroomMaxCount": 0, - "DeleteFlag": 0, - "Description": "\b\u0000\u0018\u0000\"\u0000(\u00008\u0000", - "ChatroomStatus": 0, - "Extflag": 0, - "ChatRoomBusinessType": 0 - } -} -``` - - -#### 小程序消息 -- 判断此类消息的逻辑:\$.Data.MsgType=49 并且 解析\$.Data.Content.string中的xml msg.appmsg.type=33/36 -```json -{ - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356109, 消息ID - "FromUserName": - { - "string": "wxid_phyyedw9xap22" 消息发送人的wxid - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 49, - "Content": - { - "string": "\n\n\t\n\t\t腾讯云助手\n\t\t腾讯云助手\n\t\t33\n\t\thttps://mp.weixin.qq.com/mp/waerrpage?appid=wxe2039b83454e49ed&type=upgrade&upgradetype=3#wechat_redirect\n\t\t\n\t\t\t3057020100044b304902010002048399cc8402032df731020414e461b4020465a0eb8f042463626430353633382d376263632d346161642d396234372d3435613131336339326231640204051808030201000405004c550500\n\t\t\te1284d4ae13ebd9bb2cde5251cdd05e4\n\t\t\t52357\n\t\t\t720\n\t\t\t576\n\t\t\td4142726bc730088f0fa44c9161a0992\n\t\t\td4142726bc730088f0fa44c9161a0992\n\t\t\t0\n\t\t\twxid_0xsqb3o0tsvz22_38_1705044879\n\t\t\n\t\tgh_44fc2ced7f87@app\n\t\t腾讯云助手\n\t\te1284d4ae13ebd9bb2cde5251cdd05e4\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t2\n\t\t\t594\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t0\n\t\t\t0\n\t\t\t538\n\t\t\t0\n\t\t\t0\n\t\t\t0\n\t\t\t0\n\t\t\n\t\n\twxid_phyyedw9xap22\n\t0\n\t\n\t\t1\n\t\t\n\t\n\t\n\n" - }, - "Status": 3, - "ImgStatus": 2, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705044879, 消息发送时间 - "MsgSource": "\n\t0\n\t\n\t\t2\n\t\n\t\n\t\tdb46d46fe0a926c4b571dfe9d8096bfa_\n\t\n\tv1_DkelOoZN\n\t\n\t\t\n\t\n\n", - "PushContent": "朝夕。 : [小程序]腾讯云助手", 消息通知内容 - "NewMsgId": 572974861799389774, 消息ID - "MsgSeq": 640356109 - } -} -``` - -#### 引用消息 -- 判断此类消息的逻辑:\$.Data.MsgType=49 并且 解析\$.Data.Content.string中的xml msg.appmsg.type=57 -```json -{ - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356110, 消息ID - "FromUserName": - { - "string": "wxid_phyyedw9xap22" 消息发送人的wxid - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 49, - "Content": - { - "string": "\n\n\t\n\t\t看看这个\n\t\t\n\t\t\n\t\t57\n\t\t0\n\t\t0\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t0\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\t0\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\t49\n\t\t\t3617029648443513152\n\t\t\twxid_phyyedw9xap22\n\t\t\twxid_phyyedw9xap22\n\t\t\t朝夕。\n\t\t\t<msg><appmsg appid=\"\" sdkver=\"0\"><title>hhh.xlsx</title><des></des><action></action><type>6</type><showtype>0</showtype><soundtype>0</soundtype><mediatagname></mediatagname><messageext></messageext><messageaction></messageaction><content></content><contentattr>0</contentattr><url></url><lowurl></lowurl><dataurl></dataurl><lowdataurl></lowdataurl><appattach><totallen>8939</totallen><attachid>@cdn_3057020100044b304902010002043904752002032f7e350204aa0dd83a020465a0e897042430373538386564322d353866642d343234342d386563652d6236353536306438623936610204011800050201000405004c56f900_3f28b0cbd65a86c3a980f3e22808c0fe_1</attachid><emoticonmd5></emoticonmd5><fileext>xlsx</fileext><cdnattachurl>3057020100044b304902010002043904752002032f7e350204aa0dd83a020465a0e897042430373538386564322d353866642d343234342d386563652d6236353536306438623936610204011800050201000405004c56f900</cdnattachurl><aeskey>3f28b0cbd65a86c3a980f3e22808c0fe</aeskey><encryver>0</encryver><overwrite_newmsgid>1789783684714859663</overwrite_newmsgid><fileuploadtoken>v1_paVQtd+CWGr2I3eOg71E6KBpQf0yY9RFQkqDPwT4yMnnbawqveao1vAE0qCOhWcIPkMGZavimUTDFcImr+SaManD8pKVQbBPTUvSmA6UsXgZWqQDOT00VLx7U/hoP3/CwveN2Lk56nxcef/XJiGKrOpAHKHcZvccaGk9/68wsBCOyanya/9xgdHTYxyQp4IadiSe</fileuploadtoken></appattach><extinfo></extinfo><sourceusername></sourceusername><sourcedisplayname></sourcedisplayname><thumburl></thumburl><md5>84c6737fe9549270c9b3ca4f6fc88f6f</md5><statextstr></statextstr></appmsg><fromusername></fromusername><appinfo><version>0</version><appname></appname><isforceupdate>1</isforceupdate></appinfo></msg>\n\t\t\t<msgsource>\n\t<alnode>\n\t\t<cf>3</cf>\n\t</alnode>\n\t<sec_msg_node>\n\t\t<uuid>896374a2b5979141804d509256c22f0b_</uuid>\n\t</sec_msg_node>\n</msgsource>\n\n\t\t\n\t\n\twxid_phyyedw9xap22\n\t0\n\t\n\t\t1\n\t\t\n\t\n\t\n\n" - }, - "Status": 3, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705044946, 消息发送时间 - "MsgSource": "\n\t\n\t\tea25ade83dc4b9ec91060ca3e1a0f5a2_\n\t\n\tv1_oTWRYdd1\n\t\n\t\t\n\t\n\n", - "PushContent": "看看这个", 消息通知内容 - "NewMsgId": 4334300109515885085, 消息ID - "MsgSeq": 640356110 - } -} -``` - -#### 转账消息 -- 判断此类消息的逻辑:\$.Data.MsgType=49 并且 解析\$.Data.Content.string中的xml msg.appmsg.type=2000 -```json - { - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356112, 消息ID - "FromUserName": - { - "string": "wxid_phyyedw9xap22" 消息发送人的wxid - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 49, - "Content": - { - "string": "\n\n<![CDATA[微信转账]]>\n\n\n2000\n\n\n\n\n\n\n\n1\n\n\n\n\n\n\n\n\n\n\n\n\n\n" - }, - "Status": 3, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705044984, 消息发送时间 - "MsgSource": "\n\tv1_eDcIna+F\n\t\n\t\t\n\t\n\n", - "PushContent": "朝夕。 : [转账]", 消息通知内容 - "NewMsgId": 7290406378327063279, 消息ID - "MsgSeq": 640356112 - } - } -``` - -#### 红包消息 -- 判断此类消息的逻辑:\$.Data.MsgType=49 并且 解析\$.Data.Content.string中的xml msg.appmsg.type=2001 -```json - { - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356113, 消息ID - "FromUserName": - { - "string": "wxid_phyyedw9xap22" 消息发送人的wxid - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 49, - "Content": - { - "string": "\n\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t<![CDATA[微信红包]]>\n\t\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t微信红包\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\n\t\n\n" - }, - "Status": 3, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705045011, 消息发送时间 - "MsgSource": "\n\t\n\t\n\tv1_Js6wJde/\n\t\n\t\t\n\t\n\n", - "PushContent": "朝夕。 : [红包]恭喜发财,大吉大利", 消息通知内容 - "NewMsgId": 5517720959405775296, 消息ID - "MsgSeq": 640356113 - } - } -``` - -#### 视频号消息 -- 判断此类消息的逻辑:\$.Data.MsgType=49 并且 解析\$.Data.Content.string中的xml msg.appmsg.type=51 -```json - { - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356115, 消息ID - "FromUserName": - { - "string": "wxid_phyyedw9xap22" 消息发送人的wxid - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 49, - "Content": - { - "string": "\n\n\t\n\t\t当前微信版本不支持展示该内容,请升级至最新版本。\n\t\t\n\t\t\n\t\t51\n\t\t0\n\t\t0\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t0\n\t\thttps://support.weixin.qq.com/update/\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\t0\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\t14264358459626428566\n\t\t\t4\n\t\t\t国风锦鲤\n\t\t\thttps://wx.qlogo.cn/finderhead/ver_1/x2LxetmLmgoo9jp69R3wcrtZ0LBLdjVv9vrK9HmPNGEdD1iawdrPffPvMmFUez8pWqRIfs7DtgPiaV5C7DZpibH8b3y0jG178aIict6uPf0Vht4/0\n\t\t\t还招人么?我不要工资#逆水寒cos\n\t\t\t1\n\t\t\t8046877030770906689_0_0_0_0_0\n\t\t\t0\n\t\t\tv2_060000231003b20faec8cae08b19c7d2c702e834b077fb74f482543ff67f0cc66363057a5443@finder\n\t\t\t\n\t\t\t0\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t4\n\t\t\t\t\thttp://wxapp.tc.qq.com/251/20302/stodownload?encfilekey=Cvvj5Ix3eez3Y79SxtvVL0L7CkPM6dFibFeI6caGYwFFDAZJzcvicKz3jic4UfNeiaWTwH9gTlYiafAxVkMZRXicBUBk2Ms7lauAj6SArUu0P9ddKiaa8IWZzYaaKLf1WddH4G8T0KicxQV3hQPH3pQgEMTscw&a=1&bizid=1023&dotrans=0&hy=SH&idx=1&m=4c4c7f3ed03a14a6b99d0d19176c12ac&upid=290110\n\t\t\t\t\thttp://wxapp.tc.qq.com/251/20304/stodownload?encfilekey=oibeqyX228riaCwo9STVsGLPj9UYCicgttvO59vjtcQ7Jviaia0q4bnpVP2ia7ibqzacPo0z4nIRtWom80ZXwL64icZO2q6ibVBQLZQftMwU3SHj5uplsIFroHeF0QNcCkXX3RtibaWCHJQjfqZUk&bizid=1023&dotrans=0&hy=SH&idx=1&m=7522250b4d15e5df866bf23da9f117d6&token=oA9SZ4icv8IssuhLtacX13nAzXiaf8y52juKW4ibUDN7a2vn71bbrCR0LZiabddvTsLLMvnELnuAwNxViclRT7wT9IyibzFw1pq9wdichRYaEmb6Js&ctsc=2-20\n\t\t\t\t\t1080\n\t\t\t\t\t1920\n\t\t\t\t\thttp://wxapp.tc.qq.com/251/20304/stodownload?encfilekey=oibeqyX228riaCwo9STVsGLPj9UYCicgttvO59vjtcQ7Jviaia0q4bnpVP2ia7ibqzacPo0z4nIRtWom80ZXwL64icZO2q6ibVBQLZQftMwU3SHj5uplsIFroHeF0QNcCkXX3RtibaWCHJQjfqZUk&bizid=1023&dotrans=0&hy=SH&idx=1&m=7522250b4d15e5df866bf23da9f117d6&token=oA9SZ4icv8IssuhLtacX13nAzXiaf8y52juKW4ibUDN7a2vn71bbrCR0LZiabddvTsLLMvnELnuAwNxViclRT7wT9IyibzFw1pq9wdichRYaEmb6Js&ctsc=2-20\n\t\t\t\t\thttp://wxapp.tc.qq.com/251/20350/stodownload?encfilekey=oibeqyX228riaCwo9STVsGLPj9UYCicgttv1FCQXwResqN75zI4n65zY5tkAficEPWbbClq2VcicqMYaSLK7nrAVMasrIhvsCXJib5cOLib98JgWPr4SP92W6YEkVN5Uv0TKAdyRryQ3Qxk7jU&bizid=1023&dotrans=0&hy=SH&idx=1&m=731b89683dd3cb866cdf96dab70ac183&token=KkOFht0mCXlnmicFbJnvymIJOEfZgzia8PY0ZzOdaIYTJXwfblvK4U1ibntribm1beupHwictGWs9hpMiclyhfSb6766Lnb3ib0j14bENm6u1tHpeo&ctsc=3-20\n\t\t\t\t\t10>>\n\t\t\t\t\n\t\t\t\n\t\t\n\t\n\twxid_phyyedw9xap22\n\t0\n\t\n\t\t1\n\t\t\n\t\n\t\n\n" - }, - "Status": 3, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705045057, 消息发送时间 - "MsgSource": "\n\t\n\t\t\n\t\n\t\n\t\t4\n\t\n\t\n\t\tbb2cbd9d3290e7a3d35f183eaade2213_\n\t\n\tv1_+Tfo41HS\n\n", - "PushContent": "你收到了一条消息", 消息通知内容 - "NewMsgId": 5576224237104747184, 消息ID - "MsgSeq": 640356115 - } - } -``` - -#### 撤回消息 -- 判断此类消息的逻辑:\$.Data.MsgType=10002 并且 解析\$.Data.Content.string中的xml sysmsg.type=revokemsg -```json - { - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356116, 消息ID - "FromUserName": - { - "string": "wxid_phyyedw9xap22" 消息发送人的wxid - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 10002, - "Content": - { - "string": "wxid_phyyedw9xap2210403561155576224237104747184" - }, - "Status": 3, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705045083, 消息发送时间 - "MsgSource": "\n\t\n\t\t\n\t\n\n", - "NewMsgId": 1968256046, 消息ID - "MsgSeq": 640356116 - } - } -``` - -#### 拍一拍消息 -- 判断此类消息的逻辑:\$.Data.MsgType=10002 并且 解析\$.Data.Content.string中的xml sysmsg.type=pat -```json -{ - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356117, 消息ID - "FromUserName": - { - "string": "wxid_phyyedw9xap22" 消息发送人的wxid - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 10002, - "Content": - { - "string": "\n\n wxid_phyyedw9xap22\n wxid_0xsqb3o0tsvz22\n wxid_0xsqb3o0tsvz22\n \n 0\n\n\n\n\n \n\n\n\n\n\n" - }, - "Status": 3, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705045115, 消息发送时间 - "MsgSource": "\n\t\n\t\t\n\t\n\n", - "NewMsgId": 5709690173850254331, 消息ID - "MsgSeq": 640356117 - } -} -``` - -#### 地理位置 -```json -{ - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356118, 消息ID - "FromUserName": - { - "string": "wxid_phyyedw9xap22" 消息发送人的wxid - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 48, 消息类型,48是地理位置消息 - "Content": - { - "string": "\n\n\t\n\n" - }, - "Status": 3, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705045153, 消息发送时间 - "MsgSource": "\n\t0\n\tv1_KgQA8C+H\n\t\n\t\t\n\t\n\n", - "PushContent": "朝夕。分享了一个地理位置", 消息通知内容 - "NewMsgId": 2112726776406556053, 消息ID - "MsgSeq": 640356118 - } -} -``` - -#### 群聊邀请 -- 判断此类消息的逻辑:\$.Data.MsgType=49 并且 解析\$.Data.Content.string中的xml msg.appmsg.title=邀请你加入群聊(根据手机设置的系统语言title会有调整,不同语言关键字不同) -```json -{ - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356119, 消息ID - "FromUserName": - { - "string": "wxid_phyyedw9xap22" 消息发送人的wxid - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 49, - "Content": - { - "string": "<![CDATA[邀请你加入群聊]]>view500" - }, - "Status": 3, - "ImgStatus": 0, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705045206, 消息发送时间 - "MsgSource": "\n\tv1_uHiWbihr\n\t\n\t\t\n\t\n\n", - "NewMsgId": 2331390497668538400, 消息ID - "MsgSeq": 640356119 - } -} -``` - -#### 被移除群聊通知 -- 判断此类消息的逻辑:\$.Data.MsgType=10000 并且 \$.Data.Content.string内容为移除群聊的通知内容 -```json -{ - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356153, 消息ID - "FromUserName": - { - "string": "39238473509@chatroom" 所在群聊的ID - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 10000, - "Content": - { - "string": "你被\"朝夕。\"移出群聊" - }, - "Status": 4, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705045790, 消息发送时间 - "MsgSource": "\n\tv1_f7Xny9H/\n\t\n\t\t\n\t\n\n", - "NewMsgId": 5759605552965664254, 消息ID - "MsgSeq": 640356153 - } -} -``` - -#### 踢出群聊通知 -- 判断此类消息的逻辑:\$.Data.MsgType=10002 并且 解析\$.Data.Content.string中的xml sysmsg.type=sysmsgtemplate 并且 template中的内容为“你将xxx移出了群聊”(根据手机设置的系统语言template会有调整,不同语言关键字不同) -```json -{ - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356143, 消息ID - "FromUserName": - { - "string": "34757816141@chatroom" 所在群聊的ID - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 10002, - "Content": - { - "string": "34757816141@chatroom:\n\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\n\n" - }, - "Status": 4, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705045666, 消息发送时间 - "MsgSource": "\n\t\n\t\t\n\t\n\n", - "NewMsgId": 7100572668516374210, 消息ID - "MsgSeq": 640356143 - } -} -``` - -#### 解散群聊通知 -- 判断此类消息的逻辑:\$.Data.MsgType=10002 并且 解析\$.Data.Content.string中的xml sysmsg.type=sysmsgtemplate 并且 template中的内容为“群主xxx已解散该群聊”(根据手机设置的系统语言template会有调整,不同语言关键字不同) -```json -{ - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356158, 消息ID - "FromUserName": - { - "string": "39238473509@chatroom" 所在群聊的ID - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 10002, - "Content": - { - "string": "39238473509@chatroom:\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n" - }, - "Status": 4, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705045834, 消息发送时间 - "MsgSource": "\n\t\n\t\t\n\t\n\n", - "NewMsgId": 6869316888754169027, 消息ID - "MsgSeq": 640356158 - } -} -``` - -#### 修改群名称 -- 判断此类消息的逻辑:\$.Data.MsgType=10000 并且 \$.Data.Content.string为修改群名的通知内容 -```json -{ - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356129, 消息ID - "FromUserName": - { - "string": "34757816141@chatroom" 所在群聊的ID - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 10000, - "Content": - { - "string": "你修改群名为“GeWe test1”" - }, - "Status": 4, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705045517, 消息发送时间 - "MsgSource": "\n\tv1_3uPmlxJG\n\t\n\t\t\n\t\n\n", - "NewMsgId": 6984814725261047392, 消息ID - "MsgSeq": 640356129 - } -} -``` - -#### 更换群主通知 -- 判断此类消息的逻辑:\$.Data.MsgType=10000 并且 \$.Data.Content.string为更换群主的通知内容 -```json - { - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356125, 消息ID - "FromUserName": - { - "string": "34757816141@chatroom" 所在群聊的ID - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 消息接收人的wxid - }, - "MsgType": 10000, - "Content": - { - "string": "你已成为新群主" - }, - "Status": 4, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705045441, 消息发送时间 - "MsgSource": "\n\tv1_iqIx6JkV\n\t\n\t\t\n\t\n\n", - "NewMsgId": 7268255507978211143, 消息ID - "MsgSeq": 640356125 - } - } -``` - -#### 群信息变更通知 -```json -{ - "TypeName": "ModContacts", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "UserName": - { - "string": "34757816141@chatroom" 所在群聊的ID - }, - "NickName": - { - "string": "GeWe test" - }, - "PyInitial": - { - "string": "GEWETEST" - }, - "QuanPin": - { - "string": "GeWetest" - }, - "Sex": 0, - "ImgBuf": - { - "iLen": 0 - }, - "BitMask": 4294967295, - "BitVal": 2, - "ImgFlag": 1, - "Remark": - {}, - "RemarkPyinitial": - {}, - "RemarkQuanPin": - {}, - "ContactType": 0, - "RoomInfoCount": 0, - "DomainList": [ - {}], - "ChatRoomNotify": 1, - "AddContactScene": 0, - "PersonalCard": 0, - "HasWeiXinHdHeadImg": 0, - "VerifyFlag": 0, - "Level": 0, - "Source": 0, - "ChatRoomOwner": "wxid_0xsqb3o0tsvz22", - "WeiboFlag": 0, - "AlbumStyle": 0, - "AlbumFlag": 0, - "SnsUserInfo": - { - "SnsFlag": 0, - "SnsBgobjectId": 0, - "SnsFlagEx": 0 - }, - "CustomizedInfo": - { - "BrandFlag": 0 - }, - "AdditionalContactList": - { - "LinkedinContactItem": - {} - }, - "ChatroomMaxCount": 700000019, - "DeleteFlag": 2, - "Description": "\b\u0004\u0012\u0017\n\u000Ewxid_phyyedw9xap220\u0001@\u0000�\u0001\u0000\u0012\u001B\n\u0012wxid_phyyedw9xap220\u0001@\u0000�\u0001\u0000\u0012\u001C\n\u0013wxid_0xsqb3o0tsvz220\u0001@\u0000�\u0001\u0000\u0012\u001D\n\u0013wxid_8pvka4jg6qzt220�\u0010@\u0000�\u0001\u0000\u0018\u0001\"\u0000(\u00008\u0000", - "ChatroomStatus": 27, - "Extflag": 0, - "ChatRoomBusinessType": 0 - } -} -``` - -#### 发布群公告 -- 判断此类消息的逻辑:\$.Data.MsgType=10002 并且 解析\$.Data.Content.string中的xml sysmsg.type=mmchatroombarannouncememt -```json -{ - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356133, 消息ID - "FromUserName": - { - "string": "wxid_0xsqb3o0tsvz22" 发布人的wxid - }, - "ToUserName": - { - "string": "34757816141@chatroom" 所在群聊的ID - }, - "MsgType": 10002, - "Content": - { - "string": "\n \n \n \n\t1705045558\n\t127\n\t1\n\t\n\t\twxid_0xsqb3o0tsvz22\n\t\t34757816141@chatroom\n\t\t7c79fed82a0037648954bba6d5ca2025\n\t\n\t\n\t\t\n\t\t\t.htm\n\t\t\thttp://wxapp.tc.qq.com/264/20303/stodownload?m=145a874d4eb1bb0b85af928331a168aa&filekey=3033020101041f301d02020108040253480410145a874d4eb1bb0b85af928331a168aa020120040d00000004627466730000000132&hy=SH&storeid=265a0ee36000a9c94f3064bb50000010800004f4f534825960b01e676a0b3b&bizid=1023\n\t\t\t24808ae91ac7d636c99a1b340a1f9253\n\t\t\t8fac8374ded0d5e8d5038b1ec2b77a62\n\t\t\tef033738f28bb3c80cd5e7290fdbfdcf\n\t\t\tef033738f28bb3c80cd5e7290fdbfdcf\n\t\t\t20\n\t\t\n\t\t\n\t\t\t群公告哈1\n\t\t\t\n\t\t\n\t\n\t\n\t\t\n\t\t\t-1\n\t\t\n\t\n\twxid_0xsqb3o0tsvz22_34757816141@chatroom_1705045558_2028281562\n\n]]>\n \n \n" - }, - "Status": 3, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705045559, 消息发送时间 - "MsgSource": "\n\t\n\t\t\n\t\n\n", - "NewMsgId": 8056409355261218186, 消息ID - "MsgSeq": 640356133 - } -} -``` - -#### 群待办 -- 判断此类消息的逻辑:\$.Data.MsgType=10002 并且 解析\$.Data.Content.string中的xml sysmsg.type=roomtoolstips -```json - { - "TypeName": "AddMsg", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "MsgId": 1040356135, 消息ID - "FromUserName": - { - "string": "34757816141@chatroom" 所在群聊的ID - }, - "ToUserName": - { - "string": "wxid_0xsqb3o0tsvz22" - }, - "MsgType": 10002, - "Content": - { - "string": "34757816141@chatroom:\n\n\n 0\n\n \n \n \n \n \n <![CDATA[群公告]]>\n \n \n \n 0\n \n \n \n \n\n\n \n\n\n \n \n \n \n \n \n \n\n \n\n \n\n\n" - }, - "Status": 4, - "ImgStatus": 1, - "ImgBuf": - { - "iLen": 0 - }, - "CreateTime": 1705045591, 消息发送时间 - "MsgSource": "\n\t\n\t\t\n\t\n\n", - "NewMsgId": 1765700414095721113, 消息ID - "MsgSeq": 640356135 - } - } -``` - -#### 删除好友通知 -```json -{ - "TypeName": "DelContacts", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "UserName": - { - "string": "wxid_phyyedw9xap22" 删除的好友wxid - }, - "DeleteContactScen": 0 - } -} -``` - -#### 退出群聊 -```json -{ - "TypeName": "DelContacts", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22", 所属微信的wxid - "Data": - { - "UserName": - { - "string": "34559815390@chatroom" 退出的群聊ID - }, - "DeleteContactScen": 0 - } -} -``` - -#### 掉线通知 -```json -{ - "TypeName": "Offline", 消息类型 - "Appid": "wx_wR_U4zPj2M_OTS3BCyoE4", 设备ID - "Wxid": "wxid_phyyedw9xap22" 掉线号的wxid -} -``` diff --git a/gewechat/client.py b/gewechat/client.py deleted file mode 100644 index 1c25e7c..0000000 --- a/gewechat/client.py +++ /dev/null @@ -1,48 +0,0 @@ -import os -import toml -import time -import logging - -# 假设 gewechat_client 已经安装,并且 GewechatClient 可直接导入 -from gewechat_client import GewechatClient - -logger = logging.getLogger(__name__) - -class Client: - def __init__(self, config_path=None): - # 默认配置文件路径 - if config_path is None: - config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "config.toml") - self.config_path = config_path - config = toml.load(config_path) - gewechat_cfg = config.get("Gewechat", {}) - self.base_url = gewechat_cfg.get("base_url", "") - self.gewechat_token = gewechat_cfg.get("gewechat_token", "") - self.app_id = gewechat_cfg.get("app_id", "") - self.callback_url = gewechat_cfg.get("callback_url", "") - # 初始化 GewechatClient - self.client = GewechatClient( - base_url=self.base_url, - token=self.gewechat_token - ) - app_id, error_msg = self.client.login(app_id=self.app_id) - if error_msg: - logger.error("登录失败") - return - - # 如果启动时,配置文件中的app_id为空,那么将app_id写入配置文件 - if not self.app_id and app_id: - config["Gewechat"]["app_id"] = app_id - with open(self.config_path, "w", encoding="utf-8") as f: - toml.dump(config, f) - logger.info(f"已将新的APP_ID: {app_id} 写入配置文件") - self.app_id = app_id - - def client_set_callback(self): - """在server启动后调用此方法设置回调""" - resp = self.client.set_callback(self.app_id, self.callback_url) - print(f"set_callback 成功: {resp}") - - -# 项目全局唯一 client 实例 -gewe_client = Client() \ No newline at end of file diff --git a/gewechat/client/fetchContactsList.py b/gewechat/client/fetchContactsList.py deleted file mode 100644 index 5030c6c..0000000 --- a/gewechat/client/fetchContactsList.py +++ /dev/null @@ -1,20 +0,0 @@ -import requests -import json - -url = "/login/deviceList" - -base_url="http://192.168.2.240:2531/v2/api" -payload = json.dumps({ - -}) - -headers = { - 'X-GEWE-TOKEN': 'cb43f52db27e4a56bb6ec7da54373582', - 'Content-Type': 'application/json' -} - -response = requests.request("POST", base_url+url, headers=headers, data=payload) - -print(response.text) - - diff --git a/gewechat/client/get_chatroom_members.py b/gewechat/client/get_chatroom_members.py deleted file mode 100644 index 5f3b3c1..0000000 --- a/gewechat/client/get_chatroom_members.py +++ /dev/null @@ -1,120 +0,0 @@ -import requests -import json - -base_url = "http://192.168.2.240:2531/v2/api" - -headers = { - 'X-GEWE-TOKEN': 'cb43f52db27e4a56bb6ec7da54373582', - 'Content-Type': 'application/json' -} -app_id = "wx_3BC6eSHGE5xEm_hH3__7c" - - -def get_chatroom_members(): - url = "/group/getChatroomMemberList" - - payload = json.dumps({ - "appId": app_id, - "chatroomId": "52418238895@chatroom" - - }) - - response = requests.request("POST", base_url + url, headers=headers, data=payload) - - print(response.text) - - -def revoke_msg(): - url = "/message/revokeMsg" - - payload = json.dumps({ - "appId": app_id, - "toWxid": "34757816141@chatroom", - "msgId": "769533801", - "newMsgId": "5271007655758710001", - "createTime": "1704163145" - }) - - response = requests.request("POST", base_url + url, headers=headers, data=payload) - - print(response.text) - -def set_call_back(): - - url = "/tools/setCallback" - - payload = json.dumps({ - "token": "cb43f52db27e4a56bb6ec7da54373582", - "callbackUrl": "http://192.168.2.212:8999/gewechat/message/callback" - }) - headers = { - 'X-GEWE-TOKEN': 'cb43f52db27e4a56bb6ec7da54373582', - 'Content-Type': 'application/json' - } - - response = requests.request("POST",base_url+ url, headers=headers, data=payload) - - print(response.text) - -def send_file(): - - url = "/message/postFile" - - payload = json.dumps({ - "appId": app_id, - "toWxid": "52418238895@chatroom", - "fileName": "favicon.ico", - "fileUrl": "http://192.168.2.210:8888/static/favicon.ico" - }) - headers = { - 'X-GEWE-TOKEN': 'cb43f52db27e4a56bb6ec7da54373582', - 'Content-Type': 'application/json' - } - - response = requests.request("POST", base_url+url, headers=headers, data=payload) - - print(response.text) - - -def download_file(): - - url = "/message/downloadImage" - xml =""" - - - - - 0 - 0 - - - 0 - - - 0 - - - - - - - 0 - - - """ - payload = json.dumps({ - "appId": app_id, - "type": 2, - "xml": xml - }) - headers = { - 'X-GEWE-TOKEN': 'cb43f52db27e4a56bb6ec7da54373582', - 'Content-Type': 'application/json' - } - - response = requests.request("POST", base_url+url, headers=headers, data=payload) - - print(response.text) - -if __name__ == '__main__': - download_file() diff --git a/gewechat/client/get_token.py b/gewechat/client/get_token.py deleted file mode 100644 index 47f9482..0000000 --- a/gewechat/client/get_token.py +++ /dev/null @@ -1,30 +0,0 @@ -# import requests -# -# url = "/tools/getTokenId" -# -# payload={} -# headers = {} -# base_url="http://192.168.2.240:2531/v2/api" -# response = requests.request("POST", base_url+url, headers=headers, data=payload) -# -# print(response.text) -# -# - -import requests -import json - -# url = "/login/logout" -url ="/login/reconnection" -base_url="http://192.168.2.240:2531/v2/api" -payload = json.dumps({ - "appId": "wx_3BC6eSHGE5xEm_hH3__7c" -}) -headers = { - 'X-GEWE-TOKEN': 'cb43f52db27e4a56bb6ec7da54373582', - 'Content-Type': 'application/json' -} - -response = requests.request("POST", base_url+url, headers=headers, data=payload) - -print(response.text) \ No newline at end of file diff --git a/gewechat/client/login.py b/gewechat/client/login.py deleted file mode 100644 index 0f41096..0000000 --- a/gewechat/client/login.py +++ /dev/null @@ -1,12 +0,0 @@ - -import requests -def login(): - - url = "/tools/getTokenId" - - payload = {} - headers = {} - base_url = "http://192.168.2.240:2531/v2/api" - response = requests.request("POST", base_url + url, headers=headers, data=payload) - - print(response.text) \ No newline at end of file diff --git a/gewechat/client/set_call_back.py b/gewechat/client/set_call_back.py deleted file mode 100644 index 9573869..0000000 --- a/gewechat/client/set_call_back.py +++ /dev/null @@ -1,17 +0,0 @@ -import requests -import json - -url = "/tools/setCallback" - -payload = json.dumps({ - "token": "{{gewe-token}}", - "callbackUrl": "http://www.baidu.com" -}) -headers = { - 'X-GEWE-TOKEN': '{{gewe-token}}', - 'Content-Type': 'application/json' -} - -response = requests.request("POST", url, headers=headers, data=payload) - -print(response.text) \ No newline at end of file diff --git a/gewechat/config.toml b/gewechat/config.toml deleted file mode 100644 index e01583f..0000000 --- a/gewechat/config.toml +++ /dev/null @@ -1,5 +0,0 @@ -[Gewechat] -base_url= "http://192.168.2.240:2531/v2/api" -gewechat_token= "cb43f52db27e4a56bb6ec7da54373582" -app_id="wx_3BC6eSHGE5xEm_hH3__7c" -callback_url="http://192.168.2.212:8999/gewechat/message/callback" diff --git a/gewechat/response/__init__.py b/gewechat/response/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/gewechat/response/gewe_resp.py b/gewechat/response/gewe_resp.py deleted file mode 100644 index 6303d1b..0000000 --- a/gewechat/response/gewe_resp.py +++ /dev/null @@ -1,56 +0,0 @@ -import typing - - -class GeweResponse: - """ - 通用的 Gewechat 响应处理类 - """ - - def __init__(self, resp: dict): - """ - :param resp: gewechat接口返回的原始字典 - """ - self.raw = resp - self.ret = resp.get("ret") - self.msg = resp.get("msg") - self.data = resp.get("data") - - def is_success(self) -> bool: - """ - 判断请求是否成功 - :return: True/False - """ - return self.ret == 200 - - def get_msg(self) -> str: - """ - 获取返回消息 - :return: 消息字符串 - """ - return self.msg or "" - - def get_data(self) -> typing.Any: - """ - 获取返回的数据对象,类型可能为dict、list、str等 - :return: data字段内容 - """ - return self.data - - def get_data_as_list(self) -> list: - """ - 获取data字段为list类型(若不是则返回空列表) - """ - if isinstance(self.data, list): - return self.data - return [] - - def get_data_as_dict(self) -> dict: - """ - 获取data字段为dict类型(若不是则返回空字典) - """ - if isinstance(self.data, dict): - return self.data - return {} - - def __repr__(self): - return f"" diff --git a/gewechat/response/model/__init__.py b/gewechat/response/model/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/gewechat/response/model/contacts/__init__.py b/gewechat/response/model/contacts/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/gewechat/response/model/contacts/brief_info.py b/gewechat/response/model/contacts/brief_info.py deleted file mode 100644 index 9d0031c..0000000 --- a/gewechat/response/model/contacts/brief_info.py +++ /dev/null @@ -1,31 +0,0 @@ -from dataclasses import dataclass -from typing import Optional, List - -@dataclass -class Datum: - alias: Optional[str] = None - big_head_img_url: Optional[str] = None - card_img_url: Optional[str] = None - city: Optional[str] = None - country: Optional[str] = None - description: Optional[str] = None - label_list: Optional[str] = None - nick_name: Optional[str] = None - phone_num_list: Optional[List[str]] = None - province: Optional[str] = None - py_initial: Optional[str] = None - quan_pin: Optional[str] = None - remark: Optional[str] = None - remark_py_initial: Optional[str] = None - remark_quan_pin: Optional[str] = None - sex: Optional[int] = None - signature: Optional[str] = None - small_head_img_url: Optional[str] = None - sns_bg_img: Optional[str] = None - user_name: Optional[str] = None - -@dataclass -class BriefInfo: - data: List[Datum] - msg: str - ret: int diff --git a/gewechat/response/model/contacts/contacts_list.py b/gewechat/response/model/contacts/contacts_list.py deleted file mode 100644 index 87e2990..0000000 --- a/gewechat/response/model/contacts/contacts_list.py +++ /dev/null @@ -1,19 +0,0 @@ -from dataclasses import dataclass -from typing import List - - -@dataclass -class Data: - """保存到通讯录中群聊的ID""" - chatrooms: List[str] - """好友的wxid""" - friends: List[str] - """关注的公众号ID""" - ghs: List[str] - - -@dataclass -class ContactsList: - data: Data - msg: str - ret: int \ No newline at end of file diff --git a/gewechat/response/model/contacts/detail_info.py b/gewechat/response/model/contacts/detail_info.py deleted file mode 100644 index c2bfa24..0000000 --- a/gewechat/response/model/contacts/detail_info.py +++ /dev/null @@ -1,53 +0,0 @@ -from dataclasses import dataclass -from typing import Optional, List - - -@dataclass -class Datum: - """好友的微信号""" - alias: str - """大尺寸头像链接""" - big_head_img_url: str - """好友描述的图片链接""" - card_img_url: None - """城市""" - city: None - """国家""" - country: str - """好友的描述""" - description: None - """好友的标签ID""" - label_list: None - """好友的昵称""" - nick_name: str - """好友的手机号码""" - phone_num_list: None - """省份""" - province: None - """好友昵称的拼音首字母""" - py_initial: None - """好友昵称的全拼""" - quan_pin: str - """好友备注""" - remark: None - """好友备注的拼音首字母""" - remark_py_initial: None - """好友备注的全拼""" - remark_quan_pin: None - """好友的性别""" - sex: Optional[int] = None - """好友的签名""" - signature: Optional[str] = None - """小尺寸头像链接""" - small_head_img_url: Optional[str] = None - """朋友圈背景图链接""" - sns_bg_img: Optional[str] = None - """好友的wxid""" - user_name: Optional[str] = None - - -@dataclass -class ContactsDetailInfo: - data: List[Datum] - msg: str - ret: int \ No newline at end of file diff --git a/gewechat/response/model/group/__init__.py b/gewechat/response/model/group/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/gewechat/response/model/group/chatroom_info.py b/gewechat/response/model/group/chatroom_info.py deleted file mode 100644 index e49b4ab..0000000 --- a/gewechat/response/model/group/chatroom_info.py +++ /dev/null @@ -1,54 +0,0 @@ -from dataclasses import dataclass -from typing import Optional, List - - -@dataclass -class MemberList: - """大尺寸头像""" - big_head_img_url: None - """在本群内的昵称""" - display_name: None - """标识""" - member_flag: int - """群成员的昵称""" - nick_name: str - """小尺寸头像""" - small_head_img_url: None - """群成员的wxid""" - wxid: str - """邀请人的wxid""" - inviter_user_name: Optional[str] = None - - -@dataclass -class Data: - """群ID""" - chatroom_id: str - """群消息是否提醒""" - chat_room_notify: int - """群主的wxid""" - chat_room_owner: str - """群成员列表""" - member_list: List[MemberList] - """群名称""" - nick_name: str - """群名称的拼音首字母""" - py_initial: str - """群名称的全拼""" - quan_pin: str - """群备注,仅自己可见""" - remark: str - """群备注的拼音首字母""" - remark_py_initial: str - """群备注的全拼""" - remark_quan_pin: str - sex: int - """群头像链接""" - small_head_img_url: str - - -@dataclass -class ChatroomInfo: - data: Data - msg: str - ret: int \ No newline at end of file diff --git a/gewechat/response/model/group/chatroom_member_detail.py b/gewechat/response/model/group/chatroom_member_detail.py deleted file mode 100644 index a444dce..0000000 --- a/gewechat/response/model/group/chatroom_member_detail.py +++ /dev/null @@ -1,61 +0,0 @@ -from dataclasses import dataclass -from typing import List, Optional - - -@dataclass -class Datum: - """大尺寸头像""" - big_head_img_url: str - """描述的图片链接""" - card_img_url: None - """消息通知""" - chat_room_notify: int - """国家""" - country: str - """描述""" - description: None - """好友的wxid""" - friend_user_name: str - """群成员的昵称""" - nick_name: str - """手机号码""" - phone_num_list: List[str] - """群成员昵称的拼音首字母""" - py_initial: str - """群成员昵称的全拼""" - quan_pin: str - """性别""" - sex: int - """小尺寸头像""" - small_head_img_url: str - """朋友圈背景图链接""" - sns_bg_img: str - """群成员的wxid""" - user_name: str - """微信号""" - alias: Optional[str] = None - """城市""" - city: Optional[str] = None - """邀请人的wxid""" - inviter_user_name: Optional[str] = None - """标签列表,多个英文逗号分隔""" - label_list: Optional[str] = None - """标识""" - member_flag: Optional[int] = None - """省份""" - province: Optional[str] = None - """备注""" - remark: Optional[str] = None - """备注的拼音首字母""" - remark_py_initial: Optional[str] = None - """备注的全拼""" - remark_quan_pin: Optional[str] = None - """签名""" - signature: Optional[str] = None - - -@dataclass -class ChatroomMemberDetail: - data: List[Datum] - msg: str - ret: int diff --git a/gewechat/response/model/group/chatroom_member_list.py b/gewechat/response/model/group/chatroom_member_list.py deleted file mode 100644 index 0ab6229..0000000 --- a/gewechat/response/model/group/chatroom_member_list.py +++ /dev/null @@ -1,37 +0,0 @@ -from dataclasses import dataclass -from typing import Optional, List - - -@dataclass -class MemberList: - """大尺寸头像""" - big_head_img_url: str - """标识""" - member_flag: int - """群成员昵称""" - nick_name: str - """小尺寸头像""" - small_head_img_url: str - """群成员的wxid""" - wxid: str - """在本群内的昵称""" - display_name: Optional[str] = None - """邀请人的wxid""" - inviter_user_name: Optional[str] = None - - -@dataclass -class Data: - """管理的wxid""" - admin_wxid: None - """群主的wxid""" - chatroom_owner: None - """群成员列表""" - member_list: List[MemberList] - - -@dataclass -class ChatroomMemberList: - data: Data - msg: str - ret: int diff --git a/gewechat/response/model/personal/__init__.py b/gewechat/response/model/personal/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/gewechat/response/model/personal/profile.py b/gewechat/response/model/personal/profile.py deleted file mode 100644 index 0fdfae3..0000000 --- a/gewechat/response/model/personal/profile.py +++ /dev/null @@ -1,41 +0,0 @@ -from dataclasses import dataclass -from typing import Optional - - -@dataclass -class Data: - """微信号""" - alias: Optional[str] = None - """大尺寸头像""" - big_head_img_url: Optional[str] = None - """城市""" - city: Optional[str] = None - """国家""" - country: Optional[str] = None - """绑定的手机号""" - mobile: Optional[str] = None - """昵称""" - nick_name: Optional[str] = None - """省份""" - province: Optional[str] = None - """注册国家""" - reg_country: Optional[str] = None - """性别""" - sex: Optional[int] = None - """签名""" - signature: Optional[str] = None - """小尺寸头像""" - small_head_img_url: Optional[str] = None - """朋友圈背景图""" - sns_bg_img: Optional[str] = None - """uin""" - uin: Optional[int] = None - """微信ID""" - wxid: Optional[str] = None - - -@dataclass -class Profile: - data: Optional[Data] = None - msg: Optional[str] = None - ret: Optional[int] = None \ No newline at end of file diff --git a/main.py b/main.py index 26262d2..b906285 100644 --- a/main.py +++ b/main.py @@ -1,58 +1,46 @@ #! /usr/bin/env python3 # -*- coding: utf-8 -*- -import logging import threading from argparse import ArgumentParser from configuration import Config from constants import ChatType -from gewechat.api.start_server import start_fastapi_server -from gewechat.client import gewe_client from robot import Robot -# 配置日志 -logger = logging.getLogger(__name__) +from loguru import logger + +# INFO 日志(包含 INFO、DEBUG,但不包含 WARNING、ERROR) +logger.add( + f"wx_info.log", + level="INFO", + filter=lambda record: record["level"].name in ["INFO", "DEBUG"], + rotation="10 MB", + retention="7 days", + encoding="utf-8" +) + +# ERROR 日志(仅 ERROR 及以上) +logger.add( + f"wx_error.log", + level="ERROR", + rotation="10 MB", + retention="7 days", + encoding="utf-8" +) def main(chat_type: int): config = Config() - send_msg_wxid = "filehelper" # 要发送消息的好友昵称 - - start_fastapi_server(host="0.0.0.0", port=8999) # 创建机器人实例 robot = Robot(config) - robot.LOG.info(f"WeChatRobot gewechat 成功启动···") + robot.LOG.info(f"WeChatRobot 正在启动...") - # # 注册Robot实例到callback模块 - from gewechat.api.callback import register_robot - register_robot(gewe_client.app_id, robot) - - # 机器人启动发送测试消息 - gewe_client.client.post_text(gewe_client.app_id, send_msg_wxid, "client 启动成功!") - # - # # 每天 8:30 发送新闻 - # robot.onEveryTime("08:30", robot.news_baidu_report_auto) - # - # # epic - # robot.onEveryTime("10:30", robot.send_epic_free_games) - # - # # message report 1:数据自动从redis 转到sqllite - # robot.onEveryTime("02:30", robot.message_count_to_db) - # # 从db中提取并发送给相关群 - # robot.onEveryTime("09:30", robot.generate_and_send_ranking) - # - # # sehuatang - # robot.onEveryTime("15:30", robot.generate_sehuatang_pdf) - # - # # 秀人网每天自动下载帖子 - # robot.onEveryTime("01:30", robot.xiu_ren_download_task) - # - # # 秀人网每天自动发pdf - # robot.onEveryTime("17:30", robot.xiu_ren_pdf_send) - # time.sleep(5) - # # 启动之后,填入callback - # gewe_client.client_set_callback() - # # 返回启动的端口,以便调用者知道实际使用的端口 + # 初始化并启动wechat_ipad客户端 + if robot.init_wechat_ipad(): + robot.LOG.info("wechat_ipad客户端启动成功") + else: + robot.LOG.error("wechat_ipad客户端启动失败") + # 启动Dashboard服务器 dashboard_server = None try: @@ -74,5 +62,5 @@ def main(chat_type: int): if __name__ == "__main__": parser = ArgumentParser() parser.add_argument('-c', type=int, default=0, help=f'选择模型参数序号: {ChatType.help_hint()}') - args = parser.parse_args().c - main(args) + args = parser.parse_args() + main(args.c) diff --git a/message_util.py b/message_util.py index 06f65a3..caf35d9 100644 --- a/message_util.py +++ b/message_util.py @@ -1,12 +1,12 @@ # -*- coding: utf-8 -*- -import logging +from loguru import logger import os.path import random import time +from typing import Any, Tuple, Coroutine - -from gewechat.client import gewe_client from utils.wechat.contact_manager import ContactManager +from wechat_ipad import WechatAPIClient class MessageUtil: @@ -15,11 +15,10 @@ class MessageUtil: """ # 修改 MessageUtil 类的初始化方法,接受联系人管理器而不是联系人字典 - def __init__(self): - self.app_id = gewe_client.app_id - self.client = gewe_client.client + def __init__(self, client: WechatAPIClient = None): + self.client = client self.contact_manager = ContactManager.get_instance() - self.LOG = logging.getLogger("MessageUtil") + self.LOG = logger def send_text(self, msg: str, receiver: str, at_list: str = "") -> None: """ @@ -39,15 +38,15 @@ class MessageUtil: else: wxids = at_list.split(",") if len(wxids) > 0: - ats += self.get_user_chatroom_nickname(receiver, wxids) + ats += self.client.get_nickname(receiver) # {msg}{ats} 表示要发送的消息内容后面紧跟@,例如 北京天气情况为:xxx @张三 if ats == "": self.LOG.info(f"To {receiver}: {msg}") - self.client.post_text(self.app_id, receiver, "{msg}", "") + self.client.send_text_message(receiver, "{msg}", "") else: self.LOG.info(f"To {receiver}: {ats}\r{msg}") - self.client.post_text(self.app_id, receiver, f"{ats}\n{msg}", at_list) + self.client.send_text_message(receiver, f"{ats}\n{msg}", at_list) def send_file(self, file_path: str, receiver: str) -> str: """ @@ -64,7 +63,7 @@ class MessageUtil: self.LOG.info(f"Sending file to {path}: {filename}") return self.client.post_file(self.app_id, receiver, file_path, filename) - def send_image(self, image_path: str, receiver: str) -> str: + def send_image(self, image_path: str, receiver: str) -> Coroutine[Any, Any, tuple[int, int, int]]: """ 发送文件消息 @@ -75,7 +74,7 @@ class MessageUtil: time.sleep(random.uniform(0.5, 1.5)) self.LOG.info(f"Sending file to {receiver}: {image_path}") - return self.client.post_image(self.app_id, receiver, image_path) + return self.client.send_image_message(receiver, image_path) def send_rich_text(self, name: str, account: str, title: str, digest: str, url: str, thumburl: str, receiver: str) -> int: @@ -105,18 +104,12 @@ class MessageUtil: time.sleep(random.uniform(0.5, 1.5)) self.LOG.info(f"Sending rich text to {receiver}: {title}") - return self.client.post_link(self.app_id, receiver, title, digest, url, thumburl) - - def get_user_chatroom_nickname(self, chatroom_id: str, member_wxids: list[str]) -> str: - data = self.client.get_chatroom_member_detail(self.app_id, chatroom_id, member_wxids) - nicknames_with_at = [" @" + member["nickName"] for member in data["data"] if member.get("nickName")] - return " ".join(nicknames_with_at) + return self.client.send_link_message(self.app_id, receiver, title, digest, url, thumburl) def invite_member(self, group_id, sender): - return self.client.invite_member(self.app_id, sender, group_id, "自动加群邀请") + return self.client.invite_chatroom_member( sender, group_id) def get_chatroom_members(self, group_id) -> dict: data = self.client.get_chatroom_member_list(self.app_id, group_id) members = {member["wxid"]: member["nickName"] for member in data["data"]["memberList"]} return members - diff --git a/plugin_common/message_plugin_interface.py b/plugin_common/message_plugin_interface.py index 1a5e2a5..ded63c5 100644 --- a/plugin_common/message_plugin_interface.py +++ b/plugin_common/message_plugin_interface.py @@ -1,19 +1,20 @@ from typing import Dict, Any, Tuple, Optional, List from plugin_common.plugin_interface import PluginInterface + class MessagePluginInterface(PluginInterface): """消息处理插件接口""" - + @property def command_prefix(self) -> Optional[str]: """命令前缀,如 '/'""" return None - + @property def commands(self) -> List[str]: """支持的命令列表""" return [] - + def can_process(self, message: Dict[str, Any]) -> bool: """ 检查插件是否可以处理该消息 @@ -31,7 +32,7 @@ class MessagePluginInterface(PluginInterface): command = content[len(self.command_prefix):].split()[0] return command in self.commands return False - + def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """ 处理消息 @@ -44,4 +45,4 @@ class MessagePluginInterface(PluginInterface): Returns: (是否已处理, 处理结果) """ - raise NotImplementedError("子类必须实现此方法") \ No newline at end of file + raise NotImplementedError("子类必须实现此方法") diff --git a/plugin_common/plugin_interface.py b/plugin_common/plugin_interface.py index 06e781a..9d3da5f 100644 --- a/plugin_common/plugin_interface.py +++ b/plugin_common/plugin_interface.py @@ -1,7 +1,7 @@ import os import toml from abc import ABC, abstractmethod -import logging +from loguru import logger from enum import Enum from typing import Dict, Any, List, Optional, Tuple @@ -63,7 +63,7 @@ class PluginInterface(ABC): self._config = {} self._plugin_path = "" # 初始化日志记录器 - self.LOG = logging.getLogger(f"Plugin.{self.name}") + self.LOG = logger def load_config(self) -> bool: """ @@ -187,7 +187,7 @@ class PluginInterface(ABC): """ return False - def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """ 处理消息 diff --git a/plugin_common/plugin_manager.py b/plugin_common/plugin_manager.py index e04caaa..4260c10 100644 --- a/plugin_common/plugin_manager.py +++ b/plugin_common/plugin_manager.py @@ -1,10 +1,11 @@ import importlib import inspect -import logging import os import sys from typing import Dict, List, Any, Optional, Type, Tuple +from loguru import logger + from plugin_common.plugin_interface import PluginInterface, PluginStatus from plugin_common.message_plugin_interface import MessagePluginInterface from plugin_common.scheduled_plugin_interface import ScheduledPluginInterface @@ -53,7 +54,7 @@ class PluginManager: self.module_to_display = {} # 模块名到显示名的映射 self.system_context = {} # 系统上下文 - self.LOG = logging.getLogger(__name__) + self.LOG = logger # 确保插件目录存在 if not os.path.exists(self.plugin_dir): os.makedirs(self.plugin_dir) diff --git a/plugins/beautyleg/main.py b/plugins/beautyleg/main.py index 40ab45c..1f20fad 100644 --- a/plugins/beautyleg/main.py +++ b/plugins/beautyleg/main.py @@ -1,9 +1,7 @@ -import logging import os import random from typing import Dict, Any, List, Optional, Tuple - from message_util import MessageUtil from plugin_common.message_plugin_interface import MessagePluginInterface from plugin_common.plugin_interface import PluginStatus @@ -47,7 +45,6 @@ class BeautyLegPlugin(MessagePluginInterface): def initialize(self, context: Dict[str, Any]) -> bool: """初始化插件""" - self.LOG = logging.getLogger(f"Plugin.{self.name}") self.LOG.info(f"正在初始化 {self.name} 插件...") # 保存上下文对象 diff --git a/plugins/dify/main.py b/plugins/dify/main.py index 52beb36..5a9447f 100644 --- a/plugins/dify/main.py +++ b/plugins/dify/main.py @@ -6,6 +6,7 @@ import time import re # 添加re模块导入 from typing import Dict, Any, List, Optional, Tuple +from loguru import logger from message_util import MessageUtil from plugin_common.message_plugin_interface import MessagePluginInterface @@ -15,6 +16,7 @@ from utils.robot_cmd.robot_command import Feature, PermissionStatus, GroupBotMan from utils.decorator.points_decorator import plugin_points_cost from utils.media_downloader import MediaDownloader from utils.string_utils import remove_trailing_content +from wechat_ipad import WechatAPIClient class DifyPlugin(MessagePluginInterface): @@ -58,7 +60,6 @@ class DifyPlugin(MessagePluginInterface): def initialize(self, context: Dict[str, Any]) -> bool: """初始化插件""" - self.LOG = logging.getLogger(f"Plugin.{self.name}") self.LOG.info(f"正在初始化 {self.name} 插件...") # 保存上下文对象 @@ -114,7 +115,7 @@ class DifyPlugin(MessagePluginInterface): @plugin_stats_decorator(plugin_name="Dify聊天") @plugin_points_cost(2, "AI聊天消耗积分", Feature.AI_CAPABILITY) - def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """处理消息""" content = str(message.get("content", "")).strip() self.LOG.info(f"插件执行: {self.name}:{content}") @@ -122,6 +123,7 @@ class DifyPlugin(MessagePluginInterface): roomid = message.get("roomid", "") gbm: GroupBotManager = message.get("gbm") + bot: WechatAPIClient = message.get("bot") # 处理被@的消息 if message.get("is_at", False) and roomid: # 检查权限 @@ -132,14 +134,14 @@ class DifyPlugin(MessagePluginInterface): query = re.sub(r"@.*?[\u2005|\s]", "", content).strip() if not query: - self.message_util.send_text("请在@我的同时提供问题内容", roomid, sender) + await bot.send_text_message(roomid, "请在@我的同时提供问题内容", sender) return False, "没有提供问题内容" # self.message_util.send_text_msg("⏳AI 正在加油,请稍候… 😊", roomid, sender) try: # 调用Dify API获取回复 - response = self._chat_with_dify(roomid, sender, query) + response = self._chat_with_dify((roomid if roomid else sender), sender, query) # 去除广告内容 response = remove_trailing_content(response) @@ -151,15 +153,15 @@ class DifyPlugin(MessagePluginInterface): self.message_util.send_file(response, roomid) else: # 如果是普通文本,使用发送文本方法 - self.message_util.send_text(response, roomid, sender) + await bot.send_text_message((roomid if roomid else sender), response, sender) return True, "发送成功" else: - self.message_util.send_text("❌未能获取到回复,请稍后再试", roomid, sender) + await bot.send_text_message((roomid if roomid else sender), "❌未能获取到回复,请稍后再试", sender) return False, "未获取到回复" except Exception as e: self.LOG.error(f"处理Dify聊天请求出错: {e}") - self.message_util.send_text(f"❌请求出错:{str(e)}", roomid, sender) + await bot.send_text_message((roomid if roomid else sender), "❌未能获取到回复,请稍后再试", sender) return False, f"处理出错: {e}" # 原有的命令处理逻辑 @@ -168,8 +170,7 @@ class DifyPlugin(MessagePluginInterface): # 检查命令格式 if len(parts) < 2 or not parts[1].strip(): - self.message_util.send_text(f"{self.command_format}", - (roomid if roomid else sender), sender) + await bot.send_text_message((roomid if roomid else sender), f"{self.command_format}", sender) return False, "命令格式错误" # 检查权限 @@ -199,16 +200,17 @@ class DifyPlugin(MessagePluginInterface): self.message_util.send_file(response, (roomid if roomid else sender)) else: # 如果是普通文本,使用发送文本方法 - self.message_util.send_text(response, (roomid if roomid else sender), sender if roomid else "") + await bot.send_text_message((roomid if roomid else sender), response, + sender if roomid else "") return True, "发送成功" else: - self.message_util.send_text("❌未能获取到回复,请稍后再试", (roomid if roomid else sender), + await bot.send_text_message((roomid if roomid else sender), "❌未能获取到回复,请稍后再试", sender if roomid else "") return False, "未获取到回复" except Exception as e: self.LOG.error(f"处理Dify聊天请求出错: {e}") - self.message_util.send_text(f"❌请求出错:{str(e)}", (roomid if roomid else sender), + await bot.send_text_message((roomid if roomid else sender), f"❌请求出错:{str(e)}", sender if roomid else "") return False, f"处理出错: {e}" diff --git a/plugins/douyin_parser/main.py b/plugins/douyin_parser/main.py index c3790ef..8ba55bc 100644 --- a/plugins/douyin_parser/main.py +++ b/plugins/douyin_parser/main.py @@ -1,4 +1,3 @@ -import logging import os import re import time @@ -6,6 +5,8 @@ import traceback import requests from typing import Dict, Any, List, Optional, Tuple +from loguru import logger + from message_util import MessageUtil from plugin_common.message_plugin_interface import MessagePluginInterface from plugin_common.plugin_interface import PluginStatus @@ -47,6 +48,7 @@ class DouyinParserPlugin(MessagePluginInterface): def __init__(self): super().__init__() + self.LOG = logger self.url_pattern = re.compile(r'https?://v\.douyin\.com/\w+/?') # 修改为使用插件目录下的down_load_dir文件夹 self.download_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "down_load_dir") @@ -56,7 +58,6 @@ class DouyinParserPlugin(MessagePluginInterface): def initialize(self, context: Dict[str, Any]) -> bool: """初始化插件""" - self.LOG = logging.getLogger(f"Plugin.{self.name}") self.LOG.info(f"正在初始化 {self.name} 插件...") # 保存上下文对象 diff --git a/plugins/game_task/main.py b/plugins/game_task/main.py index 1836b3f..a829cc2 100644 --- a/plugins/game_task/main.py +++ b/plugins/game_task/main.py @@ -1,8 +1,9 @@ import random -import logging from datetime import datetime from typing import Dict, Any, List, Optional, Tuple +from loguru import logger + from message_util import MessageUtil from plugin_common.message_plugin_interface import MessagePluginInterface from plugin_common.plugin_interface import PluginStatus @@ -12,6 +13,7 @@ from utils.decorator.points_decorator import points_reward_decorator from utils.ai.game_chatgpt_qa import game_question_json, game_answer_json from db.connection import DBConnectionManager from db.encyclopedia import EncyclopediaDB +from wechat_ipad import WechatAPIClient class GameTaskPlugin(MessagePluginInterface): @@ -43,10 +45,11 @@ class GameTaskPlugin(MessagePluginInterface): def __init__(self): super().__init__() + self.LOG = logger + self.bot: WechatAPIClient = None def initialize(self, context: Dict[str, Any]) -> bool: """初始化插件""" - self.LOG = logging.getLogger(f"Plugin.{self.name}") self.LOG.info(f"正在初始化 {self.name} 插件...") # 保存上下文对象 @@ -70,7 +73,6 @@ class GameTaskPlugin(MessagePluginInterface): # 初始化数据库连接 self.db_manager = DBConnectionManager.get_instance() self.encyclopedia_db = EncyclopediaDB(self.db_manager) - self.LOG.info(f"[{self.name}] 插件初始化完成,指令:{self._commands}") return True @@ -106,7 +108,7 @@ class GameTaskPlugin(MessagePluginInterface): return 0 @plugin_stats_decorator(plugin_name="百科问答") - def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """处理消息""" content = str(message.get("content", "")).strip() command = content.split(" ")[0].lower() @@ -115,6 +117,7 @@ class GameTaskPlugin(MessagePluginInterface): gbm: GroupBotManager = message.get("gbm") all_contacts = message.get("all_contacts", {}) + self.bot = message.get("bot") self.LOG.info(f"插件执行: {self.name}:{content}") # 检查权限 @@ -126,22 +129,22 @@ class GameTaskPlugin(MessagePluginInterface): wx_nick_name = all_contacts.get(sender, sender) if command == "/s": - self._handle_join_game(sender, roomid, wx_nick_name) + await self._handle_join_game(sender, roomid, wx_nick_name) return True, "加入游戏成功" elif command == "/t": - self._handle_get_task(sender, roomid) + await self._handle_get_task(sender, roomid) return True, "获取任务成功" elif command == "/a": # 这里传递整个消息对象给处理方法 - return self._handle_submit_answer(message) + return await self._handle_submit_answer(message) elif command == "/r": - self._handle_show_rank(sender, roomid) + await self._handle_show_rank(sender, roomid) return True, "显示排行榜成功" elif command == "/l": - self._handle_show_active_tasks(sender, roomid) + await self._handle_show_active_tasks(sender, roomid) return True, "显示活跃任务成功" elif command == "/h": - self._handle_list_uncompleted_tasks(sender, roomid) + await self._handle_list_uncompleted_tasks(sender, roomid) return True, "列举未完成任务成功" else: self.message_util.send_text(f"❌未知命令!\n{self.command_format}", @@ -152,15 +155,15 @@ class GameTaskPlugin(MessagePluginInterface): self.LOG.error(f"处理消息出错: {e}") return False, f"处理出错: {e}" - def _handle_join_game(self, sender: str, roomid: str, wx_nick_name: str) -> None: + async def _handle_join_game(self, sender: str, roomid: str, wx_nick_name: str) -> None: """处理加入游戏请求""" try: # 检查并添加群聊 if not self.encyclopedia_db.check_group_exists(roomid): self.encyclopedia_db.add_group(roomid) - self.message_util.send_text( - f"🎉 群 {roomid} 已就位,准备开燥!", + await self.bot.send_text_message( (roomid if roomid else sender), + f"🎉 群 {roomid} 已就位,准备开燥!", sender ) @@ -168,22 +171,22 @@ class GameTaskPlugin(MessagePluginInterface): player = self.encyclopedia_db.get_player(sender, roomid) if not player: self.encyclopedia_db.add_player(sender, roomid, wx_nick_name) - self.message_util.send_text( + await self.bot.send_text_message( + (roomid if roomid else sender), f"🎉 哇塞,{wx_nick_name} 你来啦!\n" f"🌟 群 {roomid} 瞬间燃爆!\n" f"🎈 快来接任务,秀翻全场!指令: /t", - (roomid if roomid else sender), sender ) except Exception as e: self.LOG.error(f"加入游戏出错: {e}") - self.message_util.send_text( - f"😔 加入游戏出错,请稍后再试!", + await self.bot.send_text_message( (roomid if roomid else sender), + f"😔 加入游戏出错,请稍后再试!", sender ) - def _handle_get_task(self, sender: str, roomid: str) -> None: + async def _handle_get_task(self, sender: str, roomid: str) -> None: """处理获取任务请求""" try: # 获取群内所有玩家 @@ -194,35 +197,35 @@ class GameTaskPlugin(MessagePluginInterface): # 检查并添加群聊 if not self.encyclopedia_db.check_group_exists(roomid): self.encyclopedia_db.add_group(roomid) - self.message_util.send_text( - f"🎉 群 {roomid} 已就位,准备开燥!", + await self.bot.send_text_message( (roomid if roomid else sender), + f"🎉 群 {roomid} 已就位,准备开燥!", sender ) - + # 获取用户昵称 (从all_contacts中获取可能不可行,因为这里没有all_contacts参数) # 使用sender作为临时昵称 wx_nick_name = sender - + # 添加当前用户为玩家 self.encyclopedia_db.add_player(sender, roomid, wx_nick_name) - self.message_util.send_text( + await self.bot.send_text_message( + (roomid if roomid else sender), f"🎉 哇塞,{wx_nick_name} 你是第一个玩家!\n" f"🌟 已自动为你加入游戏!\n" f"🎈 现在就为你准备题目...", - (roomid if roomid else sender), sender ) - + # 更新玩家列表 players = self.encyclopedia_db.get_all_players_in_group(roomid) - + player_dict = {p['player_id']: p['player_name'] for p in players} if sender not in player_dict: - self.message_util.send_text( + await self.bot.send_text_message( + (roomid if roomid else sender), f"😅 嘿,你谁啊?\n" f"🌟 先用 /s 报名,不然没法玩哦!", - (roomid if roomid else sender), sender ) return @@ -241,32 +244,32 @@ class GameTaskPlugin(MessagePluginInterface): ) if not active_task_id: - self.message_util.send_text( - f"😔 任务创建失败,请稍后再试!", + await self.bot.send_text_message( (roomid if roomid else sender), + f"😔 任务创建失败,请稍后再试!", sender ) return - self.message_util.send_text( + await self.bot.send_text_message( + (roomid if roomid else sender), f"🎁 {player_dict[sender]},你的专属任务闪亮登场!\n" f"🎀 任务ID: {active_task_id}\n" f"🎈 问题:[{category}]{question}\n" f"🌼 积分:{score}\n" f"🌈 快上答案:/a {active_task_id} 答案", - (roomid if roomid else sender), sender ) except Exception as e: self.LOG.error(f"获取任务出错: {e}") - self.message_util.send_text( - f"😔 获取任务出错,请稍后再试!", + await self.bot.send_text_message( (roomid if roomid else sender), + f"😔 获取任务出错,请稍后再试!", sender ) @points_reward_decorator(calculate_game_points, "game", "百科答题奖励", Feature.TASK_GAME) - def _handle_submit_answer(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + async def _handle_submit_answer(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """处理提交答案请求""" try: content = str(message.get("content", "")).strip() @@ -274,11 +277,11 @@ class GameTaskPlugin(MessagePluginInterface): roomid = message.get("roomid", "") parts = content.split(" ", 2) if len(parts) < 3: - self.message_util.send_text( + await self.bot.send_text_message( + (roomid if roomid else sender), f"😅 喂,格式不对啊!\n" f"🌟 正确姿势:/a [任务ID] [答案]\n" f"🎈 比如:/a 1 钒", - (roomid if roomid else sender), sender ) return False, "0" @@ -289,10 +292,10 @@ class GameTaskPlugin(MessagePluginInterface): # 获取玩家信息 player = self.encyclopedia_db.get_player(sender, roomid) if not player: - self.message_util.send_text( + await self.bot.send_text_message( + (roomid if roomid else sender), f"😅 嘿,你是路人甲吗?\n" f"🌟 用 /s 先加入群 {roomid} 吧!", - (roomid if roomid else sender), sender ) return False, "0" @@ -300,11 +303,11 @@ class GameTaskPlugin(MessagePluginInterface): player_name = player['player_name'] if not task_id.isdigit(): - self.message_util.send_text( + await self.bot.send_text_message( + (roomid if roomid else sender), f"😅 喂,任务ID得是数字好吗?\n" f"🌟 比如:1\n" f"🎈 别瞎搞,重新来!", - (roomid if roomid else sender), sender ) return False, "0" @@ -315,20 +318,20 @@ class GameTaskPlugin(MessagePluginInterface): task_data = self.encyclopedia_db.get_task_by_id(roomid, active_task_id) if not task_data: - self.message_util.send_text( + await self.bot.send_text_message( + (roomid if roomid else sender), f"😔 哎哟,任务 task_{active_task_id} 不翼而飞啦!\n" f"🌼 可能被别人抢先一步咯!", - (roomid if roomid else sender), sender ) return False, "0" if task_data['status'] == 'completed': - self.message_util.send_text( + await self.bot.send_text_message( + (roomid if roomid else sender), f"😄 哈哈,你慢了一步!\n" f"🌟 任务 task_{active_task_id} 已经完结\n" f"🎈 快去抢新任务吧!", - (roomid if roomid else sender), sender ) return False, "0" @@ -358,30 +361,31 @@ class GameTaskPlugin(MessagePluginInterface): self.encyclopedia_db.complete_task(active_task_id) if sender == holder_id: - self.message_util.send_text( + await self.bot.send_text_message( + (roomid if roomid else sender), f"🎉 {player_name} 你是天才吗?\n" f"🌟 任务:{question}\n" f"🎈 答对啦,简直无敌!\n" f"🌈 奖励:{points} 分\n" f"🎀 彩蛋:{description}", - (roomid if roomid else sender), sender ) else: - self.message_util.send_text( + await self.bot.send_text_message( + (roomid if roomid else sender), f"🎉 {player_name} 抢答王上线!\n" f"🌟 任务:{question}\n" f"🎈 原主:{holder_name} 被你截胡啦!\n" f"🌈 狂揽 {points} 分,太骚了!\n" f"🎀 彩蛋:{description}", - (roomid if roomid else sender), sender ) else: # 扣除积分 self.encyclopedia_db.update_player_points(sender, roomid, -1) points = -1 - self.message_util.send_text( + await self.bot.send_text_message( + (roomid if roomid else sender), f"😅 {player_name} 你这是要笑死我吗?\n" f"🌼 任务:{question}\n" f"🎈 你答:{answer}\n" @@ -389,7 +393,6 @@ class GameTaskPlugin(MessagePluginInterface): f"🌈 扣 1 分,别哭哦!\n" f"🎀 提示:{description}\n" f"🌟 任务ID: {active_task_id} 还能抢救一下!", - (roomid if roomid else sender), sender ) @@ -398,17 +401,17 @@ class GameTaskPlugin(MessagePluginInterface): self.LOG.error(f"提交答案出错: {e}") return False, "0" - def _handle_show_rank(self, sender: str, roomid: str) -> None: + async def _handle_show_rank(self, sender: str, roomid: str) -> None: """处理显示排行榜请求""" try: # 获取排行榜 ranks = self.encyclopedia_db.get_player_ranking(roomid, 10) if not ranks: - self.message_util.send_text( + await self.bot.send_text_message( + (roomid if roomid else sender), f"😔 群 {roomid} 冷冷清清\n" f"🌟 快来一起燥起来吧!", - (roomid if roomid else sender), sender ) return @@ -424,23 +427,23 @@ class GameTaskPlugin(MessagePluginInterface): ) except Exception as e: self.LOG.error(f"显示排行榜出错: {e}") - self.message_util.send_text( - f"😔 获取排行榜出错,请稍后再试!", + await self.bot.send_text_message( (roomid if roomid else sender), + f"😔 获取排行榜出错,请稍后再试!", sender ) - def _handle_show_active_tasks(self, sender: str, roomid: str) -> None: + async def _handle_show_active_tasks(self, sender: str, roomid: str) -> None: """处理显示活跃任务请求""" try: # 获取活跃任务 tasks = self.encyclopedia_db.get_active_tasks_in_group(roomid) if not tasks: - self.message_util.send_text( + await self.bot.send_text_message( + (roomid if roomid else sender), f"😄 群 {roomid} 现在一片祥和\n" f"🌟 没任务?快用 /t 搞一个!", - (roomid if roomid else sender), sender ) return @@ -453,30 +456,30 @@ class GameTaskPlugin(MessagePluginInterface): f"🌼 大佬:{task['player_name']}\n" ) - self.message_util.send_text( - task_text, + await self.bot.send_text_message( (roomid if roomid else sender), + task_text, sender ) except Exception as e: self.LOG.error(f"显示活跃任务出错: {e}") - self.message_util.send_text( - f"😔 获取活跃任务出错,请稍后再试!", + await self.bot.send_text_message( (roomid if roomid else sender), + f"😔 获取活跃任务出错,请稍后再试!", sender ) - def _handle_list_uncompleted_tasks(self, sender: str, roomid: str) -> None: + async def _handle_list_uncompleted_tasks(self, sender: str, roomid: str) -> None: """处理列举未完成任务请求""" try: # 获取未完成任务 tasks = self.encyclopedia_db.get_active_tasks_in_group(roomid) if not tasks: - self.message_util.send_text( + await self.bot.send_text_message( + (roomid if roomid else sender), f"😄 群 {roomid} 全员开挂?\n" f"🌟 没未完成任务,快用 /t 再战!", - (roomid if roomid else sender), sender ) return @@ -489,20 +492,20 @@ class GameTaskPlugin(MessagePluginInterface): f"🌼 主人:{task['player_name']}\n" ) - self.message_util.send_text( - task_text, + await self.bot.send_text_message( (roomid if roomid else sender), + task_text, sender ) except Exception as e: self.LOG.error(f"列举未完成任务出错: {e}") - self.message_util.send_text( - f"😔 获取未完成任务出错,请稍后再试!", + await self.bot.send_text_message( (roomid if roomid else sender), + f"😔 获取未完成任务出错,请稍后再试!", sender ) - def run_random_task_assignment(self) -> None: + async def run_random_task_assignment(self) -> None: """定时任务:整点触发,排除23:00-08:00""" current_hour = datetime.now().hour if current_hour >= 23 or current_hour < 9: @@ -538,14 +541,14 @@ class GameTaskPlugin(MessagePluginInterface): ) if active_task_id: - self.message_util.send_text( + await self.bot.send_text_message( + group_id, f"🎁 新任务来袭,够不够刺激?\n" f"🎀 任务ID: {active_task_id}\n" f"🌟 幸运鹅:{holder_name}\n" f"🎈 问题:[{category}]{question}\n" f"🌼 积分:{score}\n" - f"🌈 抢答格式:/a {active_task_id} 答案", - group_id + f"🌈 抢答格式:/a {active_task_id} 答案" ) except Exception as e: self.LOG.error(f"定时任务出错: {e}") diff --git a/plugins/global_news/main.py b/plugins/global_news/main.py index ec45a59..9312c43 100644 --- a/plugins/global_news/main.py +++ b/plugins/global_news/main.py @@ -1,4 +1,3 @@ -import logging import asyncio import threading import time # 添加这一行 @@ -12,6 +11,7 @@ from utils.robot_cmd.robot_command import Feature, PermissionStatus, GroupBotMan from utils.decorator.points_decorator import plugin_points_cost from utils.ai.dify_news_analyze import dify_news_title_analyze from utils.markdown_to_image import convert_md_str_to_image +from wechat_ipad import WechatAPIClient # 导入新闻抓取函数 from .news_crawler import nbc, cnn, abc, fox, bbc @@ -46,11 +46,12 @@ class GlobalNewsPlugin(MessagePluginInterface): def __init__(self): super().__init__() + + self.bot: WechatAPIClient = None self._news_tasks = {} # 存储正在进行的新闻抓取任务 def initialize(self, context: Dict[str, Any]) -> bool: """初始化插件""" - self.LOG = logging.getLogger(f"Plugin.{self.name}") self.LOG.info(f"正在初始化 {self.name} 插件...") # 保存上下文对象 @@ -90,13 +91,14 @@ class GlobalNewsPlugin(MessagePluginInterface): @plugin_stats_decorator(plugin_name="全球政治经济新闻") @plugin_points_cost(5, "全球新闻消耗积分", Feature.NEWS) - def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """处理消息""" content = str(message.get("content", "")).strip() self.LOG.info(f"插件执行: {self.name}:{content}") sender = message.get("sender") roomid = message.get("roomid", "") gbm: GroupBotManager = message.get("gbm") + self.bot: WechatAPIClient = message.get("bot") # 检查权限 if roomid and gbm.get_group_permission(roomid, Feature.NEWS) == PermissionStatus.DISABLED: @@ -106,8 +108,8 @@ class GlobalNewsPlugin(MessagePluginInterface): task_id = f"{sender}_{roomid}_{int(time.time())}" # 发送等待消息 - self.message_util.send_text("🌍正在获取全球新闻,请稍候...", - (roomid if roomid else sender), sender) + await self.bot.send_text_message( + (roomid if roomid else sender), "🌍正在获取全球新闻,请稍候...", sender) # 启动异步任务 self._start_news_task(task_id, sender, roomid) @@ -125,7 +127,7 @@ class GlobalNewsPlugin(MessagePluginInterface): self._news_tasks[task_id] = thread self.LOG.info(f"启动新闻获取任务: {task_id}") - def _fetch_news_thread(self, task_id: str, sender: str, roomid: str): + async def _fetch_news_thread(self, task_id: str, sender: str, roomid: str): """在单独的线程中运行异步新闻获取任务""" try: loop = asyncio.new_event_loop() @@ -137,15 +139,15 @@ class GlobalNewsPlugin(MessagePluginInterface): if news_result: # 发送新闻图片 receiver = roomid if roomid else sender - self.message_util.send_image(news_result, receiver) - self.message_util.send_text("🌍全球新闻获取完成!", receiver, sender) + await self.bot.send_image_message(receiver, news_result) + await self.bot.send_text_message("🌍全球新闻获取完成!", receiver, sender) else: - self.message_util.send_text("❌获取新闻失败,请稍后再试", - (roomid if roomid else sender), sender) + await self.bot.send_text_message( + (roomid if roomid else sender), "❌获取新闻失败,请稍后再试", sender) except Exception as e: self.LOG.error(f"新闻获取任务出错: {e}") - self.message_util.send_text(f"❌获取新闻出错: {str(e)}", - (roomid if roomid else sender), sender) + await self.bot.send_text_message((roomid if roomid else sender), f"❌获取新闻出错: {str(e)}", + sender) finally: # 清理任务 if task_id in self._news_tasks: diff --git a/plugins/global_news/news_crawler.py b/plugins/global_news/news_crawler.py index 2e1486c..543d2e8 100644 --- a/plugins/global_news/news_crawler.py +++ b/plugins/global_news/news_crawler.py @@ -7,20 +7,10 @@ Created Date: 2024-05-01 import requests from time import localtime, sleep from lxml import etree -import logging +from loguru import logger from datetime import datetime import time -# 配置日志 -logging.basicConfig( - level=logging.INFO, - format='%(asctime)s - %(levelname)s - %(message)s', - handlers=[ - logging.FileHandler(f'global_news_{datetime.now().strftime("%Y%m%d")}.log'), - logging.StreamHandler() - ] -) -logger = logging.getLogger(__name__) # 请求配置 HEADERS = { diff --git a/plugins/group_auto_invite/main.py b/plugins/group_auto_invite/main.py index ece3a9d..31b8bfc 100644 --- a/plugins/group_auto_invite/main.py +++ b/plugins/group_auto_invite/main.py @@ -1,16 +1,14 @@ -import logging +from loguru import logger import redis import re from typing import Dict, Any, List, Optional, Tuple -from gewechat_client import GewechatClient - -from message_util import MessageUtil from plugin_common.message_plugin_interface import MessagePluginInterface from plugin_common.plugin_interface import PluginStatus from utils.decorator.plugin_decorators import plugin_stats_decorator from utils.robot_cmd.robot_command import GroupBotManager from utils.wechat.contact_manager import ContactManager +from wechat_ipad import WechatAPIClient class GroupAutoInvitePlugin(MessagePluginInterface): @@ -45,10 +43,10 @@ class GroupAutoInvitePlugin(MessagePluginInterface): # Redis 中存储群组映射的前缀 self.mapping_prefix = "group:group_mapping:" self._commands = [] + self.bot: WechatAPIClient = None def initialize(self, context: Dict[str, Any]) -> bool: """初始化插件""" - self.LOG = logging.getLogger(f"Plugin.{self.name}") self.LOG.info(f"正在初始化 {self.name} 插件...") # 获取群管理器 @@ -56,8 +54,6 @@ class GroupAutoInvitePlugin(MessagePluginInterface): # 获取Redis连接池 self.redis_pool = context.get("redis_pool") - self.clent:GewechatClient = context.get("clent") - self.message_util: MessageUtil = context.get("message_util") # 从配置中获取命令和启用状态 plugin_config = self._config.get("GroupAutoInvite", {}) self._commands = plugin_config.get("command", ["#加群配置"]) @@ -105,7 +101,7 @@ class GroupAutoInvitePlugin(MessagePluginInterface): return False @plugin_stats_decorator(plugin_name="自动加群功能") - def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """处理消息""" content = str(message.get("content", "")).strip() self.LOG.info(f"插件执行: {self.name}:{content}") @@ -114,25 +110,26 @@ class GroupAutoInvitePlugin(MessagePluginInterface): roomid = message.get("roomid", "") gbm: GroupBotManager = message.get("gbm") + self.bot: WechatAPIClient = message.get("bot") # 处理加群配置命令 if content.startswith("#加群配置|"): - return self._handle_config_command(content, sender, roomid, gbm) + return await self._handle_config_command(content, sender, roomid, gbm) # 处理加群请求 match = re.search(r"^#加群\s+(\w+)$", content) if match: - return self._handle_join_request(match.group(1), sender, roomid, gbm) + return await self._handle_join_request(match.group(1), sender, roomid, gbm) return False, "无法处理的消息" - def _handle_config_command(self, content: str, sender: str, roomid: str, gbm: GroupBotManager) -> Tuple[ + async def _handle_config_command(self, content: str, sender: str, roomid: str, gbm: GroupBotManager) -> Tuple[ bool, Optional[str]]: """处理配置命令""" # 检查是否为管理员 admin_list = self.gbm.get_admin_list() if sender not in admin_list: - self.message_util.send_text("⚠️ 权限不足,只有管理员才能配置群邀请功能", - (roomid if roomid else sender), sender) + await self.bot.send_text_message((roomid if roomid else sender), "⚠️ 权限不足,只有管理员才能配置群邀请功能", + sender) return True, "权限不足" # 解析命令 @@ -140,10 +137,10 @@ class GroupAutoInvitePlugin(MessagePluginInterface): result = self.process_command(command) # 发送结果 - self.message_util.send_text(result, (roomid if roomid else sender), sender) + await self.bot.send_text_message((roomid if roomid else sender), result, sender) return True, "配置命令处理成功" - def _handle_join_request(self, key: str, sender: str, roomid: str, gbm: GroupBotManager) -> Tuple[ + async def _handle_join_request(self, key: str, sender: str, roomid: str, gbm: GroupBotManager) -> Tuple[ bool, Optional[str]]: """处理加群请求""" try: @@ -152,29 +149,29 @@ class GroupAutoInvitePlugin(MessagePluginInterface): # 检查是否找到群ID if isinstance(group_id, str) and "没有关联的群ID" in group_id: - self.message_util.send_text(f"⚠️ 未找到关键词 '{key}' 对应的群聊", sender) + await self.bot.send_text_message(sender, f"⚠️ 未找到关键词 '{key}' 对应的群聊") return True, "未找到群聊" # 判断是否在群里面,如果在,则不添加 con = ContactManager.get_instance() members = con.get_group_members(group_id) # 如果在群里面,则不添加 if sender in members: - self.message_util.send_text(f"⚠️ 你已经在群聊中了,无需重复添加", sender) + await self.bot.send_text_message(sender, f"⚠️ 你已经在群聊中了,无需重复添加") return True, "你已经在群聊中了" # 发送邀请 self.LOG.info(f"邀请用户 {sender} 加入群 {group_id}") - result = self.message_util.invite_member(group_id, sender) + result = await self.bot.invite_chatroom_member(sender, group_id) if result: - self.message_util.send_text(f"✅ 已发送邀请,请查看群聊邀请通知", sender) + await self.bot.send_text_message(sender, f"✅ 已发送邀请,请查看群聊邀请通知") return True, "邀请发送成功" else: - self.message_util.send_text(f"❌ 邀请发送失败,请稍后再试", sender) + await self.bot.send_text_message(sender, f"❌ 邀请发送失败,请稍后再试") return False, "邀请发送失败" except Exception as e: self.LOG.error(f"处理加群请求出错: {e}") - self.message_util.send_text(f"❌ 处理加群请求出错: {e}", sender) + await self.bot.send_text_message(sender, f"❌ 处理加群请求出错: {e}") return False, f"处理出错: {e}" def add_mapping(self, key, group_id): diff --git a/plugins/group_member_change/main.py b/plugins/group_member_change/main.py index c40fb24..50a1f72 100644 --- a/plugins/group_member_change/main.py +++ b/plugins/group_member_change/main.py @@ -1,4 +1,3 @@ -import logging from datetime import datetime from typing import Dict, Any, List, Optional, Tuple @@ -6,16 +5,16 @@ import xml.etree.ElementTree as ET import dacite -from gewechat.client import gewe_client -from gewechat.response.model.group.chatroom_member_detail import ChatroomMemberDetail from plugin_common.message_plugin_interface import MessagePluginInterface from plugin_common.plugin_interface import PluginStatus from utils.robot_cmd.robot_command import Feature, PermissionStatus, GroupBotManager from message_util import MessageUtil # 导入消息工具类 +from wechat_ipad import WechatAPIClient class GroupMemberChangePlugin(MessagePluginInterface): """群成员变更监控插件""" + @property def name(self) -> str: return "群成员变更监控" @@ -46,7 +45,6 @@ class GroupMemberChangePlugin(MessagePluginInterface): def __init__(self): super().__init__() - self.LOG = logging.getLogger(f"Plugin.{self.name}") def initialize(self, context: Dict[str, Any]) -> bool: """初始化插件""" @@ -58,7 +56,11 @@ class GroupMemberChangePlugin(MessagePluginInterface): self.LOG.info(f"{self.name} 插件初始化完成") return True - def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + def can_process(self, message: Dict[str, Any]) -> bool: + """检查是否可以处理该消息""" + return True + + async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """处理接收到的消息""" content = str(message.get("content", "")).strip() @@ -67,6 +69,7 @@ class GroupMemberChangePlugin(MessagePluginInterface): roomid = message.get("roomid", "") gbm: GroupBotManager = message.get("gbm") + bot: WechatAPIClient = message.get("bot") # 检查权限 if roomid and gbm.get_group_permission(roomid, Feature.GROUP_MEMBER_CHANGE) == PermissionStatus.DISABLED: return False, "没有权限" @@ -114,18 +117,18 @@ class GroupMemberChangePlugin(MessagePluginInterface): wxid = member["wxid"] nickname = member["nickname"] - now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + # now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") member_wxids = [wxid] - profile: ChatroomMemberDetail = dacite.from_dict(ChatroomMemberDetail, - gewe_client.client.get_chatroom_member_detail( - gewe_client.client.app_id, - member_wxids)) - if profile.ret == 200: - gewe_client.client.post_link(gewe_client.client.app_id, sender, - title=f"👏欢迎 {nickname} 加入群聊!🎉", - description=f"⌚时间:{now}\n", - url="https://hot.imsyy.top/#/", - thumb_url=profile.data[0].big_head_img_url) + + await bot.send_at_message(roomid, f"👏欢迎 {nickname} 加入群聊!🎉", member_wxids) + # members = await bot.get_contract_detail(member_wxids, roomid) + + # if members: + # gewe_client.client.post_link(gewe_client.client.app_id, sender, + # title=f"👏欢迎 {nickname} 加入群聊!🎉", + # description=f"⌚时间:{now}\n", + # url="https://hot.imsyy.top/#/", + # thumb_url=profile.data[0].big_head_img_url) return True, "已发送进群欢迎语" return False, "无需执行" diff --git a/plugins/group_virtual/main.py b/plugins/group_virtual/main.py index fd83314..d7c5bf9 100644 --- a/plugins/group_virtual/main.py +++ b/plugins/group_virtual/main.py @@ -1,7 +1,5 @@ -import logging from typing import Dict, Any, List, Optional, Tuple -from gewechat.call_back_message.message import WxMessage from message_util import MessageUtil from plugin_common.message_plugin_interface import MessagePluginInterface from plugin_common.plugin_interface import PluginStatus @@ -9,6 +7,7 @@ from utils.decorator.plugin_decorators import plugin_stats_decorator from utils.wechat.contact_manager import ContactManager from db.connection import DBConnectionManager from db.group_virtual_redis import GroupVirtualRedisDB +from wechat_ipad.models.message import WxMessage class GroupVirtualPlugin(MessagePluginInterface): @@ -46,7 +45,6 @@ class GroupVirtualPlugin(MessagePluginInterface): def initialize(self, context: Dict[str, Any]) -> bool: """初始化插件""" - self.LOG = logging.getLogger(f"Plugin.{self.name}") self.LOG.info(f"正在初始化 {self.name} 插件...") # 保存上下文对象 @@ -97,7 +95,7 @@ class GroupVirtualPlugin(MessagePluginInterface): """处理消息""" roomid = message.get("roomid", "") sender = message.get("sender", "") - full_wx_msg: WxMessage = message.get("full_wx_msg", "") + full_wx_msg: WxMessage = message.get("full_wx_msg") # 检查是否是机器人自己发送的消息 if full_wx_msg.from_self(): return False, "不转发自己的消息" diff --git a/plugins/message_recall/main.py b/plugins/message_recall/main.py index 9ad9e07..2a4abaf 100644 --- a/plugins/message_recall/main.py +++ b/plugins/message_recall/main.py @@ -1,4 +1,4 @@ -import logging +from loguru import logger from typing import Dict, Any, List, Tuple, Optional from message_util import MessageUtil @@ -40,7 +40,7 @@ class MessageRecallPlugin(MessagePluginInterface): def initialize(self, context: Dict[str, Any]) -> bool: """初始化插件""" - self.LOG = logging.getLogger(f"Plugin.{self.name}") + self.LOG = logger self.LOG.info(f"正在初始化 {self.name} 插件...") self.event_system = context.get("event_system") diff --git a/plugins/message_sign/main.py b/plugins/message_sign/main.py index e8031f0..c503f8a 100644 --- a/plugins/message_sign/main.py +++ b/plugins/message_sign/main.py @@ -1,11 +1,9 @@ from datetime import datetime, timedelta -import logging +from loguru import logger import pytz from typing import Dict, Any, List, Optional, Tuple - from db.connection import DBConnectionManager -from message_util import MessageUtil from plugin_common.message_plugin_interface import MessagePluginInterface from plugin_common.plugin_interface import PluginStatus from utils.decorator.plugin_decorators import plugin_stats_decorator @@ -16,6 +14,7 @@ import random import os from utils.decorator.points_decorator import points_reward_decorator +from wechat_ipad import WechatAPIClient class MessageSignPlugin(MessagePluginInterface): @@ -56,15 +55,15 @@ class MessageSignPlugin(MessagePluginInterface): self.vocab_file_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "resource", "6 托福-乱序.txt") self.vocab_list = [] + self.bot: WechatAPIClient = None def initialize(self, context: Dict[str, Any]) -> bool: """初始化插件""" - self.LOG = logging.getLogger(f"Plugin.{self.name}") + self.LOG = logger self.LOG.info(f"正在初始化 {self.name} 插件...") # 保存上下文对象 self.event_system = context.get("event_system") - self.message_util: MessageUtil = context.get("message_util") self.gbm = context.get("gbm") self.all_contacts = context.get("all_contacts", {}) @@ -178,15 +177,15 @@ class MessageSignPlugin(MessagePluginInterface): # 使用数据库中已更新的连签天数 streak = user_record.get('signin_streak', 1) # 如果今天刚签到,连签天数已经+1,所以这里不需要再加1 - + # 计算积分 points = self.calculate_points(streak) - + return points # 修改 process_message 方法,作为路由分发 @plugin_stats_decorator(plugin_name="签到系统") - def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """处理消息""" content = str(message.get("content", "")).strip() self.LOG.info(f"插件执行: {self.name}:{content}") @@ -194,6 +193,7 @@ class MessageSignPlugin(MessagePluginInterface): sender = message.get("sender") roomid = message.get("roomid", "") gbm: GroupBotManager = message.get("gbm") + self.bot = message.get("bot") # 检查权限 if roomid and gbm.get_group_permission(roomid, Feature.SIGNIN) == PermissionStatus.DISABLED: @@ -201,17 +201,17 @@ class MessageSignPlugin(MessagePluginInterface): # 处理补签命令 if command in self._makeup_commands: - return self._handle_makeup_sign(message) + return await self._handle_makeup_sign(message) # 处理正常签到命令 if command in self._commands: - return self._handle_sign_in(message) + return await self._handle_sign_in(message) return False, "不支持的命令" # 添加签到处理方法,应用积分奖励装饰器 @points_reward_decorator(calculate_sign_in_points, "checkin", "每日签到奖励", Feature.SIGNIN) - def _handle_sign_in(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + async def _handle_sign_in(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """处理签到请求""" sender = message.get("sender") roomid = message.get("roomid", "") @@ -237,8 +237,8 @@ class MessageSignPlugin(MessagePluginInterface): # 如果 sign_stat 已经大于或等于今天的零点,则认为用户已经签到过了 if sign_stat >= today_start: - self.message_util.send_text(f"您今天已经签到过了!", - (roomid if roomid else sender), sender) + await self.bot.send_text_message( + (roomid if roomid else sender), f"您今天已经签到过了!", sender) return False, "已签到" # 在_handle_sign_in方法中,修改断签处理逻辑 @@ -313,13 +313,13 @@ class MessageSignPlugin(MessagePluginInterface): daily_vocab = self.get_random_vocabulary() output += f"\n今日词汇:{daily_vocab}" - self.message_util.send_text(output, (roomid if roomid else sender), sender) + await self.bot.send_text_message((roomid if roomid else sender), output, sender) return True, "签到成功" except Exception as e: self.LOG.error(f"处理签到请求出错: {e}") - self.message_util.send_text(f"签到出错:{e}", - (roomid if roomid else sender), sender) + await self.bot.send_text_message((roomid if roomid else sender), f"签到出错:{e}", + sender) return False, f"处理出错: {e}" def reset_today_count_if_needed(self): @@ -350,7 +350,7 @@ class MessageSignPlugin(MessagePluginInterface): # 修改_handle_makeup_sign方法,实现连签恢复功能 - def _handle_makeup_sign(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + async def _handle_makeup_sign(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """处理补签请求""" sender = message.get("sender") roomid = message.get("roomid", "") @@ -370,9 +370,9 @@ class MessageSignPlugin(MessagePluginInterface): # 检查用户是否有签到记录 if not user_record: - self.message_util.send_text( - "❌ 您还没有签到记录,请先进行签到!", - (roomid if roomid else sender), sender + await self.bot.send_text_message( + (roomid if roomid else sender), + "❌ 您还没有签到记录,请先进行签到!", sender ) return True, "无签到记录" @@ -403,27 +403,26 @@ class MessageSignPlugin(MessagePluginInterface): else: # 昨天已经签到了或者断签超过一天,不需要补签 self.LOG.info(f"不符合补签条件,last_sign_date: {last_sign_date}, sign_stat: {sign_stat}") - self.message_util.send_text( - "❌ 您昨天已经签到过了或断签超过一天,不符合补签条件!", - (roomid if roomid else sender), sender + await self.bot.send_text_message( + (roomid if roomid else sender), "❌ 您昨天已经签到过了或断签超过一天,不符合补签条件!", sender ) return True, "不符合补签条件" else: # 今天未签到,检查是否符合补签条件(只能补签昨天) if not last_sign_date or last_sign_date < day_before_yesterday: self.LOG.info(f"断签超过一天,last_sign_date: {last_sign_date}") - self.message_util.send_text( - "❌ 只能补签断签一天的情况!您已断签超过一天或没有签到记录。", - (roomid if roomid else sender), sender - ) + await self.bot.send_text_message((roomid if roomid else sender), + "❌ 只能补签断签一天的情况!您已断签超过一天或没有签到记录。", + sender + ) return True, "不符合补签条件" if last_sign_date >= yesterday: self.LOG.info(f"昨天已签到,last_sign_date: {last_sign_date}") - self.message_util.send_text( - "❌ 您昨天已经签到过了,不需要补签!", - (roomid if roomid else sender), sender - ) + await self.bot.send_text_message((roomid if roomid else sender), + "❌ 您昨天已经签到过了,不需要补签!", + sender + ) return True, "无需补签" # 检查用户积分是否足够 @@ -432,10 +431,10 @@ class MessageSignPlugin(MessagePluginInterface): user_points = points_db.get_user_points(sender, roomid) if not user_points or user_points["total_points"] < self.makeup_cost: - self.message_util.send_text( - f"❌ 积分不足!补签需要 {self.makeup_cost} 积分,您当前只有 {user_points.get('total_points', 0)} 积分。", - (roomid if roomid else sender), sender - ) + await self.bot.send_text_message((roomid if roomid else sender), + f"❌ 积分不足!补签需要 {self.makeup_cost} 积分,您当前只有 {user_points.get('total_points', 0)} 积分。", + sender + ) return True, "积分不足" # 扣除积分 @@ -445,10 +444,10 @@ class MessageSignPlugin(MessagePluginInterface): ) if not deduct_success: - self.message_util.send_text( - f"❌ 扣除积分失败:{deduct_result.get('error', '未知错误')}", - (roomid if roomid else sender), sender - ) + await self.bot.send_text_message((roomid if roomid else sender), + f"❌ 扣除积分失败:{deduct_result.get('error', '未知错误')}", + sender + ) return True, "扣除积分失败" # 在_handle_makeup_sign方法中,修改计算新连签天数的逻辑 @@ -504,17 +503,17 @@ class MessageSignPlugin(MessagePluginInterface): success_message += f"💰 当前积分:{user_points['total_points'] - self.makeup_cost}" - self.message_util.send_text( - success_message, - (roomid if roomid else sender), sender + await self.bot.send_text_message( + (roomid if roomid else sender), + success_message, sender ) return True, "补签成功" except Exception as e: self.LOG.error(f"处理补签请求出错: {e}") - self.message_util.send_text( - f"❌ 补签出错:{e}", - (roomid if roomid else sender), sender + await self.bot.send_text_message( + (roomid if roomid else sender), + f"❌ 补签出错:{e}", sender ) return False, f"处理出错: {e}" diff --git a/plugins/music/main.py b/plugins/music/main.py index 7d14385..e443889 100644 --- a/plugins/music/main.py +++ b/plugins/music/main.py @@ -1,14 +1,13 @@ -import logging +from loguru import logger import requests from typing import Dict, Any, List, Optional, Tuple -from gewechat.client import gewe_client -from gewechat.response.gewe_resp import GeweResponse from plugin_common.message_plugin_interface import MessagePluginInterface from plugin_common.plugin_interface import PluginStatus from utils.decorator.plugin_decorators import plugin_stats_decorator from utils.robot_cmd.robot_command import Feature, PermissionStatus, GroupBotManager from utils.decorator.points_decorator import plugin_points_cost +from wechat_ipad import WechatAPIClient class MusicPlugin(MessagePluginInterface): @@ -43,7 +42,7 @@ class MusicPlugin(MessagePluginInterface): def initialize(self, context: Dict[str, Any]) -> bool: """初始化插件""" - self.LOG = logging.getLogger(f"Plugin.{self.name}") + self.LOG = logger self.LOG.info(f"正在初始化 {self.name} 插件...") # 保存上下文对象 @@ -81,7 +80,7 @@ class MusicPlugin(MessagePluginInterface): @plugin_stats_decorator(plugin_name="音乐点播") @plugin_points_cost(2, "音乐点播消耗积分", Feature.MUSIC) - def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """处理消息""" content = str(message.get("content", "")).strip() self.LOG.info(f"插件执行: {self.name}:{content}") @@ -89,11 +88,12 @@ class MusicPlugin(MessagePluginInterface): sender = message.get("sender") roomid = message.get("roomid", "") gbm: GroupBotManager = message.get("gbm") + bot: WechatAPIClient = message.get("bot") # 检查命令格式 if len(content.split(" ")) == 1: - self.message_util.send_text(f"❌命令格式错误!\n{self.command_format}", - (roomid if roomid else sender), sender) + await bot.send_text_message((roomid if roomid else sender), f"❌命令格式错误!\n{self.command_format}" + , sender) return False, "命令格式错误" # 检查权限 @@ -107,12 +107,11 @@ class MusicPlugin(MessagePluginInterface): # 搜索歌曲 song_info = self._search_song(user_song_name) if not song_info or not song_info.get("play_url"): - self.message_util.send_text(f"❌未找到歌曲:{user_song_name}", - (roomid if roomid else sender), sender) + await bot.send_text_message((roomid if roomid else sender), f"❌未找到歌曲:{user_song_name}", sender) return False, "未找到歌曲" # 发送音乐 - self._send_music_message(song_info, roomid or sender) + await self._send_music_message(bot, song_info, roomid or sender) return True, "发送成功" except Exception as e: @@ -143,7 +142,7 @@ class MusicPlugin(MessagePluginInterface): self.LOG.error(f"搜索歌曲出错: {e}") return {} - def _send_music_message(self, song_info: Dict[str, Any], receiver: str) -> bool: + async def _send_music_message(self, bot: WechatAPIClient, song_info: Dict[str, Any], receiver: str) -> bool: """发送音乐消息""" try: song_name = song_info.get("song_name", "") @@ -201,11 +200,11 @@ class MusicPlugin(MessagePluginInterface): """ - resp = gewe_client.client.post_app_msg(gewe_client.client.app_id, receiver, xml_message) - data = GeweResponse(resp) - self.LOG.info(f"发送音乐消息:{data}") - if data.is_success: - return True + + self.LOG.info(f"发送音乐消息:{xml_message}") + res = await bot.send_app_message(wxid=receiver, xml=xml_message, type=0) + self.LOG.info(f"发送音乐消息 res:{res}") + return True except Exception as e: self.LOG.error(f"发送音乐消息出错: {e}") diff --git a/plugins/plugin_manager/main.py b/plugins/plugin_manager/main.py index 40e8c23..9bfe0f3 100644 --- a/plugins/plugin_manager/main.py +++ b/plugins/plugin_manager/main.py @@ -1,4 +1,4 @@ -import logging +from loguru import logger import os from typing import Dict, Any, List, Optional, Tuple @@ -53,7 +53,7 @@ class PluginManagerPlugin(MessagePluginInterface): def initialize(self, context: Dict[str, Any]) -> bool: """初始化插件""" - self.LOG = logging.getLogger(f"Plugin.{self.name}") + self.LOG = logger self.LOG.info(f"正在初始化 {self.name} 插件...") # 保存上下文对象 diff --git a/plugins/point_trade/main.py b/plugins/point_trade/main.py index e97354a..ffc8280 100644 --- a/plugins/point_trade/main.py +++ b/plugins/point_trade/main.py @@ -1,10 +1,9 @@ -import logging +from loguru import logger import re from datetime import datetime from typing import Dict, Any, List, Optional, Tuple import xml.etree.ElementTree as ET - from db.connection import DBConnectionManager from db.points_db import PointsDBOperator, PointSource from message_util import MessageUtil @@ -15,6 +14,8 @@ from utils.robot_cmd.robot_command import Feature, PermissionStatus, GroupBotMan import mysql.connector.pooling +from wechat_ipad import WechatAPIClient + class PointTradePlugin(MessagePluginInterface): """积分交易插件""" @@ -46,15 +47,15 @@ class PointTradePlugin(MessagePluginInterface): def __init__(self): super().__init__() self.db_pool = None + self.bot: WechatAPIClient = None def initialize(self, context: Dict[str, Any]) -> bool: """初始化插件""" - self.LOG = logging.getLogger(f"Plugin.{self.name}") + self.LOG = logger self.LOG.info(f"正在初始化 {self.name} 插件...") # 保存上下文对象 self.event_system = context.get("event_system") - self.message_util: MessageUtil = context.get("message_util") self.gbm = context.get("gbm") self.db_manager = DBConnectionManager.get_instance() @@ -120,7 +121,7 @@ class PointTradePlugin(MessagePluginInterface): return command in self._commands @plugin_stats_decorator(plugin_name="积分交易") - def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """处理消息""" content = str(message.get("content", "")).strip() self.LOG.info(f"插件执行: {self.name}:{content}") @@ -129,6 +130,7 @@ class PointTradePlugin(MessagePluginInterface): roomid = message.get("roomid", "") gbm: GroupBotManager = message.get("gbm") xml = message.get("xml", "") + self.bot: WechatAPIClient = message.get("bot") # 检查权限 if roomid and gbm.get_group_permission(roomid, Feature.POINT_TRADE) == PermissionStatus.DISABLED: @@ -136,21 +138,21 @@ class PointTradePlugin(MessagePluginInterface): # 处理不同的命令 if command[0] == "我的积分": - return self._handle_my_points(message) + return await self._handle_my_points(message) elif command[0] == "积分排行": - return self._handle_points_ranking(message) + return await self._handle_points_ranking(message) elif command[0] == "打劫": - return self._handle_rob_points(message) + return await self._handle_rob_points(message) elif command[0] == "保释": - return self._handle_bailout(message) + return await self._handle_bailout(message) elif command[0] in self._commands: - return self._handle_transfer_points(message) + return await self._handle_transfer_points(message) else: - self.message_util.send_text(f"❌未知命令!{self.command_format}", - (roomid if roomid else sender), sender) + await self.bot.send_text_message((roomid if roomid else sender), f"❌未知命令!{self.command_format}", + sender) return True, "未知命令" - def _handle_transfer_points(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + async def _handle_transfer_points(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """处理积分转账命令""" content = str(message.get("content", "")).strip() command = content.split(" ") @@ -160,21 +162,23 @@ class PointTradePlugin(MessagePluginInterface): # 检查命令格式 if len(command) < 3: - self.message_util.send_text(f"❌命令格式错误!积分转账 积分数 @用户", - (roomid if roomid else sender), sender) + await self.bot.send_text_message((roomid if roomid else sender), f"❌命令格式错误!积分转账 积分数 @用户", + sender) return True, "命令格式错误" # 检查积分数是否为正整数 if not command[1].isdigit(): - self.message_util.send_text(f"🈚️转账积分无效(必须为正整数!) \n积分转账 积分数 @用户", - (roomid if roomid else sender), sender) + await self.bot.send_text_message((roomid if roomid else sender), + f"🈚️转账积分无效(必须为正整数!) \n积分转账 积分数 @用户", + sender) return True, "积分无效" # 检查@用户是否有效 at_users = self.at_list(xml) if len(at_users) != 1: - self.message_util.send_text(f"转账失败❌\n🈚️转账人无效! \n积分转账 积分数 @用户", - (roomid if roomid else sender), sender) + await self.bot.send_text_message((roomid if roomid else sender), + f"转账失败❌\n🈚️转账人无效! \n积分转账 积分数 @用户", + sender) return True, "转账人无效" reward_points = int(command[1]) @@ -193,13 +197,13 @@ class PointTradePlugin(MessagePluginInterface): error_msg = result.get("error", "未知错误") if "积分不足" in error_msg: current_points = result.get("current_points", 0) - self.message_util.send_text( - f"❌转账失败!\n你的积分不足以进行转账!当前积分:{current_points},你需要 {reward_points} 积分。", - (roomid if roomid else sender), sender) + await self.bot.send_text_message((roomid if roomid else sender), + f"❌转账失败!\n你的积分不足以进行转账!当前积分:{current_points},你需要 {reward_points} 积分。", + sender) else: - self.message_util.send_text( - f"❌转账失败!\n{error_msg}", - (roomid if roomid else sender), sender) + await self.bot.send_text_message((roomid if roomid else sender), + f"❌转账失败!\n{error_msg}", + sender) return True, f"转账失败: {error_msg}" # 获取转账后的积分信息 @@ -220,16 +224,16 @@ class PointTradePlugin(MessagePluginInterface): f"👤{to_user_name} 当前积分: {to_user.get('total_points', 0)}" ) - self.message_util.send_text(output, (roomid if roomid else sender), sender) + await self.bot.send_text_message((roomid if roomid else sender), output, sender) return True, "转账成功" except Exception as e: self.LOG.error(f"积分交易出错: {e}") - self.message_util.send_text(f"❌积分交易失败!请稍后重试。错误: {str(e)}", - (roomid if roomid else sender), sender) + await self.bot.send_text_message((roomid if roomid else sender), f"❌积分交易失败!请稍后重试。错误: {str(e)}", + sender) return True, f"处理出错: {str(e)}" - def _handle_my_points(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + async def _handle_my_points(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """处理查询个人积分命令""" sender = message.get("sender") roomid = message.get("roomid", "") @@ -239,8 +243,9 @@ class PointTradePlugin(MessagePluginInterface): user_points = self.points_db.get_user_points(sender, roomid) if not user_points: - self.message_util.send_text(f"❌未找到你的积分记录!请先参与积分活动[签到,答题/t]。", - (roomid if roomid else sender), sender) + await self.bot.send_text_message((roomid if roomid else sender), + f"❌未找到你的积分记录!请先参与积分活动[签到,答题/t]。", + sender) return False, "未找到积分记录" # 获取用户昵称 @@ -295,22 +300,22 @@ class PointTradePlugin(MessagePluginInterface): f"{recent_txs}" ) - self.message_util.send_text(output, (roomid if roomid else sender), sender) + await self.bot.send_text_message((roomid if roomid else sender), output, sender) return True, "查询积分成功" except Exception as e: self.LOG.error(f"查询积分出错: {e}") - self.message_util.send_text(f"❌查询积分失败!请稍后重试。错误: {str(e)}", - (roomid if roomid else sender), sender) + await self.bot.send_text_message((roomid if roomid else sender), f"❌查询积分失败!请稍后重试。错误: {str(e)}", + sender) return True, f"处理出错: {str(e)}" - def _handle_points_ranking(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + async def _handle_points_ranking(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """处理积分排行榜命令""" sender = message.get("sender") roomid = message.get("roomid", "") if not roomid: - self.message_util.send_text("❌积分排行榜仅在群聊中可用!", sender, "") + await self.bot.send_text_message(sender, "❌积分排行榜仅在群聊中可用!", "") return True, "非群聊环境" try: @@ -318,7 +323,7 @@ class PointTradePlugin(MessagePluginInterface): ranking = self.points_db.get_points_ranking(roomid, 10) if not ranking: - self.message_util.send_text("❌暂无积分排行数据!请先参与积分活动。", roomid, sender) + await self.bot.send_text_message(roomid, "❌暂无积分排行数据!请先参与积分活动。", sender) return True, "无排行数据" # 构建排行榜消息 @@ -343,12 +348,12 @@ class PointTradePlugin(MessagePluginInterface): f"更新时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}" ) - self.message_util.send_text(output, roomid, sender) + await self.bot.send_text_message(roomid, output, sender) return True, "查询排行榜成功" except Exception as e: self.LOG.error(f"查询积分排行榜出错: {e}") - self.message_util.send_text(f"❌查询积分排行榜失败!请稍后重试。错误: {str(e)}", roomid, sender) + await self.bot.send_text_message(roomid, f"❌查询积分排行榜失败!请稍后重试。错误: {str(e)}", sender) return True, f"处理出错: {str(e)}" def at_list(self, xml): @@ -438,7 +443,7 @@ class PointTradePlugin(MessagePluginInterface): self.LOG.error(f"更新用户积分失败: {e}") raise - def _handle_rob_points(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + async def _handle_rob_points(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """处理打劫积分命令""" import random import time @@ -451,13 +456,13 @@ class PointTradePlugin(MessagePluginInterface): # 检查是否在群聊中 if not roomid: - self.message_util.send_text("❌打劫功能仅在群聊中可用!", sender, "") + await self.bot.send_text_message(sender, "❌打劫功能仅在群聊中可用!", "") return True, "非群聊环境" # 检查时间限制 - 只允许在18:00-21:00之间打劫 current_hour = datetime.now().hour if current_hour < 18 or current_hour >= 21: - self.message_util.send_text("❌打劫功能仅在晚上18:00-21:00之间开放!请在开放时间再来。", roomid, sender) + await self.bot.send_text_message(roomid, "❌打劫功能仅在晚上18:00-21:00之间开放!请在开放时间再来。", sender) return True, "时间限制" # 检查是否在押 @@ -466,8 +471,10 @@ class PointTradePlugin(MessagePluginInterface): remaining_time = prison_status['end_time'] - datetime.now() hours = int(remaining_time.total_seconds() / 3600) minutes = int((remaining_time.total_seconds() % 3600) / 60) - self.message_util.send_text(f"❌你正在服刑!\n剩余时间: {hours}小时{minutes}分钟\n可请求他人花费30积分保释。", roomid, - sender) + await self.bot.send_text_message( + f"❌你正在服刑!\n剩余时间: {hours}小时{minutes}分钟\n可请求他人花费30积分保释。", + roomid, + sender) return True, "在押状态" # 检查冷却时间 @@ -478,15 +485,16 @@ class PointTradePlugin(MessagePluginInterface): if time_passed < self.rob_cooldown: remaining_time = int(self.rob_cooldown - time_passed) minutes, seconds = divmod(remaining_time, 60) - self.message_util.send_text(f"❌你最近已经打劫过了,需要冷却 {minutes}分{seconds}秒 后才能再次打劫!", - roomid, sender) + await self.bot.send_text_message(roomid, + f"❌你最近已经打劫过了,需要冷却 {minutes}分{seconds}秒 后才能再次打劫!", + sender) return True, "冷却中" # 检查@用户是否有效 at_users = self.at_list(xml) if len(at_users) != 1: - self.message_util.send_text(f"打劫失败❌\n请指定一个打劫目标!\n打劫 @用户", - roomid, sender) + await self.bot.send_text_message(roomid, f"打劫失败❌\n请指定一个打劫目标!\n打劫 @用户", + sender) return True, "目标无效" target_wxid = next(iter(at_users)) @@ -494,7 +502,7 @@ class PointTradePlugin(MessagePluginInterface): # 不能打劫自己 if target_wxid == robber_wxid: - self.message_util.send_text("❌你不能打劫自己!", roomid, sender) + await self.bot.send_text_message(roomid, "❌你不能打劫自己!", sender) return True, "不能打劫自己" try: @@ -503,11 +511,11 @@ class PointTradePlugin(MessagePluginInterface): target_points = self.points_db.get_user_points(target_wxid, roomid) if not robber_points: - self.message_util.send_text("❌你没有积分记录,无法进行打劫!请先参与积分活动。", roomid, sender) + await self.bot.send_text_message(roomid, "❌你没有积分记录,无法进行打劫!请先参与积分活动。", sender) return True, "打劫者无积分" if not target_points: - self.message_util.send_text("❌目标没有积分记录,无法进行打劫!", roomid, sender) + await self.bot.send_text_message(roomid, "❌目标没有积分记录,无法进行打劫!", sender) return True, "目标无积分" robber_total = robber_points.get('total_points', 0) @@ -515,11 +523,12 @@ class PointTradePlugin(MessagePluginInterface): # 检查最低积分要求 if robber_total < self.rob_min_points: - self.message_util.send_text(f"❌你的积分不足 {self.rob_min_points} 点,无法进行打劫!", roomid, sender) + await self.bot.send_text_message(roomid, f"❌你的积分不足 {self.rob_min_points} 点,无法进行打劫!", + sender) return True, "打劫者积分不足" if target_total < self.rob_min_points: - self.message_util.send_text(f"❌目标积分不足 {self.rob_min_points} 点,不值得打劫!", roomid, sender) + await self.bot.send_text_message(roomid, f"❌目标积分不足 {self.rob_min_points} 点,不值得打劫!", sender) return True, "目标积分不足" # 获取用户昵称 @@ -575,10 +584,11 @@ class PointTradePlugin(MessagePluginInterface): f"👤{target_name} 当前积分: {from_user.get('total_points', 0)}" ) - self.message_util.send_text(output, roomid, sender) + await self.bot.send_text_message(output, roomid, sender) return True, "打劫成功" else: - self.message_util.send_text(f"❌打劫过程中出现问题:{result.get('error', '未知错误')}", roomid, sender) + await self.bot.send_text_message(roomid, f"❌打劫过程中出现问题:{result.get('error', '未知错误')}", + sender) return True, "打劫失败" else: @@ -612,18 +622,20 @@ class PointTradePlugin(MessagePluginInterface): f"👤{robber_name} 当前积分: {from_user.get('total_points', 0)}" ) - self.message_util.send_text(output, roomid, sender) + await self.bot.send_text_message(roomid, output, sender) return True, "打劫失败" else: - self.message_util.send_text(f"❌处理打劫惩罚时出现问题:{result.get('error', '未知错误')}", roomid, sender) + await self.bot.send_text_message(roomid, + f"❌处理打劫惩罚时出现问题:{result.get('error', '未知错误')}", + sender) return True, "处理惩罚失败" except Exception as e: self.LOG.error(f"处理打劫请求出错: {e}") - self.message_util.send_text(f"❌打劫过程中出现意外:{str(e)}", roomid, sender) + await self.bot.send_text_message(roomid, f"❌打劫过程中出现意外:{str(e)}", sender) return True, f"处理出错: {str(e)}" - def _handle_bailout(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + async def _handle_bailout(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """处理保释命令""" sender = message.get("sender") roomid = message.get("roomid", "") @@ -631,14 +643,14 @@ class PointTradePlugin(MessagePluginInterface): # 检查是否在群聊中 if not roomid: - self.message_util.send_text("❌保释功能仅在群聊中可用!", sender, "") + await self.bot.send_text_message(sender, "❌保释功能仅在群聊中可用!", "") return True, "非群聊环境" # 检查@用户是否有效 at_users = self.at_list(xml) if len(at_users) != 1: - self.message_util.send_text(f"保释失败❌\n请指定一个保释目标!\n保释 @用户", - roomid, sender) + await self.bot.send_text_message(roomid, f"保释失败❌\n请指定一个保释目标!\n保释 @用户", + sender) return True, "目标无效" prisoner_wxid = next(iter(at_users)) @@ -646,7 +658,7 @@ class PointTradePlugin(MessagePluginInterface): # 不能保释自己 if prisoner_wxid == bailout_wxid: - self.message_util.send_text("❌你不能保释自己!", roomid, sender) + await self.bot.send_text_message(roomid, "❌你不能保释自己!", sender) return True, "不能保释自己" try: @@ -665,13 +677,13 @@ class PointTradePlugin(MessagePluginInterface): f"✅ 保释成功!\n" f"👤{bailout_name} 花费30积分保释了 👤{prisoner_name}" ) - self.message_util.send_text(output, roomid, sender) + await self.bot.send_text_message(roomid, output, sender) return True, "保释成功" else: - self.message_util.send_text(f"❌保释失败: {message}", roomid, sender) + await self.bot.send_text_message(roomid, f"❌保释失败: {message}", sender) return True, "保释失败" except Exception as e: self.LOG.error(f"处理保释请求出错: {e}") - self.message_util.send_text(f"❌保释过程中出现意外:{str(e)}", roomid, sender) + await self.bot.send_text_message(roomid, f"❌保释过程中出现意外:{str(e)}", sender) return True, f"处理出错: {str(e)}" diff --git a/plugins/stats_collector/main.py b/plugins/stats_collector/main.py index a995cd2..133f9c1 100644 --- a/plugins/stats_collector/main.py +++ b/plugins/stats_collector/main.py @@ -1,4 +1,4 @@ -import logging +from loguru import logger import time from typing import Dict, Any, Tuple, Optional, List from datetime import datetime @@ -42,7 +42,7 @@ class StatsCollectorPlugin(PluginInterface): def __init__(self): super().__init__() - self.logger = logging.getLogger("StatsCollector") + self.LOG = logger self.LOG.info(f"正在初始化 {self.name} 插件...") # 默认配置 @@ -62,7 +62,7 @@ class StatsCollectorPlugin(PluginInterface): self.config.update(config) if not self.config["enable"]: - self.logger.info("统计收集插件已禁用") + self.LOG.info("统计收集插件已禁用") return False # 注册事件处理器 @@ -79,7 +79,7 @@ class StatsCollectorPlugin(PluginInterface): return # 记录开始时间和相关信息 - self.logger.debug(f"记录插件调用开始: {event.plugin_name} - {event.command}") + self.LOG.debug(f"记录插件调用开始: {event.plugin_name} - {event.command}") def handle_plugin_call_end(self, event: PluginCallEndEvent) -> None: """处理插件调用结束事件""" @@ -98,10 +98,10 @@ class StatsCollectorPlugin(PluginInterface): success=event.process_result, process_time_ms=event.process_time ) - self.logger.debug( + self.LOG.debug( f"记录插件调用结束: {event.plugin_name} - {event.command} - 成功: {event.process_result} - 处理时间: {event.process_time}ms") except Exception as e: - self.logger.error(f"记录插件调用统计数据出错: {e}") + self.LOG.error(f"记录插件调用统计数据出错: {e}") def handle_plugin_error(self, event: PluginCallErrorEvent) -> None: """处理插件调用错误事件""" @@ -119,9 +119,9 @@ class StatsCollectorPlugin(PluginInterface): error_message=event.error_message, stack_trace=event.stack_trace ) - self.logger.debug(f"记录插件调用错误: {event.plugin_name} - {event.command} - {event.error_message}") + self.LOG.debug(f"记录插件调用错误: {event.plugin_name} - {event.command} - {event.error_message}") except Exception as e: - self.logger.error(f"记录插件错误信息出错: {e}") + self.LOG.error(f"记录插件错误信息出错: {e}") def _should_record_plugin(self, plugin_name: str) -> bool: """检查是否应该记录该插件的调用""" @@ -154,7 +154,7 @@ class StatsCollectorPlugin(PluginInterface): self.event_manager.unregister(PluginCallEndEvent, self.handle_plugin_call_end) self.event_manager.unregister(PluginCallErrorEvent, self.handle_plugin_error) - self.logger.info("统计收集插件已关闭") + self.LOG.info("统计收集插件已关闭") def start(self) -> bool: """启动插件""" diff --git a/plugins/system_updater/main.py b/plugins/system_updater/main.py index a292509..3dde61e 100644 --- a/plugins/system_updater/main.py +++ b/plugins/system_updater/main.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -import logging +from loguru import logger from typing import Dict, Any, List, Optional, Tuple from plugin_common.message_plugin_interface import MessagePluginInterface @@ -42,7 +42,7 @@ class SystemUpdaterPlugin(MessagePluginInterface): def initialize(self, context: Dict[str, Any]) -> bool: """初始化插件""" - self.LOG = logging.getLogger(f"Plugin.{self.name}") + self.LOG = logger self.LOG.info(f"正在初始化 {self.name} 插件...") # 保存上下文对象 diff --git a/plugins/video/main.py b/plugins/video/main.py index 9df3bc6..36b100e 100644 --- a/plugins/video/main.py +++ b/plugins/video/main.py @@ -1,14 +1,14 @@ -import logging +from loguru import logger import os import requests from typing import Dict, Any, List, Optional, Tuple - from plugin_common.message_plugin_interface import MessagePluginInterface from plugin_common.plugin_interface import PluginStatus from utils.decorator.plugin_decorators import plugin_stats_decorator from utils.robot_cmd.robot_command import Feature, PermissionStatus, GroupBotManager from utils.decorator.points_decorator import plugin_points_cost +from wechat_ipad import WechatAPIClient class VideoPlugin(MessagePluginInterface): @@ -40,12 +40,13 @@ class VideoPlugin(MessagePluginInterface): def __init__(self): super().__init__() + self.bot: WechatAPIClient = None # 修改为使用插件目录下的down_load_dir文件夹 self.download_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "down_load_dir") def initialize(self, context: Dict[str, Any]) -> bool: """初始化插件""" - self.LOG = logging.getLogger(f"Plugin.{self.name}") + self.LOG = logger self.LOG.info(f"正在初始化 {self.name} 插件...") # 保存上下文对象 @@ -56,7 +57,7 @@ class VideoPlugin(MessagePluginInterface): self._commands = self._config.get("Video", {}).get("command", ["黑丝视频", "黑丝", "来个黑丝", "搞个黑丝"]) self.command_format = self._config.get("Video", {}).get("command-format", "黑丝") self.enable = self._config.get("Video", {}).get("enable", True) - + # 确保下载目录存在 if not os.path.exists(self.download_dir): os.makedirs(self.download_dir, exist_ok=True) @@ -88,13 +89,14 @@ class VideoPlugin(MessagePluginInterface): @plugin_stats_decorator(plugin_name="视频插件") @plugin_points_cost(2, "视频插件消耗积分", Feature.VIDEO) - def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """处理消息""" content = str(message.get("content", "")).strip() self.LOG.info(f"插件执行: {self.name}:{content}") sender = message.get("sender") roomid = message.get("roomid", "") gbm: GroupBotManager = message.get("gbm") + self.bot: WechatAPIClient = message.get("bot") # 检查权限 if roomid and gbm.get_group_permission(roomid, Feature.VIDEO) == PermissionStatus.DISABLED: @@ -104,21 +106,21 @@ class VideoPlugin(MessagePluginInterface): # 下载视频 save_path = os.path.join(self.download_dir, "video.mp4") file_abspath = self._download_stream("https://api.guiguiya.com/api/hook/heisis", save_path) - + if not file_abspath or not file_abspath.endswith("mp4"): - self.message_util.send_text(f"\n❌视频下载失败,请稍后再试", - (roomid if roomid else sender), sender) + await self.bot.send_text_message((roomid if roomid else sender), f"\n❌视频下载失败,请稍后再试", + sender) return False, "视频下载失败" # 发送视频 - result = self.message_util.send_file(file_abspath, (roomid if roomid else sender)) + result = await self.bot.send_video_message((roomid if roomid else sender), file_abspath) self.LOG.info(f"发送视频结果: {result}") return True, "发送成功" except Exception as e: self.LOG.error(f"处理视频请求出错: {e}") - self.message_util.send_text(f"\n❌请求出错:{e}", - (roomid if roomid else sender), sender) + await self.bot.send_text_message((roomid if roomid else sender), f"\n❌请求出错:{e}", + sender) return False, f"处理出错: {e}" def _download_stream(self, url, save_path): @@ -157,4 +159,4 @@ class VideoPlugin(MessagePluginInterface): self.LOG.error(f"文件写入失败: {e}") except Exception as e: self.LOG.error(f"发生未知错误: {e}") - return None \ No newline at end of file + return None diff --git a/plugins/video_man/main.py b/plugins/video_man/main.py index f4ef08d..b87b871 100644 --- a/plugins/video_man/main.py +++ b/plugins/video_man/main.py @@ -1,4 +1,4 @@ -import logging +from loguru import logger import os import requests from typing import Dict, Any, List, Optional, Tuple @@ -45,7 +45,7 @@ class VideoManPlugin(MessagePluginInterface): def initialize(self, context: Dict[str, Any]) -> bool: """初始化插件""" - self.LOG = logging.getLogger(f"Plugin.{self.name}") + self.LOG = logger self.LOG.info(f"正在初始化 {self.name} 插件...") # 保存上下文对象 diff --git a/plugins/xiuren_image/main.py b/plugins/xiuren_image/main.py index a9cbe68..64dbcfe 100644 --- a/plugins/xiuren_image/main.py +++ b/plugins/xiuren_image/main.py @@ -1,4 +1,6 @@ -import logging +from pathlib import Path + +from loguru import logger import os import random from typing import Dict, Any, List, Optional, Tuple @@ -8,6 +10,7 @@ from plugin_common.plugin_interface import PluginStatus from utils.decorator.plugin_decorators import plugin_stats_decorator from utils.robot_cmd.robot_command import Feature, PermissionStatus, GroupBotManager from utils.decorator.points_decorator import plugin_points_cost +from wechat_ipad import WechatAPIClient class XiurenImagePlugin(MessagePluginInterface): @@ -39,11 +42,12 @@ class XiurenImagePlugin(MessagePluginInterface): def __init__(self): super().__init__() - self.image_folder = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "xiuren") + self.image_folder = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), + "xiuren") def initialize(self, context: Dict[str, Any]) -> bool: """初始化插件""" - self.LOG = logging.getLogger(f"Plugin.{self.name}") + self.LOG = logger self.LOG.info(f"正在初始化 {self.name} 插件...") # 保存上下文对象 @@ -86,13 +90,14 @@ class XiurenImagePlugin(MessagePluginInterface): @plugin_stats_decorator(plugin_name="秀人图片") @plugin_points_cost(2, "秀人图片消耗积分", Feature.PIC) - def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: """处理消息""" content = str(message.get("content", "")).strip() self.LOG.info(f"插件执行: {self.name}:{content}") sender = message.get("sender") roomid = message.get("roomid", "") gbm: GroupBotManager = message.get("gbm") + bot: WechatAPIClient = message.get("bot") # 检查权限 if roomid and gbm.get_group_permission(roomid, Feature.PIC) == PermissionStatus.DISABLED: @@ -102,12 +107,13 @@ class XiurenImagePlugin(MessagePluginInterface): # 获取随机图片 pic_path = self._get_random_pic() if not pic_path: - self.message_util.send_text(f"❌未找到图片资源", - (roomid if roomid else sender), sender) + await bot.send_text_message((roomid if roomid else sender), f"❌未找到图片资源", + sender) return False, "未找到图片资源" # 发送图片 - result = self.message_util.send_file(pic_path, (roomid if roomid else sender)) + + result = await bot.send_image_message((roomid if roomid else sender), Path(pic_path)) self.LOG.info(f"发送图片结果: {result}") return True, "发送成功" diff --git a/robot.py b/robot.py index f9f6160..4b79c69 100644 --- a/robot.py +++ b/robot.py @@ -1,39 +1,30 @@ # -*- coding: utf-8 -*- -import logging import re import time +import asyncio +import threading +import tomllib +import toml -import dacite +import wechat_ipad +from loguru import logger -from base.func_epic import is_friday, get_free - -from base.func_news import News from configuration import Config -from gewechat.call_back_message.message import WxMessage, MessageType -from gewechat.client import gewe_client -from gewechat.response.model.group.chatroom_info import ChatroomInfo -from gewechat.response.model.personal.profile import Profile -from utils.json_converter import json_to_object -from utils.wechat.message_to_db import MessageStorage +from job_mgmt import Job from plugin_common.event_system import EventType, EventSystem from plugin_common.message_plugin_interface import MessagePluginInterface from plugin_common.plugin_interface import PluginStatus from plugin_common.plugin_manager import PluginManager from plugin_common.plugin_registry import PluginRegistry -from utils.robot_cmd.robot_command import GroupBotManager -from job_mgmt import Job -from utils.robot_cmd.robot_command import Feature -from utils.robot_cmd.robot_command import PermissionStatus - -from sehuatang.shehuatang import pdf_file_path -from utils.wechat.contact_manager import ContactManager -from xiuren.meitu_dl import meitu_dowload_pub_pic -from xiuren.xiuren_pdf import generate_pdf_from_images +from utils.robot_cmd.robot_command import GroupBotManager, Feature, PermissionStatus from db.connection import DBConnectionManager from message_util import MessageUtil - from db.contacts_db import ContactsDBOperator +from utils.wechat.contact_manager import ContactManager +from utils.wechat.message_to_db import MessageStorage +from wechat_ipad import WechatAPIClient +from wechat_ipad.models.message import WxMessage, MessageType class Robot(Job): @@ -41,13 +32,20 @@ class Robot(Job): """ def __init__(self, config: Config) -> None: - self.client = gewe_client.client - if not self.client: - logging.getLogger("Robot").error("gewe_client.client 不存在,Robot 初始化失败,程序退出。") - return + super().__init__() self.config = config - self.app_id = gewe_client.app_id - self.LOG = logging.getLogger("Robot") + self.LOG = logger + + # wechat_ipad 相关属性 + self.ipad_bot: WechatAPIClient + self.ipad_config = None + self.ipad_running = False + self.ipad_thread = None + self.ipad_loop = None + self.wxid = None + self.nickname = None + self.alias = None + self.phone = None self.LOG.info(f"DB+REDIS 连接池开始初始化") # 使用单例模式获取实例 @@ -58,45 +56,30 @@ class Robot(Job): self.LOG.info(f"数据库连接管理器初始化完成") # 为了兼容现有代码,保留原有的连接池 - self.db_pool = self.db_manager .mysql_pool + self.db_pool = self.db_manager.mysql_pool self.redis_pool = self.db_manager.redis_pool self.contacts_db = ContactsDBOperator(self.db_manager) - # 初始化联系人管理器并设置联系人 + # 初始化联系人管理器 self.contact_manager = ContactManager.get_instance() - self.allContacts = self.get_all_contacts() - self.contact_manager.set_contacts(self.allContacts) + self.allContacts = {} # 将在登录后填充 - # 获取个人信息 - profile_dict = self.client.get_profile(self.app_id) - try: - profile: Profile = dacite.from_dict(Profile, profile_dict) - except Exception as e: - self.LOG.info(f"Profile dict 转换失败: {e}") - return - if profile.data.wxid is None: - self.LOG.info(f"获取个人信息失败,退出程序!") - return - self.wxid = profile.data.wxid - - # 初始化消息工具类 - 使用联系人管理器 - self.message_util = MessageUtil() self.groups = {} # 存储按group_id分组的消息列表,每个group_id最多保留10条消息 GroupBotManager.load_local_cache() # 权限模块加载 self.gbm = GroupBotManager() + # 初始化插件系统 self.LOG.info("开始初始化插件系统...") self.plugin_registry = PluginRegistry() self.event_system = EventSystem() self.plugin_modules = {} # 存储已加载的插件模块 self.plugins = {} # 存储已加载的插件实例 - + self.message_util = None # 设置插件系统上下文 self.system_context = { "config": config, - "client": gewe_client, "event_system": self.event_system, "plugin_registry": self.plugin_registry, "db_pool": self.db_pool, @@ -111,174 +94,366 @@ class Robot(Job): # 加载插件 self.LOG.info("插件系统初始化完成") - # 消息存档模块初始化,自动完成入库动作 - self.message_storage = MessageStorage(self.client) - - @staticmethod - def value_check(args: dict) -> bool: - if args: - return all(value is not None for key, value in args.items() if key != 'proxy') - return False - - def toChitchat(self, msg: WxMessage) -> bool: - """闲聊,接入 ChatGPT - """ - # 去除@的人和空格等字符 - q = re.sub(r"@.*?[\u2005|\s]", "", msg.content.raw_content).replace(" ", "") - - if q == "#今日百度新闻": - self.news_baidu_report((msg.roomid if msg.from_group() else msg.sender)) - return True - elif q in ["nbc", "cnn", "abc", "fox", "bbc"]: - self.news_en_report(q, (msg.roomid if msg.from_group() else msg.sender)) - return True - else: - # 如果是群消息,并且群没开启AI,则不处理该动作 - if msg.from_group() and self.gbm.get_group_permission(msg.roomid, - Feature.AI_CAPABILITY) == PermissionStatus.ENABLED: - resp = self.gbm.get_enabled_features(msg.roomid) - self.message_util.send_text(resp, (msg.roomid if msg.from_group() else msg.sender), msg.sender) - return True - else: - return True - - def processMsg(self, msg: WxMessage) -> None: - """当接收到消息的时候,会调用本方法。如果不实现本方法,则打印原始消息。 - 此处可进行自定义发送的内容,如通过 msg.content 关键字自动获取当前天气信息,并发送到对应的群组@发送者 - 群号:msg.roomid 微信ID:msg.sender 消息内容:msg.content - content = "xx天气信息为:" - receivers = msg.roomid - self.sendTextMsg(content, receivers, msg.sender) - """ + def init_wechat_ipad(self): + """初始化wechat_ipad客户端""" try: - # 检测群聊是否已加入机器人管理,如果没有则自动添加并开启机器人功能 - if msg.from_group() and msg.roomid not in GroupBotManager.local_cache["group_list"]: - self.LOG.info(f"检测到新群聊: {msg.roomid},自动添加到机器人管理列表并启用机器人功能") + # 读取config.toml文件 + with open("wechat_ipad/config.toml", "rb") as f: + self.ipad_config = tomllib.load(f) + + self.LOG.info("正在初始化wechat_ipad客户端...") + + # 检查必要的配置 + server_url = self.ipad_config.get("server_url", "") + if server_url == "": + self.LOG.error("server_url不能为空,wechat_ipad初始化失败") + return False + + server_ip = self.ipad_config.get("server_ip", "") + server_port = self.ipad_config.get("server_port", 8058) + + # 创建事件循环 + self.ipad_loop = asyncio.new_event_loop() + + # 在新线程中启动wechat_ipad客户端 + self.ipad_thread = threading.Thread( + target=self._run_wechat_ipad_client, + args=(server_ip, server_port), + daemon=True + ) + self.ipad_thread.start() + + self.LOG.info("wechat_ipad客户端初始化完成") + return True + except Exception as e: + self.LOG.error(f"初始化wechat_ipad客户端失败: {e}") + return False + + def _run_wechat_ipad_client(self, server_ip, server_port): + """在新线程中运行wechat_ipad客户端""" + asyncio.set_event_loop(self.ipad_loop) + self.ipad_loop.run_until_complete(self._wechat_ipad_core(server_ip, server_port)) + + async def _wechat_ipad_core(self, server_ip, server_port): + """wechat_ipad核心逻辑,基于bot-core.py""" + try: + self.LOG.info("启动wechat_ipad bot") + # 调用登录接口 + self.ipad_bot = wechat_ipad.WechatAPIClient(server_ip, server_port) + wxid = self.ipad_config.get("wxid", "") + device_name = self.ipad_config.get("device_name", "") + device_id = self.ipad_config.get("device_id", "") + + if device_name == "": + device_name = self.ipad_bot.create_device_name() + if device_id == "": + device_id = self.ipad_bot.create_device_id() + + # 登录逻辑 + if not await self.ipad_bot.is_logged_in(wxid): + await self._handle_ipad_login(wxid, device_name, device_id) + else: # 已登录 + self.ipad_bot.wxid = wxid + profile = await self.ipad_bot.get_profile() + + self.ipad_bot.nickname = profile.get("NickName").get("string") + self.ipad_bot.alias = profile.get("Alias") + self.ipad_bot.phone = profile.get("BindMobile").get("string") + + # 更新Robot类的属性 + self.wxid = self.ipad_bot.wxid + self.nickname = self.ipad_bot.nickname + self.alias = self.ipad_bot.alias + self.phone = self.ipad_bot.phone + + self.LOG.info( + f"wechat_ipad登录账号信息: wxid: {self.wxid} 昵称: {self.nickname} 微信号: {self.alias} 手机号: {self.phone}") + + self.LOG.info(f"wechat_ipad登录设备信息: device_name: {device_name} device_id: {device_id}") + self.LOG.info("wechat_ipad登录成功") + + # 登录成功后加载联系人信息 + self.allContacts = self.get_all_contacts() + self.contact_manager.set_contacts(self.allContacts) + + # 开启自动心跳(作为后台任务) + heartbeat_task = asyncio.create_task(self._heartbeat_task()) + self.message_storage = MessageStorage(self.ipad_bot) + + # 初始化消息工具类 - 使用联系人管理器 + self.message_util = MessageUtil(self.ipad_bot) + # 先接受堆积消息 + self.LOG.info("处理堆积消息中") + count = 0 + while True: + data = await self.ipad_bot.sync_message() + data = data.get("AddMsgs") + if not data: + if count > 2: + break + else: + count += 1 + continue + + self.LOG.debug(f"接受到 {len(data)} 条消息") + await asyncio.sleep(1) + self.LOG.info("处理堆积消息完毕") + + # 标记为运行中 + self.ipad_running = True + + # 开始处理消息 + self.LOG.info("开始处理wechat_ipad消息") + while self.ipad_running: + try: + data = await self.ipad_bot.sync_message() + except Exception as e: + self.LOG.warning(f"获取新消息失败 {e}") + await asyncio.sleep(5) + continue + + data = data.get("AddMsgs") + if data: + for message in data: + # 处理消息 + wxmsg: WxMessage = WxMessage.from_json(message) + await self._process_ipad_message(wxmsg) + + # 使用异步睡眠替代忙等待循环 + await asyncio.sleep(0.5) + + except Exception as e: + self.LOG.error(f"wechat_ipad客户端运行出错: {e}") + self.ipad_running = False + + async def _handle_ipad_login(self, wxid, device_name, device_id): + """处理wechat_ipad登录""" + while not await self.ipad_bot.is_logged_in(wxid): + # 需要登录 + try: + if await self.ipad_bot.get_cached_info(wxid): + # 尝试唤醒登录 + uuid = await self.ipad_bot.awaken_login(wxid) + self.LOG.info(f"获取到登录uuid: {uuid}") + else: + # 二维码登录 + if not device_name: + device_name = self.ipad_bot.create_device_name() + if not device_id: + device_id = self.ipad_bot.create_device_id() + uuid, url = await self.ipad_bot.get_qr_code(device_id=device_id, device_name=device_name, + print_qr=True) + self.LOG.info(f"获取到登录uuid: {uuid}") + self.LOG.info(f"获取到登录二维码: {url}") + except Exception as e: + self.LOG.error(f"登录过程出错: {e}") + # 二维码登录 + if not device_name: + device_name = self.ipad_bot.create_device_name() + if not device_id: + device_id = self.ipad_bot.create_device_id() + uuid, url = await self.ipad_bot.get_qr_code(device_id=device_id, device_name=device_name, print_qr=True) + self.LOG.info(f"获取到登录uuid: {uuid}") + self.LOG.info(f"获取到登录二维码: {url}") + + while True: + self.LOG.info(f"uuid: {uuid}, url: {url}") + stat, data = await self.ipad_bot.check_login_uuid(uuid, device_id=device_id) + if stat: + break + self.LOG.info(f"等待登录中,过期倒计时:{data}") + await asyncio.sleep(5) + + # 保存登录信息 + self.ipad_config["wxid"] = self.ipad_bot.wxid + self.ipad_config["device_name"] = device_name + self.ipad_config["device_id"] = device_id + with open("wechat_ipad/config.toml", "w", encoding="utf-8") as f: + toml.dump(self.ipad_config, f) + + # 获取登录账号信息 + self.ipad_bot.wxid = data.get("acctSectResp").get("userName") + self.ipad_bot.nickname = data.get("acctSectResp").get("nickName") + self.ipad_bot.alias = data.get("acctSectResp").get("alias") + self.ipad_bot.phone = data.get("acctSectResp").get("bindMobile") + + # 更新Robot类的属性 + self.wxid = self.ipad_bot.wxid + self.nickname = self.ipad_bot.nickname + self.alias = self.ipad_bot.alias + self.phone = self.ipad_bot.phone + + self.LOG.info( + f"wechat_ipad登录账号信息: wxid: {self.wxid} 昵称: {self.nickname} 微信号: {self.alias} 手机号: {self.phone}") + break + + async def _heartbeat_task(self): + """wechat_ipad心跳任务""" + self.LOG.info("开启wechat_ipad心跳!") + while self.ipad_running: + try: + success = await self.ipad_bot.heartbeat() + if success: + self.LOG.success("心跳进行中") + else: + self.LOG.warning("心跳失败") + except Exception as e: + self.LOG.error(f"wechat_ipad heartbeat: {e}") + await asyncio.sleep(5) + + async def _process_ipad_message(self, message: WxMessage): + """处理wechat_ipad消息""" + try: + self.LOG.debug(f"message: {message}") + # 消息已经是WxMessage对象,直接使用其属性和方法 + from_user = message.sender + to_user = message.to_user + content = message.content + msg_type = message.msg_type + + # 判断是否为群消息 + is_group = message.from_group() + group_id = message.roomid + + # 检测群聊是否已加入机器人管理 + if is_group and group_id not in GroupBotManager.local_cache["group_list"]: + self.LOG.info(f"检测到新群聊: {group_id},自动添加到机器人管理列表并启用机器人功能") # 添加群组到列表 - GroupBotManager.local_cache["group_list"].add(msg.roomid) + GroupBotManager.local_cache["group_list"].add(group_id) # 保存到Redis redis_conn = self.db_manager.get_redis_connection() - redis_conn.sadd("group:list", msg.roomid) + redis_conn.sadd("group:list", group_id) # 设置ROBOT功能为启用状态 - GroupBotManager.set_group_permission(msg.roomid, Feature.ROBOT, PermissionStatus.ENABLED) - # 更新联系人信息 - # 群第一次加入机器人管理,自动添加并开启机器人功能,需要进行群成员信息初始化。请完成写入数据库,并更新联系人信息 + GroupBotManager.set_group_permission(group_id, Feature.ROBOT, PermissionStatus.ENABLED) + + # 获取群成员信息并更新数据库 try: - chatroom_info = self.client.get_chatroom_info(self.app_id, msg.roomid) - self.LOG.info(f"chatroom_info: {chatroom_info}") - self.contacts_db.save_chatroom_info(chatroom_info.get('data', {})) - self.LOG.info(f"添加新的群信息到数据库成功:{chatroom_info}") - # 添加 memberList 到群组信息表中 - member_list = chatroom_info.get('data', {}).get('memberList', []) - self.contacts_db.save_chatroom_member_simple(msg.roomid, member_list) - for info in member_list: - wxid = info.get("wxid", "") - self.LOG.info(f"已添加新用户信息到数据库: {wxid}") - # 更新缓存 - self.allContacts[wxid] = info.get("nickName", "nickName") - self.LOG.info(f"已维护新用户信息到缓存: {wxid}") - self.contact_manager.set_contacts(self.allContacts) + chatroom_info = await self.ipad_bot.get_chatroom_info(group_id) + if chatroom_info: + # 保存群信息到数据库 + self.contacts_db.save_chatroom_info(chatroom_info) + + # 保存群成员信息 + if "NewChatroomData" in chatroom_info and "ChatRoomMember" in chatroom_info["NewChatroomData"]: + member_list = chatroom_info["NewChatroomData"]["ChatRoomMember"] + self.contacts_db.save_chatroom_member_simple(group_id, member_list) + + # 更新联系人缓存 + for member in member_list: + wxid = "" + if isinstance(member.get("UserName"), dict): + wxid = member["UserName"].get("string", "") + else: + wxid = member.get("UserName", "") + + nick_name = "" + if isinstance(member.get("NickName"), dict): + nick_name = member["NickName"].get("string", "") + else: + nick_name = member.get("NickName", "") + + if wxid: + self.allContacts[wxid] = nick_name + + self.contact_manager.set_contacts(self.allContacts) + self.LOG.info(f"已更新群 {group_id} 的成员信息") except Exception as e: - self.LOG.error(f"chatroom_info save error: {e}") - return + self.LOG.error(f"获取群成员信息失败: {e}") + + # 发布消息接收事件 + self.event_system.publish(EventType.MESSAGE_RECEIVED, {"message": message}) + + # 尝试使用插件处理消息 + plugin_processed = await self.process_plugin_message(message) + self.LOG.debug(f"plugin_processed: {plugin_processed}") + # 处理群聊命令或私聊命令 + if from_user == self.wxid: # 自己发送的消息 + if is_group: + rsp = self.gbm.handle_command(group_id, content) + if rsp is not None: + await self.send_text(rsp, group_id) + else: + # 处理特殊命令 + if content == "^更新$": + self.config.reload() + self.gbm.load_local_cache() + await self.send_text("已更新", "filehelper") + + if is_group: + self.LOG.debug(f"入库和记录群消息: {message}") + # 调用统计逻辑进行聊天数据统计: + try: + self.message_storage.process_message(message) + except Exception as e: + self.LOG.error(f"process_message error: {e}") + + # # 聊天记录入库动作: + try: + self.message_storage.archive_message(message) + # 单独处理图片消息 后续写定时任务自动完成下载。延时处理。 + # if message.msg_type == MessageType.IMAGE: # 图片消息类型 + # self.message_storage.process_image(message) + except Exception as e: + self.LOG.error(f"archive_message error: {e}") except Exception as e: - self.LOG.error(f"加入新群,自动添加并开启机器人功能 error: {e}") + self.LOG.error(f"处理wechat_ipad消息出错: {e}") + + def _convert_to_wx_message(self, message): + """将wechat_ipad消息转换为WxMessage对象""" + from wechat_ipad.models.message import WxMessage + return WxMessage.from_json(message) + + async def send_text(self, content, to_user, at_user=None): + """发送文本消息""" + if not self.ipad_bot or not self.ipad_running: + self.LOG.error("wechat_ipad客户端未初始化或未运行") + return False - # 如果用户信息缓存里面没有这个用户昵称,则添加用户信息,并且维护该用户信息 - # 以 wxid 作为唯一标识 try: - if msg.from_group(): - wxid = msg.sender - if wxid and wxid not in self.allContacts: - # 添加到数据库 - # 这里假设 contacts_db 有 save_contact_info 方法,参数为 dict - resp = self.client.get_chatroom_member_detail(self.app_id, msg.roomid, [wxid]) - infos = resp.get('data', {}) - for info in infos: - self.LOG.info(f"已添加新用户信息到数据库: {wxid}") - # 更新缓存 - self.allContacts[wxid] = info.get("nickName", "nickName") - self.contact_manager.set_contacts(self.allContacts) - self.LOG.info(f"已维护新用户信息到缓存: {wxid}") - self.contacts_db.save_chatroom_member_detail(msg.roomid, infos) + if at_user and to_user.endswith("@chatroom"): + # 在群里@某人 + await self.ipad_bot.send_text_message(to_user, content, at_list=[at_user]) + else: + # 普通发送 + await self.ipad_bot.send_text_message(to_user, content) + return True except Exception as e: - self.LOG.error(f"添加新用户信息到数据库失败: {e}") - # - # # 发布消息接收事件 - # self.event_system.publish(EventType.MESSAGE_RECEIVED, {"message": msg}) - # - # # 标记插件是否处理了消息 - # plugin_processed = False - # - # # 尝试使用插件处理消息 - # if self.process_plugin_message(msg): - # plugin_processed = True - # - # # 群聊消息处理 - 无论插件是否处理过,都执行数据存储 - if msg.from_group(): - # 调用统计逻辑进行聊天数据统计: - try: - self.message_storage.process_message(msg) - except Exception as e: - self.LOG.error(f"process_message error: {e}") + self.LOG.error(f"发送文本消息失败: {e}") + return False - # # 聊天记录入库动作: - try: - self.message_storage.archive_message(msg) - # 单独处理图片消息 后续写定时任务自动完成下载。延时处理。 - if msg.msg_type == MessageType.IMAGE: # 图片消息类型 - self.message_storage.process_image(msg) - except Exception as e: - self.LOG.error(f"archive_message error: {e}") + async def send_image(self, image_path, to_user): + """发送图片消息""" + if not self.ipad_bot or not self.ipad_running: + self.LOG.error("wechat_ipad客户端未初始化或未运行") + return False - # # 如果插件已处理消息,则不再执行后续的业务逻辑 - # if plugin_processed: - # return - # - # # 记录在群里发的最新消息,可以通过撤回指令撤回 - # try: - # if msg.from_self(): - # rsp = self.gbm.handle_command(msg.roomid, msg.content) - # # 不在群里发送,防止被骚扰 - # if rsp is not None: - # self.message_util.send_text(rsp, msg.roomid, msg.sender) - # return - # except Exception as e: - # self.LOG.error(f"revoke_receive_message error: {e}") - # - # return # 处理完群聊信息,后面就不需要处理了 - # - # # 如果插件已处理消息,则不再执行后续的业务逻辑 - # if plugin_processed: - # return - # - # elif msg.msg_type == MessageType.TEXT: # 文本消息 - # # 让配置加载更灵活,自己可以更新配置。也可以利用定时任务更新。 - # if msg.from_self(): - # if msg.content.clean_content == "^更新$": - # self.config.reload() - # self.gbm.load_local_cache() - # self.LOG.info("已更新") - # if msg.content.clean_content == "今日百度新闻": - # self.news_baidu_report() - # if msg.content.clean_content == "TO_DB": - # self.message_count_to_db() - # if msg.content.clean_content == "PDF": - # self.generate_sehuatang_pdf() - # if msg.content.raw_content.startswith("清除群-"): - # self.gbm.handle_command(msg.roomid, msg.content.clean_content) - # else: - # self.toChitchat(msg) # 闲聊 - - def onMsg(self, msg: WxMessage) -> int: try: - self.LOG.info(msg) # 打印信息 - self.processMsg(msg) + await self.ipad_bot.send_image_message(to_user, image_path) + return True except Exception as e: - self.LOG.error(e) + self.LOG.error(f"发送图片消息失败: {e}") + return False - return 0 + async def send_file(self, file_path, to_user): + """发送文件消息""" + if not self.ipad_bot or not self.ipad_running: + self.LOG.error("wechat_ipad客户端未初始化或未运行") + return False + + try: + await self.ipad_bot.send_file(to_user, file_path) + return True + except Exception as e: + self.LOG.error(f"发送文件消息失败: {e}") + return False + + def stop_wechat_ipad(self): + """停止wechat_ipad客户端""" + self.ipad_running = False + if self.ipad_loop: + self.ipad_loop.stop() + self.LOG.info("wechat_ipad客户端已停止") def keep_running_and_block_process(self) -> None: """ @@ -295,32 +470,36 @@ class Robot(Job): self.contact_manager.refresh_contacts(self.allContacts) self.LOG.info("联系人信息已刷新") - def send_group_txt_message(self, msg: str, feature: Feature): + async def send_group_txt_message(self, msg: str, feature: Feature): + """向所有启用了特定功能的群发送文本消息""" try: receivers = self.gbm.get_group_list() if not receivers: return for r in receivers: if self.gbm.get_group_permission(r, feature) == PermissionStatus.ENABLED: - self.message_util.send_text(msg, r) + await self.send_text(msg, r) except Exception as e: self.LOG.error(f"send_group_txt_message:{feature.description} error:{e}") - def send_group_file_message(self, path: str, feature: Feature): + async def send_group_file_message(self, path: str, feature: Feature): + """向所有启用了特定功能的群发送文件消息""" try: receivers = self.gbm.get_group_list() if not receivers: return for r in receivers: if self.gbm.get_group_permission(r, feature) == PermissionStatus.ENABLED: - self.message_util.send_file(path, r) + await self.send_file(path, r) except Exception as e: self.LOG.error(f"send_group_file_message:{feature.description} error:{e}") - def process_plugin_message(self, msg: WxMessage) -> bool: + async def process_plugin_message(self, msg) -> bool: """使用插件处理消息""" # 获取所有消息处理插件 message_plugins = self.plugin_registry.get_plugins_by_type(MessagePluginInterface) + if not message_plugins: + return False # 依次尝试处理消息 for plugin in message_plugins: @@ -328,267 +507,41 @@ class Robot(Job): continue try: - # 转换WxMessage为插件可处理的格式 + # 转换消息为插件可处理的格式 plugin_msg = { "type": msg.msg_type, "content": msg.content.clean_content, "sender": msg.sender, "roomid": msg.roomid if msg.from_group() else "", - "xml": msg.content.xml_content, - "is_at": msg.is_at(self.wxid), # 确保正确设置is_at标志 + "is_at": msg.is_at(self.wxid), "timestamp": time.time(), - "message_util": self.message_util, # 提供消息工具类 - "gbm": self.gbm, # 每次从程序变量中取,保证最新 "all_contacts": self.allContacts, - "full_wx_msg": msg + "full_wx_msg": msg, + "gbm": self.gbm, + "bot": self.ipad_bot } # 检查插件是否可以处理该消息 if plugin.can_process(plugin_msg): - processed, _ = plugin.process_message(plugin_msg) + processed, _ = await plugin.process_message(plugin_msg) if processed: # 发布消息处理事件 self.event_system.publish(EventType.MESSAGE_PROCESSED, { "message": msg, "plugin": plugin.name }) - return True except Exception as e: self.LOG.error(f"插件 {plugin.name} 处理消息失败: {e}") return False - # ============================================== 业务内容========================================================== - def news_baidu_report_auto(self) -> None: - try: - news = News().get_baidu_news() - self.send_group_txt_message(news, Feature.DAILY_NEWS) - except Exception as e: - self.LOG.error(f"newsBaiduReportAuto error:{e}") - - def news_baidu_report(self, sender: str = None) -> None: - try: - news = News().get_baidu_news() - if news and isinstance(news, str): - self.message_util.send_text(news, sender) - else: - self.LOG.error("获取百度新闻返回值异常") - except Exception as e: - self.LOG.error(f"newsBaiduReport error:{e}") - # 发送错误信息给用户,让用户知道发生了什么 - - def news_en_report(self, website, sender: str = None) -> None: - try: - news = News().get_eng_news(website) - self.message_util.send_text(news, sender) - except Exception as e: - self.LOG.error(f"newsEnReport error:{e}") - - # 使用装饰器标记定时任务 星期五 10:30 执行 - def send_epic_free_games(self): - try: - if is_friday(): - games = get_free() - self.send_group_txt_message(games, Feature.EPIC) - except Exception as e: - self.LOG.error(f"sendEpicFreeGames error:{e}") - - # 使用装饰器标记定时任务 - def message_count_to_db(self): - try: - self.message_storage.write_to_db() - except Exception as e: - self.LOG.error(f"write_to_db error:{e}") - - def generate_sehuatang_pdf(self): - try: - self.LOG.info("开始生成PDF,generate_sehuatang_pdf") - path = pdf_file_path() - # 暂时只发4K群 - self.send_group_file_message(path, Feature.PDF_CAPABILITY) - except Exception as e: - self.LOG.error(f"generateSehuatangPdf error:{e}") - - def generate_and_send_ranking(self): - try: - receivers = self.gbm.get_group_list() - if not receivers: - return - for r in receivers: - if self.gbm.get_group_permission(r, Feature.DAILY_SUMMARY) == PermissionStatus.ENABLED: - output = self.message_storage.generate_and_send_ranking(r, self.allContacts) - self.message_util.send_text(output, r) - except Exception as e: - self.LOG.error(f"SendRanking error:{e}") - - # - # # 设置定时任务 - # def game_auto_tasks(self): - # try: - # group_ids = get_group_ids() - # for gid in group_ids: - # if self.gbm.get_group_permission(gid, Feature.TASK_GAME) == PermissionStatus.ENABLED: - # rep = run_random_task_assignment(group_id=gid) - # message = rep["message"] - # player_id = rep["player_id"] - # print(f"消息: {message}") - # print(f"玩家ID: {player_id}") - # self.send_text_msg(message, gid, player_id) - # except Exception as e: - # self.LOG.error(f"message_summary_robot error:{e}") - - def xiu_ren_download_task(self): - try: - # 每天下载10组图,然后发一个帖子PDF - meitu_dowload_pub_pic() - except Exception as e: - self.LOG.error(f"xiu_ren_download_task error:{e}") - - def xiu_ren_pdf_send(self): - try: - pub_path = generate_pdf_from_images("xiuren") - self.message_util.send_file(pub_path, "45317011307@chatroom") - except Exception as e: - self.LOG.error(f"xiu_ren_pdf_send error:{e}") - - # 本逻辑主要解决加载联系人信息的问题,只从数据库里面提取,不完成下载行为。 def get_all_contacts(self) -> dict: """获取所有联系人信息并返回字典格式 {wxid: nickname}""" - # 从数据库提取信息,如果数据库没内容,则完成第一次初始化。 try: - # 先尝试从数据库获取联系人信息 - contacts_dict = self.contacts_db.get_all_contacts() - # 获取群成员列表 - return contacts_dict - + # 从数据库获取联系人信息 + contacts = self.contacts_db.get_all_contacts() + return contacts except Exception as e: self.LOG.error(f"获取联系人信息失败: {e}") return {} - - def sync_all_contacts(self): - """同步所有联系人信息""" - try: - # 数据库中没有联系人信息,需要初始化 - self.LOG.info("数据库中没有联系人信息,开始初始化...") - - contacts_dict = {} - # 获取所有联系人列表 - response = self.client.fetch_contacts_list(self.app_id) - self.LOG.info(f"获取联系人列表响应: {response}") - - if not response or response.get("ret") != 200: - self.LOG.warning(f"获取联系人列表失败: {response}") - return contacts_dict - - # 从响应中提取联系人数据 - contact_data = response.get("data", {}) - - # 处理好友列表 - friends = contact_data.get("friends", []) - for wxid in friends: - contacts_dict[wxid] = wxid # 默认使用wxid作为昵称 - - # 处理群聊列表 - chatrooms = contact_data.get("chatrooms", []) - for chatroom_id in chatrooms: - contacts_dict[chatroom_id] = chatroom_id - # 如果是群聊,则获取群成员信息 - self.update_chatroom_member_details(chatroom_id) - - # 处理公众号列表 - ghs = contact_data.get("ghs", []) - for gh_id in ghs: - contacts_dict[gh_id] = gh_id - - # 获取联系人详细信息(昵称等) - self.update_contact_details(contacts_dict) - - self.LOG.info(f"成功获取并保存{len(contacts_dict)}个联系人信息") - return contacts_dict - - except Exception as e: - self.LOG.error(f"获取联系人信息失败: {e}") - return {} - - def update_contact_details(self, contacts_dict): - """更新联系人详细信息(昵称等)""" - try: - # 将wxid列表分批处理,每批50个 - batch_size = 10 - wxids = list(contacts_dict.keys()) - - for i in range(0, len(wxids), batch_size): - batch_wxids = wxids[i:i + batch_size] - - # 批量获取联系人详细信息 - contact_info = self.client.get_detail_info(self.app_id, batch_wxids) - self.LOG.info(f"获取联系人详细信息响应: {contact_info}") - # 处理返回的数据 - if contact_info and contact_info.get("ret") == 200 and "data" in contact_info: - contact_data = contact_info.get("data", []) - - if contact_data: - for contact in contact_data: - user_name = contact.get("userName") - if not user_name or user_name not in contacts_dict: - continue - - # 更新昵称 - contacts_dict[user_name] = contact.get("nickName") or user_name - - try: - # 判断联系人类型 - contact_type = "friends" # 默认为好友类型 - if user_name.endswith("@chatroom"): - contact_type = "chatrooms" - elif user_name.startswith("gh_"): - contact_type = "ghs" - - # 保存到数据库 - self.contacts_db.save_contacts([contact], contact_type) - - except Exception as e: - self.LOG.error(f"处理联系人 {user_name} 失败: {e}") - continue - else: - self.LOG.error(f"获取联系人详情失败: {contact_info}") - - except Exception as e: - self.LOG.error(f"更新联系人详细信息失败: {e}") - - def update_chatroom_member_details(self, chatroom_id): - """更新群成员详细信息""" - try: - # 首先获取群成员列表 - members_response = self.client.get_chatroom_member_list(self.app_id, chatroom_id) - if members_response and members_response.get('ret') == 200: - member_list = members_response.get('data', {}).get('memberList', []) - - # 提取成员wxid列表 - member_wxids = [member.get('wxid') for member in member_list if member.get('wxid')] - - if member_wxids: - # 按照官方接口格式传递参数 - details_response = self.client.get_chatroom_member_detail( - self.app_id, - chatroom_id, - member_wxids # 直接传递列表,不需要转换为集合 - ) - - success = self.contacts_db.process_chatroom_member_detail_response(chatroom_id, details_response) - - if success: - self.LOG.info(f"成功更新群聊{chatroom_id}的成员详细信息") - else: - self.LOG.error(f"更新群聊{chatroom_id}的成员详细信息失败") - - return success - else: - self.LOG.warning(f"群聊{chatroom_id}没有成员") - return False - else: - self.LOG.error(f"获取群聊{chatroom_id}成员列表失败") - return False - except Exception as e: - self.LOG.error(f"更新群聊成员详细信息出错: {e}") diff --git a/utils/decorator/plugin_decorators.py b/utils/decorator/plugin_decorators.py index 4dc491b..5ef6a84 100644 --- a/utils/decorator/plugin_decorators.py +++ b/utils/decorator/plugin_decorators.py @@ -1,7 +1,8 @@ import functools import time import traceback -import logging +import asyncio +from loguru import logger from datetime import datetime from typing import Callable, Dict, Any, Tuple @@ -19,14 +20,13 @@ def plugin_stats_decorator(plugin_name: str) -> Callable: 装饰器函数 """ # 获取日志记录器 - logger = logging.getLogger(f"StatsCollector.{plugin_name}") logger.debug(f"为插件 '{plugin_name}' 应用统计装饰器") def decorator(func: Callable) -> Callable: logger.debug(f"装饰 '{plugin_name}' 的 {func.__name__} 方法") @functools.wraps(func) - def wrapper(self, message: Dict[str, Any]) -> Tuple[bool, str]: + async def async_wrapper(self, message: Dict[str, Any]) -> Tuple[bool, str]: # 获取数据库连接 try: logger.debug(f"[{plugin_name}] 开始处理消息") @@ -48,7 +48,122 @@ def plugin_stats_decorator(plugin_name: str) -> Callable: logger.debug(f"[{plugin_name}] 开始执行时间: {datetime.fromtimestamp(start_time).strftime('%Y-%m-%d %H:%M:%S.%f')}") try: - # 调用原始方法 + # 调用原始异步方法 + logger.debug(f"[{plugin_name}] 调用原始方法 {func.__name__}") + success, response = await func(self, message) + + # 计算执行时间(毫秒) + end_time = time.time() + process_time_ms = (end_time - start_time) * 1000 + logger.debug(f"[{plugin_name}] 执行完成,耗时: {process_time_ms:.2f}ms, 结果: {success}, 响应: {response}") + + # 记录插件调用 + logger.debug(f"[{plugin_name}] 记录插件调用统计") + stats_db.record_plugin_call( + plugin_name=plugin_name, + command=command, + user_id=sender, + group_id=roomid, + success=success, + process_time_ms=process_time_ms + ) + logger.info(f"[{plugin_name}] 成功记录插件调用: {command}, 耗时: {process_time_ms:.2f}ms") + + # 定义不需要记录错误的正常业务状态 + normal_responses = { + "没有权限", + "命令格式错误", + "请先开启功能", + # 可以添加其他正常的业务状态返回 + } + + # 新增:如果业务代码返回失败,且不属于正常业务状态,则记录错误信息 + if not success and response and response not in normal_responses: + logger.debug(f"[{plugin_name}] 业务代码返回失败,记录错误信息: {response}") + try: + stats_db.record_error( + plugin_name=plugin_name, + command=command, + user_id=sender, + group_id=roomid, + error_message=f"业务返回失败: {response}", + stack_trace="业务代码捕获的错误,无堆栈信息" + ) + logger.info(f"[{plugin_name}] 成功记录业务失败信息: {response}") + except Exception as err_record_error: + logger.error(f"[{plugin_name}] 记录业务失败信息出错: {err_record_error}") + + return success, response + except Exception as e: + # 计算执行时间(毫秒) + end_time = time.time() + process_time_ms = (end_time - start_time) * 1000 + + # 记录错误 + error_message = str(e) + stack_trace = traceback.format_exc() + logger.error(f"[{plugin_name}] 执行出错: {error_message}") + logger.debug(f"[{plugin_name}] 错误堆栈: {stack_trace}") + + try: + # 记录插件调用(失败) + logger.debug(f"[{plugin_name}] 记录插件调用失败统计") + stats_db.record_plugin_call( + plugin_name=plugin_name, + command=command, # 使用提取的指令而不是完整内容 + user_id=sender, + group_id=roomid, + success=False, + process_time_ms=process_time_ms + ) + + # 记录错误详情 + logger.debug(f"[{plugin_name}] 记录错误详情") + stats_db.record_error( + plugin_name=plugin_name, + command=command, # 使用提取的指令而不是完整内容 + user_id=sender, + group_id=roomid, + error_message=error_message[:500] if error_message else "未知错误", # 限制长度并确保不为空 + stack_trace=stack_trace[:2000] if stack_trace else "无堆栈信息" # 限制长度并确保不为空 + ) + logger.info(f"[{plugin_name}] 成功记录插件错误: {command}, 错误: {error_message}") + except Exception as db_error: + logger.error(f"[{plugin_name}] 记录插件统计数据失败: {db_error}") + logger.error(traceback.format_exc()) + + # 重新抛出异常,让上层处理 + raise + except Exception as outer_error: + logger.error(f"[{plugin_name}] 装饰器外层错误: {outer_error}") + logger.error(traceback.format_exc()) + # 确保原始函数仍然被调用,即使装饰器出错 + return await func(self, message) + + @functools.wraps(func) + def sync_wrapper(self, message: Dict[str, Any]) -> Tuple[bool, str]: + # 获取数据库连接 + try: + logger.debug(f"[{plugin_name}] 开始处理消息") + db_manager = DBConnectionManager.get_instance() + stats_db = StatsDBOperator(db_manager) + + # 提取消息信息 + content = message.get("content", "") + sender = message.get("sender", "") + roomid = message.get("roomid", "") + + # 提取指令部分(假设指令是第一个单词或空格前的部分) + command = content.strip().split(' ')[0] if content else "" + + logger.debug(f"[{plugin_name}] 消息内容: '{content}', 指令: '{command}', 发送者: {sender}, 群ID: {roomid}") + + # 记录开始时间 + start_time = time.time() + logger.debug(f"[{plugin_name}] 开始执行时间: {datetime.fromtimestamp(start_time).strftime('%Y-%m-%d %H:%M:%S.%f')}") + + try: + # 调用原始同步方法 logger.debug(f"[{plugin_name}] 调用原始方法 {func.__name__}") success, response = func(self, message) @@ -140,6 +255,10 @@ def plugin_stats_decorator(plugin_name: str) -> Callable: # 确保原始函数仍然被调用,即使装饰器出错 return func(self, message) - return wrapper + # 根据原始函数是否为异步函数返回相应的包装器 + if asyncio.iscoroutinefunction(func): + return async_wrapper + else: + return sync_wrapper return decorator \ No newline at end of file diff --git a/utils/decorator/points_decorator.py b/utils/decorator/points_decorator.py index 2c8d731..7392627 100644 --- a/utils/decorator/points_decorator.py +++ b/utils/decorator/points_decorator.py @@ -1,7 +1,8 @@ import functools import time import traceback -import logging +import asyncio +from loguru import logger from typing import Callable, Dict, Any, Tuple, Union from db.connection import DBConnectionManager @@ -25,7 +26,7 @@ def points_reward_decorator(points_calculator: Union[int, Callable], source_type def decorator(func: Callable) -> Callable: @functools.wraps(func) - def wrapper(self, message: Dict[str, Any]) -> Tuple[bool, str]: + async def async_wrapper(self, message: Dict[str, Any]) -> Tuple[bool, str]: # 检查权限 roomid = message.get("roomid", "") @@ -33,7 +34,74 @@ def points_reward_decorator(points_calculator: Union[int, Callable], source_type if GroupBotManager.get_group_permission(roomid, feature) == PermissionStatus.DISABLED: return False, "没有权限" - # 调用原始方法 + # 调用原始异步方法 + success, response = await func(self, message) + + # 如果原始方法执行成功,奖励积分 + if success: + try: + # 获取消息信息 + sender = message.get("sender", "") + roomid = message.get("roomid", "") + + if sender and (roomid or sender): + # 计算奖励积分数量 + if callable(points_calculator): + # 如果是函数,调用函数计算积分 + points = points_calculator(self, message, success, response) + if not points or points <= 0: + # 如果计算结果为0或负数,不奖励积分 + return success, response + else: + # 如果是固定值,直接使用 + points = points_calculator + + # 获取积分来源类型 + source = PointSource.CHECKIN + if source_type.lower() == "game": + source = PointSource.GAME + elif source_type.lower() != "checkin": + source = PointSource.OTHER + + # 奖励积分 + db_manager = DBConnectionManager.get_instance() + points_db = PointsDBOperator(db_manager) + + # 如果description是函数,调用函数获取描述 + desc = description + if callable(description): + desc = description(self, message, success, response, points) + + reward_success, reward_result = points_db.add_points( + sender, roomid, points, source, + desc or f"使用 {self.name if hasattr(self, 'name') else '功能'} 获得奖励" + ) + + logger.info(f"PointsReward.{self.name if hasattr(self, 'name') else 'Unknown'}") + if reward_success: + logger.info(f"用户 {sender} 获得 {points} 积分奖励") + + # 如果响应中没有提到积分,添加积分信息 + if "积分" not in response: + response += f"\n\n🎁 恭喜获得 {points} 积分奖励!" + else: + logger.warning(f"用户 {sender} 积分奖励失败: {reward_result}") + except Exception as e: + logger.error(f"奖励积分失败: {e}") + logger.error(traceback.format_exc()) + + return success, response + + @functools.wraps(func) + def sync_wrapper(self, message: Dict[str, Any]) -> Tuple[bool, str]: + # 检查权限 + roomid = message.get("roomid", "") + + if feature and roomid: + if GroupBotManager.get_group_permission(roomid, feature) == PermissionStatus.DISABLED: + return False, "没有权限" + + # 调用原始同步方法 success, response = func(self, message) # 如果原始方法执行成功,奖励积分 @@ -76,7 +144,7 @@ def points_reward_decorator(points_calculator: Union[int, Callable], source_type desc or f"使用 {self.name if hasattr(self, 'name') else '功能'} 获得奖励" ) - logger = logging.getLogger(f"PointsReward.{self.name if hasattr(self, 'name') else 'Unknown'}") + logger.info(f"PointsReward.{self.name if hasattr(self, 'name') else 'Unknown'}") if reward_success: logger.info(f"用户 {sender} 获得 {points} 积分奖励") @@ -86,13 +154,16 @@ def points_reward_decorator(points_calculator: Union[int, Callable], source_type else: logger.warning(f"用户 {sender} 积分奖励失败: {reward_result}") except Exception as e: - logger = logging.getLogger("PointsReward") logger.error(f"奖励积分失败: {e}") logger.error(traceback.format_exc()) return success, response - return wrapper + # 根据原始函数是否为异步函数返回相应的包装器 + if asyncio.iscoroutinefunction(func): + return async_wrapper + else: + return sync_wrapper return decorator @@ -111,19 +182,90 @@ def plugin_points_cost(points: int, description: str = None, feature: Feature = def decorator(func: Callable) -> Callable: @functools.wraps(func) - def wrapper(self, message: Dict[str, Any]) -> Tuple[bool, str]: + async def async_wrapper(self, message: Dict[str, Any]) -> Tuple[bool, str]: try: # 检查权限 roomid = message.get("roomid", "") if feature and roomid: - if GroupBotManager.get_group_permission(roomid, feature) == PermissionStatus.DISABLED: + gbm = message.get("gbm") + if gbm and gbm.get_group_permission(roomid, feature) == PermissionStatus.DISABLED: return False, "没有权限" - # 检查是否开启了积分获取功能 SIGNIN 和 TASK_GAME 如果没有开启,则不扣积分 请用== == PermissionStatus.DISABLED 判断 - if GroupBotManager.get_group_permission(roomid, - Feature.SIGNIN) == PermissionStatus.DISABLED and GroupBotManager.get_group_permission( - roomid, Feature.TASK_GAME) == PermissionStatus.DISABLED: + # 检查是否开启了积分获取功能 + if gbm and gbm.get_group_permission(roomid, Feature.SIGNIN) == PermissionStatus.DISABLED and gbm.get_group_permission( + roomid, Feature.TASK_GAME) == PermissionStatus.DISABLED: + return await func(self, message) + + # 获取消息信息 + sender = message.get("sender", "") + roomid = message.get("roomid", "") + + if not sender or not (roomid or sender): + return await func(self, message) + + # 检查用户积分是否足够 + db_manager = DBConnectionManager.get_instance() + points_db = PointsDBOperator(db_manager) + + plugin_name = self.name if hasattr(self, 'name') else "未知插件" + logger.info(f"PointsCost.{plugin_name}") + + user_points = points_db.get_user_points(sender, roomid) + if user_points["total_points"] < points: + # 积分不足 + await self.message_util.send_text( + f"❌ 积分不足\n无法使用 {plugin_name} 功能\n" + f"🪙 先参与积分活动[签到,答题/t]赚取吧!\n" + f"💰 有: {user_points['total_points']} | 需: {points} |差: {points - user_points['total_points']} ", + (roomid if roomid else sender), sender + ) + logger.info(f"用户 {sender} 积分不足,无法使用功能") + return False, "积分不足" + + # 调用原始异步方法 + success, response = await func(self, message) + + # 如果原始方法执行成功,扣除积分 + if success: + deduct_success, deduct_result = points_db.deduct_points( + sender, roomid, points, PointSource.PLUGIN, + description or f"使用 {plugin_name} 功能" + ) + + if deduct_success: + logger.info(f"用户 {sender} 使用 {plugin_name} 功能扣除 {points} 积分") + + # 添加对 response 的类型检查 + if isinstance(response, str) and "积分" not in response: + response += f"\n\n💰 已消费 {points} 积分" + await self.message_util.send_text( + f"💰消费 {points} 积分", + (roomid if roomid else sender), sender + ) + else: + logger.warning(f"用户 {sender} 积分扣除失败: {deduct_result}") + + return success, response + except Exception as e: + logger.error(f"积分消费失败: {e}") + logger.error(traceback.format_exc()) + return await func(self, message) + + @functools.wraps(func) + def sync_wrapper(self, message: Dict[str, Any]) -> Tuple[bool, str]: + try: + # 检查权限 + roomid = message.get("roomid", "") + if feature and roomid: + gbm = message.get("gbm") + if gbm and gbm.get_group_permission(roomid, feature) == PermissionStatus.DISABLED: + return False, "没有权限" + + # 检查是否开启了积分获取功能 + if gbm and gbm.get_group_permission(roomid, Feature.SIGNIN) == PermissionStatus.DISABLED and gbm.get_group_permission( + roomid, Feature.TASK_GAME) == PermissionStatus.DISABLED: return func(self, message) + # 获取消息信息 sender = message.get("sender", "") roomid = message.get("roomid", "") @@ -136,7 +278,7 @@ def plugin_points_cost(points: int, description: str = None, feature: Feature = points_db = PointsDBOperator(db_manager) plugin_name = self.name if hasattr(self, 'name') else "未知插件" - logger = logging.getLogger(f"PointsCost.{plugin_name}") + logger.info(f"PointsCost.{plugin_name}") user_points = points_db.get_user_points(sender, roomid) if user_points["total_points"] < points: @@ -150,7 +292,7 @@ def plugin_points_cost(points: int, description: str = None, feature: Feature = logger.info(f"用户 {sender} 积分不足,无法使用功能") return False, "积分不足" - # 调用原始方法 + # 调用原始同步方法 success, response = func(self, message) # 如果原始方法执行成功,扣除积分 @@ -175,11 +317,14 @@ def plugin_points_cost(points: int, description: str = None, feature: Feature = return success, response except Exception as e: - logger = logging.getLogger("PointsCost") logger.error(f"积分消费失败: {e}") logger.error(traceback.format_exc()) return func(self, message) - return wrapper + # 根据原始函数是否为异步函数返回相应的包装器 + if asyncio.iscoroutinefunction(func): + return async_wrapper + else: + return sync_wrapper return decorator diff --git a/utils/media_downloader.py b/utils/media_downloader.py index 5e070ed..cdcd047 100644 --- a/utils/media_downloader.py +++ b/utils/media_downloader.py @@ -3,7 +3,7 @@ import requests import uuid from typing import Optional from urllib.parse import urlparse -import logging +from loguru import logger import time class MediaDownloader: @@ -16,13 +16,13 @@ class MediaDownloader: Args: download_dir: 下载目录,默认为项目下的 media_downloads 目录 """ - self.logger = logging.getLogger("MediaDownloader") + self.LOG = logger self.download_dir = download_dir or os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "media_downloads" ) os.makedirs(self.download_dir, exist_ok=True) - self.logger.info(f"媒体下载目录: {self.download_dir}") + self.LOG.info(f"媒体下载目录: {self.download_dir}") def download_media(self, url: str, file_type: str = None) -> Optional[str]: """ @@ -47,7 +47,7 @@ class MediaDownloader: local_path = os.path.join(self.download_dir, filename) - self.logger.info(f"开始下载媒体文件: {url} -> {local_path}") + self.LOG.info(f"开始下载媒体文件: {url} -> {local_path}") # 下载文件 response = requests.get(url, stream=True, timeout=30) @@ -58,7 +58,7 @@ class MediaDownloader: if chunk: f.write(chunk) - self.logger.info(f"媒体文件下载成功: {local_path}") + self.LOG.info(f"媒体文件下载成功: {local_path}") # 下载成功后清理旧文件 self.clear_downloads() @@ -66,7 +66,7 @@ class MediaDownloader: return os.path.abspath(local_path) except Exception as e: - self.logger.error(f"下载媒体文件失败: {url}, 错误: {str(e)}") + self.LOG.error(f"下载媒体文件失败: {url}, 错误: {str(e)}") return None def _guess_file_type(self, url: str) -> Optional[str]: @@ -138,12 +138,12 @@ class MediaDownloader: try: os.remove(file_path) cleared_count += 1 - self.logger.debug(f"已删除过期文件: {file_path}") + self.LOG.debug(f"已删除过期文件: {file_path}") except Exception as e: - self.logger.error(f"删除文件失败 {file_path}: {str(e)}") + self.LOG.error(f"删除文件失败 {file_path}: {str(e)}") if cleared_count > 0: - self.logger.info(f"清理完成,共删除 {cleared_count} 个过期文件") + self.LOG.info(f"清理完成,共删除 {cleared_count} 个过期文件") except Exception as e: - self.logger.error(f"清理下载文件时出错: {str(e)}") \ No newline at end of file + self.LOG.error(f"清理下载文件时出错: {str(e)}") \ No newline at end of file diff --git a/utils/robot_cmd/robot_command.py b/utils/robot_cmd/robot_command.py index 6461ed9..60b00f6 100644 --- a/utils/robot_cmd/robot_command.py +++ b/utils/robot_cmd/robot_command.py @@ -6,15 +6,15 @@ # 3.群AI能力 #启用群AI #关闭群AI # 4.群总结能力 #启用群总结 #关闭群总结 # 5.sehuatang PDF能力 #启用pdf #关闭pdf -import logging from typing import List import redis from enum import Enum +from loguru import logger + # 连接到本地 Redis 服务 r = redis.StrictRedis(host='192.168.2.40', port=6379, db=0, decode_responses=True) -logger = logging.getLogger(f"GroupBotManager") class PermissionStatus(Enum): """权限状态枚举""" diff --git a/utils/wechat/contact_manager.py b/utils/wechat/contact_manager.py index 9779ac7..ffaf74d 100644 --- a/utils/wechat/contact_manager.py +++ b/utils/wechat/contact_manager.py @@ -2,10 +2,10 @@ """ 联系人管理器 - 提供全局访问联系人信息的单例类 """ -import logging + +from loguru import logger from typing import Dict, Optional, List, Tuple -from gewechat_client import GewechatClient from utils.json_converter import json_to_object @@ -20,7 +20,7 @@ class ContactManager: _official_accounts: Dict[str, str] = {} # 公众号 _head_images: Dict[str, str] = {} # 头像信息 _initialized = False - _logger = logging.getLogger("ContactManager") + _logger = logger _friends: List[Dict] = [] _group_contacts_friends: Dict[str, Dict[str, str]] = {} # 定义公共好友列表 diff --git a/utils/wechat/message_to_db.py b/utils/wechat/message_to_db.py index 4fba756..f4a3685 100644 --- a/utils/wechat/message_to_db.py +++ b/utils/wechat/message_to_db.py @@ -1,29 +1,24 @@ import time from datetime import datetime, timedelta import xml.etree.ElementTree as ET -import logging import concurrent.futures # 添加线程池支持 import os -from gewechat_client import GewechatClient - from db.connection import DBConnectionManager from db.message_storage import MessageStorageDB # 导入积分系统 from db.points_db import PointsDBOperator, PointSource -from gewechat.call_back_message.message import WxMessage, MessageType +from wechat_ipad import WechatAPIClient +from wechat_ipad.models.message import WxMessage, MessageType -# 配置日志 -logging.basicConfig( - level=logging.INFO, - format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' -) -logger = logging.getLogger("MessageStorage") +from loguru import logger + +logging = logger class MessageStorage: - def __init__(self, client: GewechatClient = None): + def __init__(self, client: WechatAPIClient = None): # 获取数据库连接管理器的单例 self.db_manager = DBConnectionManager.get_instance() self.message_db = MessageStorageDB(self.db_manager) @@ -123,38 +118,38 @@ class MessageStorage: if not os.path.exists(target_dir): os.makedirs(target_dir, exist_ok=True) # 尝试使用wcf下载图片到分组后的目录 - json = self.client.download_image(msg.appid, msg.content.xml_content, 2) - # { - # "ret": 200, - # "msg": "操作成功", - # "data": { - # "fileUrl": "/download/20240720/wx_BTVoJ_o_r6DpxNCNiycFE/0ca5b675-8e2c-4dc1-b288-3c44a40086ec4" - # } - # } - # 解析JSON http://192.168.2.240:2532/download/20250428/wx_3BC6eSHGE5xEm_hH3__7c/03ab5c03-5524-4a39-aabe-27ca014a4d1e.png - if json and json.get('data') and json['data'].get('fileUrl'): - file_url = json['data']['fileUrl'] - if file_url: - logger.info(f"记录gewe服务端图片路径成功: {msg.msg_id} -> {file_url}") - # 后续如果需要使用,则去服务器端提取图片 - # 直接使用下载后的路径更新数据库 - self.message_db.update_message_image_path(msg.msg_id, file_url) - - return { - 'success': True, - 'message_id': msg.msg_id, - 'roomid': msg.roomid, - 'sender': msg.sender, - 'file_path': file_url - } - else: - return { - 'success': False, - 'message_id': msg.msg_id, - 'roomid': msg.roomid, - 'sender': msg.sender, - 'error': "图片下载失败" - } + # json = self.client.download_image(msg.appid, msg.content.xml_content, 2) + # # { + # # "ret": 200, + # # "msg": "操作成功", + # # "data": { + # # "fileUrl": "/download/20240720/wx_BTVoJ_o_r6DpxNCNiycFE/0ca5b675-8e2c-4dc1-b288-3c44a40086ec4" + # # } + # # } + # # 解析JSON http://192.168.2.240:2532/download/20250428/wx_3BC6eSHGE5xEm_hH3__7c/03ab5c03-5524-4a39-aabe-27ca014a4d1e.png + # if json and json.get('data') and json['data'].get('fileUrl'): + # file_url = json['data']['fileUrl'] + # if file_url: + # logger.info(f"记录gewe服务端图片路径成功: {msg.msg_id} -> {file_url}") + # # 后续如果需要使用,则去服务器端提取图片 + # # 直接使用下载后的路径更新数据库 + # self.message_db.update_message_image_path(msg.msg_id, file_url) + # + # return { + # 'success': True, + # 'message_id': msg.msg_id, + # 'roomid': msg.roomid, + # 'sender': msg.sender, + # 'file_path': file_url + # } + # else: + # return { + # 'success': False, + # 'message_id': msg.msg_id, + # 'roomid': msg.roomid, + # 'sender': msg.sender, + # 'error': "图片下载失败" + # } else: return { 'success': False, diff --git a/wechat_ipad/bot-core.py b/wechat_ipad/bot-core.py index e30c286..6a430ff 100644 --- a/wechat_ipad/bot-core.py +++ b/wechat_ipad/bot-core.py @@ -8,6 +8,8 @@ import wechat_ipad # 明确导入需要的类 from loguru import logger +from wechat_ipad.models.message import WxMessage + async def bot_core(): # 读取 config.toml 文件 @@ -140,7 +142,11 @@ async def bot_core(): data = data.get("AddMsgs") if data: for message in data: - logger.info("message: {}".format(message)) + # 获取原始JSON数据 + # 创建消息对象 + msg = WxMessage.from_json(message) + logger.info("source message: {}".format(message)) + logger.info("parse msg: {}".format(msg)) # 使用异步睡眠替代忙等待循环 await asyncio.sleep(0.5) diff --git a/wechat_ipad/client/__init__.py b/wechat_ipad/client/__init__.py index bfaa79d..3631662 100644 --- a/wechat_ipad/client/__init__.py +++ b/wechat_ipad/client/__init__.py @@ -34,10 +34,11 @@ class WechatAPIClient(LoginMixin, MessageMixin, FriendMixin, ChatroomMixin, User raise UserLoggedOut("请先登录") output = "" - for id in at: - nickname = await self.get_nickname(id) + for at_id in at: + nickname = await self.get_chatroom_nickname(at_id, wxid) output += f"@{nickname}\u2005" + output += "\n" output += content return await self.send_text_message(wxid, output, at) diff --git a/wechat_ipad/client/fallback.png b/wechat_ipad/client/fallback.png new file mode 100644 index 0000000..466ff2e Binary files /dev/null and b/wechat_ipad/client/fallback.png differ diff --git a/wechat_ipad/client/firends.py b/wechat_ipad/client/firends.py index 3cdc913..18a6afe 100644 --- a/wechat_ipad/client/firends.py +++ b/wechat_ipad/client/firends.py @@ -59,7 +59,7 @@ class FriendMixin(WechatAPIClientBase): async with aiohttp.ClientSession() as session: json_param = {"Wxid": self.wxid, "RequestWxids": wxid} - response = await session.post(f'http://{self.ip}:{self.port}/GetContact', json=json_param) + response = await session.post(f'http://{self.ip}:{self.port}/api/Friend/GetContractDetail', json=json_param) json_resp = await response.json() if json_resp.get("Success"): @@ -90,7 +90,7 @@ class FriendMixin(WechatAPIClientBase): wxid = ",".join(wxid) async with aiohttp.ClientSession() as session: - json_param = {"Wxid": self.wxid, "RequestWxids": wxid, "Chatroom": chatroom} + json_param = {"Wxid": self.wxid, "Towxids": wxid, "Chatroom": chatroom} response = await session.post(f'http://{self.ip}:{self.port}/api/Friend/GetContractDetail', json=json_param) json_resp = await response.json() diff --git a/wechat_ipad/client/group.py b/wechat_ipad/client/group.py index 46318c7..2a2d384 100644 --- a/wechat_ipad/client/group.py +++ b/wechat_ipad/client/group.py @@ -43,8 +43,8 @@ class ChatroomMixin(WechatAPIClientBase): raise UserLoggedOut("请先登录") async with aiohttp.ClientSession() as session: - json_param = {"Wxid": self.wxid, "Chatroom": chatroom} - response = await session.post(f'http://{self.ip}:{self.port}/GetChatroomInfo', json=json_param) + json_param = {"Wxid": self.wxid, "QID": chatroom} + response = await session.post(f'http://{self.ip}:{self.port}/api/Group/GetChatRoomInfoDetail', json=json_param) json_resp = await response.json() if json_resp.get("Success"): @@ -67,8 +67,8 @@ class ChatroomMixin(WechatAPIClientBase): raise UserLoggedOut("请先登录") async with aiohttp.ClientSession() as session: - json_param = {"Wxid": self.wxid, "Chatroom": chatroom} - response = await session.post(f'http://{self.ip}:{self.port}/GetChatroomInfoNoAnnounce', json=json_param) + json_param = {"Wxid": self.wxid, "QID": chatroom} + response = await session.post(f'http://{self.ip}:{self.port}/api/Group/GetChatRoomInfo', json=json_param) json_resp = await response.json() if json_resp.get("Success"): @@ -89,8 +89,8 @@ class ChatroomMixin(WechatAPIClientBase): raise UserLoggedOut("请先登录") async with aiohttp.ClientSession() as session: - json_param = {"Wxid": self.wxid, "Chatroom": chatroom} - response = await session.post(f'http://{self.ip}:{self.port}/GetChatroomMemberDetail', json=json_param) + json_param = {"Wxid": self.wxid, "QID": chatroom} + response = await session.post(f'http://{self.ip}:{self.port}/api/Group/GetChatRoomMemberDetail', json=json_param) json_resp = await response.json() if json_resp.get("Success"): @@ -138,11 +138,46 @@ class ChatroomMixin(WechatAPIClientBase): wxid = ",".join(wxid) async with aiohttp.ClientSession() as session: - json_param = {"Wxid": self.wxid, "Chatroom": chatroom, "InviteWxids": wxid} - response = await session.post(f'http://{self.ip}:{self.port}/InviteChatroomMember', json=json_param) + json_param = {"Wxid": self.wxid, "ChatRoomName": chatroom, "ToWxids": wxid} + response = await session.post(f'http://{self.ip}:{self.port}/api/Group/InviteChatRoomMember', + json=json_param) json_resp = await response.json() if json_resp.get("Success"): return True else: self.error_handler(json_resp) + + async def get_chatroom_nickname(self, wxid: Union[str, list[str]], chatroom: str) -> Union[str, list[str]]: + """获取用户昵称 + + Args: + wxid: 用户wxid,可以是单个wxid或最多20个wxid的列表 + chatroom: 群聊id + + Returns: + Union[str, list[str]]: 如果输入单个wxid返回str,如果输入wxid列表则返回对应的昵称列表 + """ + data = await self.get_chatroom_member_list(chatroom) + + if isinstance(wxid, str): + # 单个wxid的情况 + for member in data: + if member.get("UserName") == wxid: + # 优先返回DisplayName,如果不存在则返回NickName + return member.get("DisplayName") or member.get("NickName") or "" + return "" # 如果没找到对应的成员,返回空字符串 + else: + # wxid列表的情况 + result = [] + for single_wxid in wxid: + found = False + for member in data: + if member.get("UserName") == single_wxid: + # 优先返回DisplayName,如果不存在则返回NickName + result.append(member.get("DisplayName") or member.get("NickName") or "") + found = True + break + if not found: + result.append("") # 如果没找到对应的成员,添加空字符串 + return result diff --git a/wechat_ipad/client/login.py b/wechat_ipad/client/login.py index dbbc631..aabcdfc 100644 --- a/wechat_ipad/client/login.py +++ b/wechat_ipad/client/login.py @@ -97,8 +97,7 @@ class LoginMixin(WechatAPIClientBase): raise UserLoggedOut("请先登录") async with aiohttp.ClientSession() as session: - json_param = {"Wxid": self.wxid} - response = await session.post(f'http://{self.ip}:{self.port}/Logout', json=json_param) + response = await session.post(f'http://{self.ip}:{self.port}/api/Login/LogOut?wxid={self.wxid}') json_resp = await response.json() if json_resp.get("Success"): diff --git a/wechat_ipad/client/message.py b/wechat_ipad/client/message.py index 16c9f75..e316a90 100644 --- a/wechat_ipad/client/message.py +++ b/wechat_ipad/client/message.py @@ -8,7 +8,7 @@ from pathlib import Path from typing import Union import aiohttp -import logging +from loguru import logger from pymediainfo import MediaInfo import pysilk @@ -24,6 +24,7 @@ class MessageMixin(WechatAPIClientBase): super().__init__(ip, port) self._message_queue = Queue() self._is_processing = False + self.logging = logger async def _process_message_queue(self): """ @@ -62,7 +63,13 @@ class MessageMixin(WechatAPIClientBase): async def revoke_message(self, wxid: str, client_msg_id: int, create_time: int, new_msg_id: int) -> bool: """撤回消息。 - + { + "ClientMsgId": 0, + "CreateTime": 0, + "NewMsgId": 0, + "ToUserName": "string", + "Wxid": "string" + } Args: wxid (str): 接收人wxid client_msg_id (int): 发送消息的返回值 @@ -81,16 +88,17 @@ class MessageMixin(WechatAPIClientBase): raise UserLoggedOut("请先登录") async with aiohttp.ClientSession() as session: - json_param = {"Wxid": self.wxid, "ToWxid": wxid, "ClientMsgId": client_msg_id, "CreateTime": create_time, + json_param = {"Wxid": self.wxid, "ToUserName": wxid, "ClientMsgId": client_msg_id, + "CreateTime": create_time, "NewMsgId": new_msg_id} - response = await session.post(f'http://{self.ip}:{self.port}/RevokeMsg', json=json_param) + response = await session.post(f'http://{self.ip}:{self.port}/api/Msg/Revoke', json=json_param) json_resp = await response.json() if json_resp.get("Success"): - logging.info("消息撤回成功: 对方wxid:{} ClientMsgId:{} CreateTime:{} NewMsgId:{}", - wxid, - client_msg_id, - new_msg_id) + self.logging.info("消息撤回成功: 对方wxid:{} ClientMsgId:{} CreateTime:{} NewMsgId:{}", + wxid, + client_msg_id, + new_msg_id) return True else: self.error_handler(json_resp) @@ -131,10 +139,10 @@ class MessageMixin(WechatAPIClientBase): async with aiohttp.ClientSession() as session: json_param = {"Wxid": self.wxid, "ToWxid": wxid, "Content": content, "Type": 1, "At": at_str} - response = await session.post(f'http://{self.ip}:{self.port}/SendTextMsg', json=json_param) + response = await session.post(f'http://{self.ip}:{self.port}/api/Msg/SendTxt', json=json_param) json_resp = await response.json() if json_resp.get("Success"): - logging.info("发送文字消息: 对方wxid:{} at:{} 内容:{}", wxid, at, content) + self.logging.info("发送文字消息: 对方wxid:{} at:{} 内容:{}", wxid, at, content) data = json_resp.get("Data") return data.get("List")[0].get("ClientMsgid"), data.get("List")[0].get("Createtime"), data.get("List")[ 0].get("NewMsgId") @@ -163,7 +171,6 @@ class MessageMixin(WechatAPIClientBase): int, int, int]: if not self.wxid: raise UserLoggedOut("请先登录") - if isinstance(image, str): pass @@ -177,12 +184,12 @@ class MessageMixin(WechatAPIClientBase): async with aiohttp.ClientSession() as session: json_param = {"Wxid": self.wxid, "ToWxid": wxid, "Base64": image} - response = await session.post(f'http://{self.ip}:{self.port}/SendImageMsg', json=json_param) + response = await session.post(f'http://{self.ip}:{self.port}/api/Msg/UploadImg', json=json_param) json_resp = await response.json() if json_resp.get("Success"): json_param.pop('Base64') - logging.info("发送图片消息: 对方wxid:{} 图片base64略", wxid) + self.logging.info("发送图片消息: 对方wxid:{} 图片base64略", wxid) data = json_resp.get("Data") return data.get("ClientImgId").get("string"), data.get("CreateTime"), data.get("Newmsgid") else: @@ -240,18 +247,18 @@ class MessageMixin(WechatAPIClientBase): # 打印预估时间,300KB/s predict_time = int(file_len / 1024 / 300) - logging.info("开始发送视频: 对方wxid:{} 视频base64略 图片base64略 预计耗时:{}秒", wxid, predict_time) + self.logging.info("开始发送视频: 对方wxid:{} 视频base64略 图片base64略 预计耗时:{}秒", wxid, predict_time) async with aiohttp.ClientSession() as session: json_param = {"Wxid": self.wxid, "ToWxid": wxid, "Base64": vid_base64, "ImageBase64": image_base64, "PlayLength": duration} - async with session.post(f'http://{self.ip}:{self.port}/SendVideoMsg', json=json_param) as resp: + async with session.post(f'http://{self.ip}:{self.port}/api/Msg/SendVideo', json=json_param) as resp: json_resp = await resp.json() if json_resp.get("Success"): json_param.pop('Base64') json_param.pop('ImageBase64') - logging.info("发送视频成功: 对方wxid:{} 时长:{} 视频base64略 图片base64略", wxid, duration) + self.logging.info("发送视频成功: 对方wxid:{} 时长:{} 视频base64略 图片base64略", wxid, duration) data = json_resp.get("Data") return data.get("clientMsgId"), data.get("newMsgId") else: @@ -277,12 +284,12 @@ class MessageMixin(WechatAPIClientBase): """ return await self._queue_message(self._send_voice_message, wxid, voice, format) - async def _send_voice_message(self, wxid: str, voice: Union[str, bytes, os.PathLike], format: str = "amr") -> \ + async def _send_voice_message(self, wxid: str, voice: Union[str, bytes, os.PathLike], format: str = "AMR") -> \ tuple[int, int, int]: if not self.wxid: raise UserLoggedOut("请先登录") - - elif format not in ["amr", "wav", "mp3"]: + + elif format not in ["AMR", "WAVE", "MP3", "SILK", "SPEEX"]: raise ValueError("format must be one of amr, wav, mp3") # read voice to byte @@ -297,15 +304,15 @@ class MessageMixin(WechatAPIClientBase): raise ValueError("voice should be str, bytes, or path") # get voice duration and b64 - if format.lower() == "amr": + if format.lower() == "AMR": audio = AudioSegment.from_file(BytesIO(voice_byte), format="amr") voice_base64 = base64.b64encode(voice_byte).decode() - elif format.lower() == "wav": + elif format.lower() == "WAVE": audio = AudioSegment.from_file(BytesIO(voice_byte), format="wav").set_channels(1) audio = audio.set_frame_rate(self._get_closest_frame_rate(audio.frame_rate)) voice_base64 = base64.b64encode( await pysilk.async_encode(audio.raw_data, sample_rate=audio.frame_rate)).decode() - elif format.lower() == "mp3": + elif format.lower() == "MP3": audio = AudioSegment.from_file(BytesIO(voice_byte), format="mp3").set_channels(1) audio = audio.set_frame_rate(self._get_closest_frame_rate(audio.frame_rate)) voice_base64 = base64.b64encode( @@ -314,18 +321,24 @@ class MessageMixin(WechatAPIClientBase): raise ValueError("format must be one of amr, wav, mp3") duration = len(audio) - - format_dict = {"amr": 0, "wav": 4, "mp3": 4} - + # Type: AMR = 0, MP3 = 2, SILK = 4, SPEEX = 1, WAVE = 3 VoiceTime :音频长度 1000为一秒 + format_dict = {"AMR": 0, "WAVE": 3, "MP3": 2, "SILK": 4, "SPEEX": 1} + # { + # "Base64": "string", + # "ToWxid": "string", + # "Type": 0, + # "VoiceTime": 0, + # "Wxid": "string" + # } async with aiohttp.ClientSession() as session: json_param = {"Wxid": self.wxid, "ToWxid": wxid, "Base64": voice_base64, "VoiceTime": duration, "Type": format_dict[format]} - response = await session.post(f'http://{self.ip}:{self.port}/SendVoiceMsg', json=json_param) + response = await session.post(f'http://{self.ip}:{self.port}/api/Msg/SendVoice', json=json_param) json_resp = await response.json() if json_resp.get("Success"): json_param.pop('Base64') - logging.info("发送语音消息: 对方wxid:{} 时长:{} 格式:{} 音频base64略", wxid, duration, format) + self.logging.info("发送语音消息: 对方wxid:{} 时长:{} 格式:{} 音频base64略", wxid, duration, format) data = json_resp.get("Data") return int(data.get("ClientMsgId")), data.get("CreateTime"), data.get("NewMsgId") else: @@ -344,10 +357,38 @@ class MessageMixin(WechatAPIClientBase): return closest_rate + async def send_link_xml_message(self, xml: str, towxid: str) -> tuple[str, int, int]: + """发送链接消息。 + { + "ToWxid": "string", + "Type": 0, + "Wxid": "string", + "Xml": "string" + } + Args: + xml (str): 发送的内容 + towxid (str):接收人 + + Returns: + tuple[str, int, int]: 返回(ClientMsgid, CreateTime, NewMsgId) + + Raises: + UserLoggedOut: 未登录时调用 + BanProtection: 登录新设备后4小时内操作 + 根据error_handler处理错误 + """ + + return await self._queue_message(self._send_link_xml_message, xml, towxid) + async def send_link_message(self, wxid: str, url: str, title: str = "", description: str = "", thumb_url: str = "") -> tuple[str, int, int]: """发送链接消息。 - + { + "ToWxid": "string", + "Type": 0, + "Wxid": "string", + "Xml": "string" + } Args: wxid (str): 接收人wxid url (str): 跳转链接 @@ -363,8 +404,25 @@ class MessageMixin(WechatAPIClientBase): BanProtection: 登录新设备后4小时内操作 根据error_handler处理错误 """ + return await self._queue_message(self._send_link_message, wxid, url, title, description, thumb_url) + async def _send_link_xml_message(self, xml: str, towxid: str) -> tuple[int, int, int]: + if not self.wxid: + raise UserLoggedOut("请先登录") + + async with aiohttp.ClientSession() as session: + json_param = {"Wxid": self.wxid, "ToWxid": towxid, "Xml": xml, "Type": 0} + + response = await session.post(f'http://{self.ip}:{self.port}/api/Msg/ShareLink', json=json_param) + json_resp = await response.json() + logger.info(f"_send_link_xml_message resp:{json_resp}") + if json_resp.get("Success"): + data = json_resp.get("Data") + return data.get("clientMsgId"), data.get("createTime"), data.get("newMsgId") + else: + self.error_handler(json_resp) + async def _send_link_message(self, wxid: str, url: str, title: str = "", description: str = "", thumb_url: str = "") -> tuple[int, int, int]: if not self.wxid: @@ -373,16 +431,17 @@ class MessageMixin(WechatAPIClientBase): async with aiohttp.ClientSession() as session: json_param = {"Wxid": self.wxid, "ToWxid": wxid, "Url": url, "Title": title, "Desc": description, "ThumbUrl": thumb_url} - response = await session.post(f'http://{self.ip}:{self.port}/SendShareLink', json=json_param) + + response = await session.post(f'http://{self.ip}:{self.port}/api/Msg/ShareLink', json=json_param) json_resp = await response.json() if json_resp.get("Success"): - logging.info("发送链接消息: 对方wxid:{} 链接:{} 标题:{} 描述:{} 缩略图链接:{}", - wxid, - url, - title, - description, - thumb_url) + self.logging.info("发送链接消息: 对方wxid:{} 链接:{} 标题:{} 描述:{} 缩略图链接:{}", + wxid, + url, + title, + description, + thumb_url) data = json_resp.get("Data") return data.get("clientMsgId"), data.get("createTime"), data.get("newMsgId") else: @@ -409,7 +468,6 @@ class MessageMixin(WechatAPIClientBase): async def _send_emoji_message(self, wxid: str, md5: str, total_length: int) -> tuple[int, int, int]: if not self.wxid: raise UserLoggedOut("请先登录") - async with aiohttp.ClientSession() as session: json_param = {"Wxid": self.wxid, "ToWxid": wxid, "Md5": md5, "TotalLen": total_length} @@ -417,7 +475,7 @@ class MessageMixin(WechatAPIClientBase): json_resp = await response.json() if json_resp.get("Success"): - logging.info("发送表情消息: 对方wxid:{} md5:{} 总长度:{}", wxid, md5, total_length) + self.logging.info("发送表情消息: 对方wxid:{} md5:{} 总长度:{}", wxid, md5, total_length) return json_resp.get("Data").get("emojiItem") else: self.error_handler(json_resp) @@ -447,7 +505,6 @@ class MessageMixin(WechatAPIClientBase): if not self.wxid: raise UserLoggedOut("请先登录") - async with aiohttp.ClientSession() as session: json_param = {"Wxid": self.wxid, "ToWxid": wxid, "CardWxid": card_wxid, "CardAlias": card_alias, "CardNickname": card_nickname} @@ -455,10 +512,10 @@ class MessageMixin(WechatAPIClientBase): json_resp = await response.json() if json_resp.get("Success"): - logging.info("发送名片消息: 对方wxid:{} 名片wxid:{} 名片备注:{} 名片昵称:{}", wxid, - card_wxid, - card_alias, - card_nickname) + self.logging.info("发送名片消息: 对方wxid:{} 名片wxid:{} 名片备注:{} 名片昵称:{}", wxid, + card_wxid, + card_alias, + card_nickname) data = json_resp.get("Data") return data.get("List")[0].get("ClientMsgid"), data.get("List")[0].get("Createtime"), data.get("List")[ 0].get("NewMsgId") @@ -486,16 +543,20 @@ class MessageMixin(WechatAPIClientBase): async def _send_app_message(self, wxid: str, xml: str, type: int) -> tuple[int, int, int]: if not self.wxid: raise UserLoggedOut("请先登录") - - + # { + # "ToWxid": "string", + # "Type": 0, + # "Wxid": "string", + # "Xml": "string" + # } async with aiohttp.ClientSession() as session: json_param = {"Wxid": self.wxid, "ToWxid": wxid, "Xml": xml, "Type": type} - response = await session.post(f'http://{self.ip}:{self.port}/SendAppMsg', json=json_param) + response = await session.post(f'http://{self.ip}:{self.port}/api/Msg/SendApp', json=json_param) json_resp = await response.json() - + logger.info(f"json_resp: {json_resp}") if json_resp.get("Success"): json_param["Xml"] = json_param["Xml"].replace("\n", "") - logging.info("发送app消息: 对方wxid:{} 类型:{} xml:{}", wxid, type, json_param["Xml"]) + self.logging.info("发送app消息: 对方wxid:{} 类型:{} xml:{}", wxid, type, json_param["Xml"]) return json_resp.get("Data").get("clientMsgId"), json_resp.get("Data").get( "createTime"), json_resp.get("Data").get("newMsgId") else: @@ -522,14 +583,13 @@ class MessageMixin(WechatAPIClientBase): if not self.wxid: raise UserLoggedOut("请先登录") - async with aiohttp.ClientSession() as session: json_param = {"Wxid": self.wxid, "ToWxid": wxid, "Content": xml} response = await session.post(f'http://{self.ip}:{self.port}/SendCDNFileMsg', json=json_param) json_resp = await response.json() if json_resp.get("Success"): - logging.info("转发文件消息: 对方wxid:{} xml:{}", wxid, xml) + self.logging.info("转发文件消息: 对方wxid:{} xml:{}", wxid, xml) data = json_resp.get("Data") return data.get("clientMsgId"), data.get("createTime"), data.get("newMsgId") else: @@ -556,14 +616,13 @@ class MessageMixin(WechatAPIClientBase): if not self.wxid: raise UserLoggedOut("请先登录") - async with aiohttp.ClientSession() as session: json_param = {"Wxid": self.wxid, "ToWxid": wxid, "Content": xml} response = await session.post(f'http://{self.ip}:{self.port}/SendCDNImgMsg', json=json_param) json_resp = await response.json() if json_resp.get("Success"): - logging.info("转发图片消息: 对方wxid:{} xml:{}", wxid, xml) + self.logging.info("转发图片消息: 对方wxid:{} xml:{}", wxid, xml) data = json_resp.get("Data") return data.get("ClientImgId").get("string"), data.get("CreateTime"), data.get("Newmsgid") else: @@ -590,14 +649,13 @@ class MessageMixin(WechatAPIClientBase): if not self.wxid: raise UserLoggedOut("请先登录") - async with aiohttp.ClientSession() as session: json_param = {"Wxid": self.wxid, "ToWxid": wxid, "Content": xml} response = await session.post(f'http://{self.ip}:{self.port}/SendCDNVideoMsg', json=json_param) json_resp = await response.json() if json_resp.get("Success"): - logging.info("转发视频消息: 对方wxid:{} xml:{}", wxid, xml) + self.logging.info("转发视频消息: 对方wxid:{} xml:{}", wxid, xml) data = json_resp.get("Data") return data.get("clientMsgId"), data.get("newMsgId") else: diff --git a/wechat_ipad/client/tools.py b/wechat_ipad/client/tools.py index df55d3b..ab46c91 100644 --- a/wechat_ipad/client/tools.py +++ b/wechat_ipad/client/tools.py @@ -13,7 +13,11 @@ from wechat_ipad.client.base import WechatAPIClientBase, Proxy class ToolMixin(WechatAPIClientBase): async def download_image(self, aeskey: str, cdnmidimgurl: str) -> str: """CDN下载高清图片。 - + { + "Wxid": "string", + "FileNo": "string", + "FileAesKey": "string" + } Args: aeskey (str): 图片的AES密钥 cdnmidimgurl (str): 图片的CDN URL @@ -30,7 +34,7 @@ class ToolMixin(WechatAPIClientBase): async with aiohttp.ClientSession() as session: json_param = {"Wxid": self.wxid, "AesKey": aeskey, "Cdnmidimgurl": cdnmidimgurl} - response = await session.post(f'http://{self.ip}:{self.port}/CdnDownloadImg', json=json_param) + response = await session.post(f'http://{self.ip}:{self.port}/api/Tools/CdnDownloadImage', json=json_param) json_resp = await response.json() if json_resp.get("Success"): diff --git a/gewechat/call_back_message/message.py b/wechat_ipad/models/message.py similarity index 97% rename from gewechat/call_back_message/message.py rename to wechat_ipad/models/message.py index f247fed..42dff0d 100644 --- a/gewechat/call_back_message/message.py +++ b/wechat_ipad/models/message.py @@ -4,6 +4,7 @@ from enum import Enum import xml.etree.ElementTree as ET import re + class MessageType(Enum): """消息类型枚举""" UNKNOWN = 0 # 未知类型 @@ -158,18 +159,17 @@ class WxMessage: raw_data: Dict[str, Any] # 原始JSON数据 @classmethod - def from_json(cls, json_data: Dict[str, Any]) -> 'WxMessage': + def from_json(cls, data: Dict[str, Any]) -> 'WxMessage': """从JSON数据创建消息对象""" - data = json_data.get("Data", {}) to_user = data.get("ToUserName", {}).get("string", "") from_user = data.get("FromUserName", {}).get("string", "") # 获取原始内容 content_str = data.get("Content", {}).get("string", "") - + # 判断是否是群聊消息 is_group_chat = from_user.endswith("@chatroom") - + # 如果是群聊消息,需要调整发送者和接收者 actual_sender = from_user if is_group_chat and content_str: @@ -182,14 +182,14 @@ class WxMessage: actual_sender = potential_sender # 群聊消息中,接收者是群ID to_user = from_user - + # 创建MessageContent对象时传入发信人信息 message_content = MessageContent(content_str, sender=actual_sender) return cls( - type_name=json_data.get("TypeName", ""), - appid=json_data.get("Appid", ""), - wxid=json_data.get("Wxid", ""), + type_name=data.get("TypeName", ""), + appid=data.get("Appid", ""), + wxid=data.get("Wxid", ""), msg_id=data.get("MsgId", 0), sender=actual_sender, # 使用提取出的实际发送人 to_user=to_user, # 群聊时,接收者为群ID @@ -201,7 +201,7 @@ class WxMessage: new_msg_id=data.get("NewMsgId", 0), msg_seq=data.get("MsgSeq", 0), msg_source=data.get("MsgSource", ""), - raw_data=json_data + raw_data=data ) def __str__(self) -> str: @@ -396,4 +396,4 @@ if __name__ == '__main__': content = MessageContent(content_str, sender="Jyunere") print(content.raw_content) print(content.xml_content) - print(content.clean_content) \ No newline at end of file + print(content.clean_content)