diff --git a/clients/http/MANIFEST.in b/clients/http/MANIFEST.in deleted file mode 100644 index e228aeb..0000000 --- a/clients/http/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -include wcferry/*.dll -include wcferry/*.exe diff --git a/clients/http/README.MD b/clients/http/README.MD index c9d8684..f06d39a 100644 --- a/clients/http/README.MD +++ b/clients/http/README.MD @@ -1,32 +1,3 @@ -# WeChatFerry HTTP 客户端 -[![PyPi](https://img.shields.io/pypi/v/wcfhttp.svg)](https://pypi.python.org/pypi/wcfhttp) [![Downloads](https://static.pepy.tech/badge/wcfhttp)](https://pypi.python.org/pypi/wcfhttp) [![Documentation Status](https://readthedocs.org/projects/wechatferry/badge/?version=latest)](https://wechatferry.readthedocs.io/zh/latest/?badge=latest) +# ~~WeChatFerry HTTP 客户端~~ -基于 [wcferry](https://pypi.org/project/wcferry/) 封装的 HTTP 客户端。 - -## 快速开始 -### 安装 -```sh -pip install --upgrade wcfhttp -``` - -### 运行 -```sh -# 查看版本 -wcfhttp -v - -# 查看帮助 -wcfhttp -h - -# 忽略新消息运行 -wcfhttp - -# 新消息转发到指定地址 -wcfhttp --cb http://your_host:your_port/callback -``` - -### 接收消息回调接口文档 -参考文档(默认地址为:http://localhost:9999/docs )`接收消息回调样例`。 - -|![碲矿](https://raw.githubusercontent.com/lich0821/WeChatFerry/master/assets/TEQuant.jpg)|![赞赏](https://raw.githubusercontent.com/lich0821/WeChatFerry/master/assets/QR.jpeg)| -|:-:|:-:| -|后台回复 `WCF` 加群交流|如果你觉得有用| +❗ **wcfhttp 不再维护,有需要可以使用 [WcfRust](https://github.com/lich0821/wcf-client-rust) 或者 [GoHttp](clients/gohttp/README.md)。** diff --git a/clients/http/setup.py b/clients/http/setup.py deleted file mode 100644 index f4e4771..0000000 --- a/clients/http/setup.py +++ /dev/null @@ -1,50 +0,0 @@ -#! /usr/bin/env python3 -# -*- coding: utf-8 -*- - - -from __future__ import print_function -from setuptools import setup, find_packages - -import wcfhttp - -with open("README.md", "r", encoding="utf-8") as fh: - long_description = fh.read() - - -setup( - name="wcfhttp", - version=wcfhttp.core.__version__, - author="Changhua", - author_email="lichanghua0821@gmail.com", - description="一个玩微信的工具", - long_description=long_description, - long_description_content_type="text/markdown", - license="MIT", - url="https://github.com/lich0821/WeChatFerry", - python_requires=">=3.8", - packages=find_packages(), - include_package_data=True, - entry_points={ - 'console_scripts': [ - 'wcfhttp=wcfhttp.main:main' - ] - }, - install_requires=[ - "setuptools", - "fastapi", - "uvicorn[standard]", - "wcferry>=39.0.10.0", - ], - classifiers=[ - "Environment :: Win32 (MS Windows)", - "Intended Audience :: Developers", - "Intended Audience :: Customer Service", - "Topic :: Communications :: Chat", - "Operating System :: Microsoft :: Windows", - "Programming Language :: Python", - ], - project_urls={ - "Documentation": "https://wechatferry.readthedocs.io/zh/latest/index.html", - "GitHub": "https://github.com/lich0821/WeChatFerry/", - }, -) diff --git a/clients/http/wcfhttp/__init__.py b/clients/http/wcfhttp/__init__.py deleted file mode 100644 index c8795b3..0000000 --- a/clients/http/wcfhttp/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- - -from wcfhttp.core import Http, __version__ \ No newline at end of file diff --git a/clients/http/wcfhttp/core.py b/clients/http/wcfhttp/core.py deleted file mode 100644 index b7dd7fb..0000000 --- a/clients/http/wcfhttp/core.py +++ /dev/null @@ -1,550 +0,0 @@ -#! /usr/bin/env python3 -# -*- coding: utf-8 -*- - -import base64 -import logging -from queue import Empty -from threading import Thread -from typing import Any - -import requests -from fastapi import Body, FastAPI, Query -from pydantic import BaseModel -from wcferry import Wcf, WxMsg - -__version__ = "39.0.10.0" - - -class Msg(BaseModel): - id: int - ts: int - sign: str - type: int - xml: str - sender: str - roomid: str - content: str - thumb: str - extra: str - is_at: bool - is_self: bool - is_group: bool - - -class Http(FastAPI): - """WeChatFerry HTTP 客户端,文档地址:http://IP:PORT/docs""" - - def __init__(self, wcf: Wcf, cb: str, **extra: Any) -> None: - super().__init__(**extra) - self.LOG = logging.getLogger(__name__) - self.LOG.info(f"wcfhttp version: {__version__}") - self.wcf = wcf - self._set_cb(cb) - self.add_api_route("/msg_cb", self.msg_cb, methods=["POST"], summary="接收消息回调样例", tags=["示例"]) - - self.add_api_route("/login", self.is_login, methods=["GET"], summary="获取登录状态") - self.add_api_route("/wxid", self.get_self_wxid, methods=["GET"], summary="获取登录账号 wxid") - self.add_api_route("/user-info", self.get_user_info, methods=["GET"], summary="获取登录账号个人信息") - self.add_api_route("/msg-types", self.get_msg_types, methods=["GET"], summary="获取消息类型") - self.add_api_route("/contacts", self.get_contacts, methods=["GET"], summary="获取完整通讯录") - self.add_api_route("/friends", self.get_friends, methods=["GET"], summary="获取好友列表") - self.add_api_route("/dbs", self.get_dbs, methods=["GET"], summary="获取所有数据库") - self.add_api_route("/{db}/tables", self.get_tables, methods=["GET"], summary="获取 db 中所有表") - self.add_api_route("/pyq", self.refresh_pyq, methods=["GET"], summary="刷新朋友圈(数据从消息回调中查看)") - self.add_api_route("/chatroom-member", self.get_chatroom_members, methods=["GET"], summary="获取群成员") - self.add_api_route("/alias-in-chatroom", self.get_alias_in_chatroom, methods=["GET"], summary="获取群成员名片") - self.add_api_route("/ocr-result", self.get_ocr_result, methods=["GET"], summary="获取 OCR 结果") - - self.add_api_route("/text", self.send_text, methods=["POST"], summary="发送文本消息") - self.add_api_route("/image", self.send_image, methods=["POST"], summary="发送图片消息") - self.add_api_route("/file", self.send_file, methods=["POST"], summary="发送文件消息") - self.add_api_route("/rich-text", self.send_rich_text, methods=["POST"], summary="发送卡片消息") - self.add_api_route("/pat", self.send_pat_msg, methods=["POST"], summary="发送拍一拍消息") - # self.add_api_route("/xml", self.send_xml, methods=["POST"], summary="发送 XML 消息") - # self.add_api_route("/emotion", self.send_emotion, methods=["POST"], summary="发送表情消息") - self.add_api_route("/sql", self.query_sql, methods=["POST"], summary="执行 SQL,如果数据量大注意分页,以免 OOM") - self.add_api_route("/new-friend", self.accept_new_friend, methods=["POST"], summary="通过好友申请") - self.add_api_route("/chatroom-member", self.add_chatroom_members, methods=["POST"], summary="添加群成员") - self.add_api_route("/cr-members", self.invite_chatroom_members, methods=["POST"], summary="邀请群成员") - self.add_api_route("/transfer", self.receive_transfer, methods=["POST"], summary="接收转账") - self.add_api_route("/dec-image", self.decrypt_image, methods=["POST"], summary="(废弃)解密图片") - self.add_api_route("/attachment", self.download_attachment, methods=["POST"], summary="(废弃)下载图片、文件和视频") - self.add_api_route("/save-image", self.download_image, methods=["POST"], summary="下载图片") - self.add_api_route("/save-audio", self.get_audio_msg, methods=["POST"], summary="保存语音") - - self.add_api_route("/chatroom-member", self.del_chatroom_members, methods=["DELETE"], summary="删除群成员") - - def _forward_msg(self, msg: WxMsg, cb: str): - data = {} - data["id"] = msg.id - data["ts"] = msg.ts - data["sign"] = msg.sign - data["type"] = msg.type - data["xml"] = msg.xml - data["sender"] = msg.sender - data["roomid"] = msg.roomid - data["content"] = msg.content - data["thumb"] = msg.thumb - data["extra"] = msg.extra - data["is_at"] = msg.is_at(self.wcf.self_wxid) - data["is_self"] = msg.from_self() - data["is_group"] = msg.from_group() - - try: - rsp = requests.post(url=cb, json=data, timeout=30) - if rsp.status_code != 200: - self.LOG.error(f"消息转发失败,HTTP 状态码为: {rsp.status_code}") - except Exception as e: - self.LOG.error(f"消息转发异常: {e}") - - def _set_cb(self, cb: str): - def callback(wcf: Wcf): - while wcf.is_receiving_msg(): - try: - msg = wcf.get_msg() - self.LOG.info(msg) - self._forward_msg(msg, cb) - except Empty: - continue # Empty message - except Exception as e: - self.LOG.error(f"Receiving message error: {e}") - - if cb: - self.LOG.info(f"消息回调: {cb}") - self.wcf.enable_receiving_msg(pyq=True) # 同时允许接收朋友圈消息 - Thread(target=callback, name="GetMessage", args=(self.wcf,), daemon=True).start() - else: - self.LOG.info(f"没有设置回调,打印消息") - self.wcf.enable_recv_msg(print) - - def is_login(self) -> dict: - """获取登录状态""" - ret = self.wcf.is_login() - return {"status": 0, "message": "成功", "data": {"login": ret}} - - def get_self_wxid(self) -> dict: - """获取登录账号 wxid""" - ret = self.wcf.get_self_wxid() - if ret: - return {"status": 0, "message": "成功", "data": {"wxid": ret}} - return {"status": -1, "message": "失败"} - - def get_msg_types(self) -> dict: - """获取消息类型""" - ret = self.wcf.get_msg_types() - if ret: - return {"status": 0, "message": "成功", "data": {"types": ret}} - return {"status": -1, "message": "失败"} - - def get_contacts(self) -> dict: - """获取完整通讯录""" - ret = self.wcf.get_contacts() - if ret: - return {"status": 0, "message": "成功", "data": {"contacts": ret}} - return {"status": -1, "message": "失败"} - - def get_friends(self) -> dict: - """获取好友列表""" - ret = self.wcf.get_friends() - if ret: - return {"status": 0, "message": "成功", "data": {"friends": ret}} - return {"status": -1, "message": "失败"} - - def get_dbs(self) -> dict: - """获取所有数据库""" - ret = self.wcf.get_dbs() - if ret: - return {"status": 0, "message": "成功", "data": {"dbs": ret}} - return {"status": -1, "message": "失败"} - - def get_tables(self, db: str) -> dict: - """获取 db 中所有表 - - Args: - db (str): 数据库名(可通过 `get_dbs` 查询) - - Returns: - List[dict]: `db` 下的所有表名及对应建表语句 - """ - ret = self.wcf.get_tables(db) - if ret: - return {"status": 0, "message": "成功", "data": {"tables": ret}} - return {"status": -1, "message": "失败"} - - def get_user_info(self) -> dict: - """获取登录账号个人信息""" - ret = self.wcf.get_user_info() - if ret: - return {"status": 0, "message": "成功", "data": {"ui": ret}} - return {"status": -1, "message": "失败"} - - def get_ocr_result(self, extra: str = Body("C:/...", description="消息中的 extra"), - timeout: int = Body("30", description="超时时间(秒)")) -> dict: - """获取 OCR 结果。鸡肋,需要图片能自动下载;通过下载接口下载的图片无法识别。 - - Args: - extra (str): 待识别的图片路径,消息里的 extra - - Returns: - str: OCR 结果 - """ - ret = self.wcf.get_ocr_result(extra, timeout) - if ret: - return {"status": 0, "message": "成功", "data": {"ocr": ret}} - return {"status": -1, "message": "可能失败,可以看看日志。这接口没啥用,别用了。"} - - def msg_cb(self, msg: Msg = Body(description="微信消息")): - """示例回调方法,简单打印消息""" - print(f"收到消息:{msg}") - return {"status": 0, "message": "成功"} - - def send_text( - self, msg: str = Body(description="要发送的消息,换行用\\n表示"), - receiver: str = Body("filehelper", description="消息接收者,roomid 或者 wxid"), - aters: str = Body("", description="要 @ 的 wxid,多个用逗号分隔;@所有人 用 notify@all")) -> dict: - """发送文本消息,可参考:https://github.com/lich0821/WeChatRobot/blob/master/robot.py 里 sendTextMsg - - Args: - msg (str): 要发送的消息,换行使用 `\\n`;如果 @ 人的话,需要带上跟 `aters` 里数量相同的 @ - receiver (str): 消息接收人,wxid 或者 roomid - aters (str): 要 @ 的 wxid,多个用逗号分隔;`@所有人` 只需要 `notify@all` - - Returns: - int: 0 为成功,其他失败 - """ - ret = self.wcf.send_text(msg, receiver, aters) - return {"status": ret, "message": "成功"if ret == 0 else "失败"} - - def send_image(self, - path: str = Body("C:\\Projs\\WeChatRobot\\TEQuant.jpeg", description="图片路径"), - receiver: str = Body("filehelper", description="消息接收者,roomid 或者 wxid")) -> dict: - """发送图片,非线程安全 - - Args: - path (str): 图片路径,如:`C:/Projs/WeChatRobot/TEQuant.jpeg` 或 `https://raw.githubusercontent.com/lich0821/WeChatRobot/master/TEQuant.jpeg` - receiver (str): 消息接收人,wxid 或者 roomid - - Returns: - int: 0 为成功,其他失败 - """ - ret = self.wcf.send_image(path, receiver) - return {"status": ret, "message": "成功"if ret == 0 else "失败"} - - def send_file(self, - path: str = Body("C:\\Projs\\WeChatRobot\\TEQuant.jpeg", description="本地文件路径,不支持网络路径"), - receiver: str = Body("filehelper", description="roomid 或者 wxid")) -> dict: - """发送文件 - - Args: - path (str): 本地文件路径,如:`C:/Projs/WeChatRobot/README.MD` - receiver (str): 消息接收人,wxid 或者 roomid - - Returns: - int: 0 为成功,其他失败 - """ - ret = self.wcf.send_file(path, receiver) - return {"status": ret, "message": "成功"if ret == 0 else "失败"} - - def send_rich_text( - self, name: str = Body("碲矿", description="左下显示的名字"), - account: str = Body("gh_75dea2d6c71f", description="填公众号 id 可以显示对应的头像"), - title: str = Body("【FAQ】WeChatFerry 机器人常见问题 v39.0.10", description="标题,最多两行"), - digest: str = Body("先看再问,少走弯路。", description="最多三行,会占位"), - url: - str = Body( - "http://mp.weixin.qq.com/s?__biz=MzI0MjI1OTk0OQ==&mid=2247487601&idx=1&sn=1bf7a0d1c659f8bc78a00cba18d7b204&chksm=e97e52f3de09dbe591fe23f335ce73bc468bd107a8c7bc5a458752a47f9d2d55a5fcdc5dd386&mpshare=1&scene=1&srcid=1209eP4EsXnynxyRQHzCK2bY&sharer_shareinfo=a12096ee76b4e3a9e72c9aedaf51a5ef&sharer_shareinfo_first=a12096ee76b4e3a9e72c9aedaf51a5ef#rd", - description="点击后跳转的链接"), - thumburl: str = Body("https://mmbiz.qpic.cn/mmbiz_jpg/XaSOeHibHicMGIiaZsBeYYjcuS2KfBGXfm8ibb9QrKJqk0H0W3JHia9icVica9nlWMiaD0xWmA0pKHpMOWbeBCJaAQc2IQ/0?wx_fmt=jpeg", description="缩略图的链接"), - receiver: str = Body("filehelper", description="接收人, wxid 或者 roomid")) -> dict: - """发送卡片消息 - 卡片样式(格式乱了,看这里:https://github.com/lich0821/WeChatFerry/blob/master/clients/python/wcferry/client.py#L421): - |-------------------------------------| - |title, 最长两行 - |(长标题, 标题短的话这行没有) - |digest, 最多三行,会占位 |--------| - |digest, 最多三行,会占位 |thumburl| - |digest, 最多三行,会占位 |--------| - |(account logo) name - |-------------------------------------| - Args: - name (str): 左下显示的名字 - account (str): 填公众号 id 可以显示对应的头像(gh_ 开头的) - title (str): 标题,最多两行 - digest (str): 摘要,三行 - url (str): 点击后跳转的链接 - thumburl (str): 缩略图的链接 - receiver (str): 接收人, wxid 或者 roomid - - Returns: - int: 0 为成功,其他失败 - """ - ret = self.wcf.send_rich_text(name, account, title, digest, url, thumburl, receiver) - return {"status": ret, "message": "成功"if ret == 0 else "失败,原因见日志"} - - def send_pat_msg( - self, roomid: str = Body(description="要发送的消息,换行用\\n表示"), - wxid: str = Body("filehelper", description="消息接收者,roomid 或者 wxid")) -> dict: - """拍一拍群友 - - Args: - roomid (str): 群友所在群 roomid - wxid (str): 要拍的群友的 wxid - - Returns: - int: 1 为成功,其他失败 - """ - ret = self.wcf.send_pat_msg(roomid, wxid) - return {"status": ret, "message": "成功"if ret == 1 else "失败,原因见日志"} - - def send_xml( - self, receiver: str = Body("filehelper", description="roomid 或者 wxid"), - xml: - str = Body( - '叮当药房,24小时服务,28分钟送药到家!叮当快药首家承诺范围内28分钟送药到家!叮当快药核心区域内7*24小时全天候服务,送药上门!叮当快药官网为您提供快捷便利,正品低价,安全放心的购药、送药服务体验。view33wxid_xxxxxxxxxxxxxx01', - description="xml 内容"), - type: int = Body(0x21, description="xml 类型,0x21 为小程序"), - path: str = Body(None, description="封面图片路径")) -> dict: - """发送 XML - - Args: - receiver (str): 消息接收人,wxid 或者 roomid - xml (str): xml 内容 - type (int): xml 类型,如:0x21 为小程序 - path (str): 封面图片路径 - - Returns: - int: 0 为成功,其他失败 - """ - ret = self.wcf.send_xml(receiver, xml, type, path) - return {"status": ret, "message": "成功"if ret == 0 else "失败"} - - def send_emotion(self, - path: str = Body("C:/Projs/WeChatRobot/emo.gif", description="本地文件路径,不支持网络路径"), - receiver: str = Body("filehelper", description="roomid 或者 wxid")) -> dict: - """发送表情 - - Args: - path (str): 本地表情路径,如:`C:/Projs/WeChatRobot/emo.gif` - receiver (str): 消息接收人,wxid 或者 roomid - - Returns: - int: 0 为成功,其他失败 - """ - ret = self.wcf.send_emotion(path, receiver) - return {"status": ret, "message": "成功"if ret == 0 else "失败"} - - def query_sql(self, - db: str = Body("MicroMsg.db", description="数据库"), - sql: str = Body("SELECT * FROM Contact LIMIT 1;", description="SQL 语句")) -> dict: - """执行 SQL,如果数据量大注意分页,以免 OOM - - Args: - db (str): 要查询的数据库 - sql (str): 要执行的 SQL - - Returns: - List[dict]: 查询结果 - """ - ret = self.wcf.query_sql(db, sql) - if ret: - for row in ret: - for k, v in row.items(): - print(k, type(v)) - if type(v) is bytes: - row[k] = base64.b64encode(v) - return {"status": 0, "message": "成功", "data": {"bs64": ret}} - return {"status": -1, "message": "失败"} - - def accept_new_friend(self, - v3: str = Body("v3", description="加密用户名 (好友申请消息里 v3 开头的字符串)"), - v4: str = Body("v4", description="Ticket (好友申请消息里 v4 开头的字符串)"), - scene: int = Body(30, description="申请方式 (好友申请消息里的 scene)")) -> dict: - """通过好友申请 - - Args: - v3 (str): 加密用户名 (好友申请消息里 v3 开头的字符串) - v4 (str): Ticket (好友申请消息里 v4 开头的字符串) - scene: 申请方式 (好友申请消息里的 scene) - - Returns: - int: 1 为成功,其他失败 - """ - ret = self.wcf.accept_new_friend(v3, v4, scene) - return {"status": ret, "message": "成功"if ret == 1 else "失败"} - - def add_chatroom_members(self, - roomid: str = Body("xxxxxxxx@chatroom", description="待加群的 id"), - wxids: str = Body("wxid_xxxxxxxxxxxxx", description="要加到群里的 wxid,多个用逗号分隔")) -> dict: - """添加群成员 - - Args: - roomid (str): 待加群的 id - wxids (str): 要加到群里的 wxid,多个用逗号分隔 - - Returns: - int: 1 为成功,其他失败 - """ - ret = self.wcf.add_chatroom_members(roomid, wxids) - return {"status": ret, "message": "成功"if ret == 1 else "失败"} - - def invite_chatroom_members(self, - roomid: str = Body("xxxxxxxx@chatroom", description="待加群的 id"), - wxids: str = Body("wxid_xxxxxxxxxxxxx", description="要加到群里的 wxid,多个用逗号分隔")) -> dict: - """邀请群成员 - - Args: - roomid (str): 待加群的 id - wxids (str): 要加到群里的 wxid,多个用逗号分隔 - - Returns: - int: 1 为成功,其他失败 - """ - ret = self.wcf.invite_chatroom_members(roomid, wxids) - return {"status": ret, "message": "成功"if ret == 1 else "失败"} - - def del_chatroom_members(self, - roomid: str = Body("xxxxxxxx@chatroom", description="群的 id"), - wxids: str = Body("wxid_xxxxxxxxxxxxx", description="要删除的 wxid,多个用逗号分隔")) -> dict: - """删除群成员 - - Args: - roomid (str): 群的 id - wxids (str): 要删除的 wxid,多个用逗号分隔 - - Returns: - int: 1 为成功,其他失败 - """ - ret = self.wcf.del_chatroom_members(roomid, wxids) - return {"status": ret, "message": "成功"if ret == 1 else "失败"} - - def receive_transfer(self, - wxid: str = Body("wxid_xxxxxxxxxxxxx", description="转账消息里的发送人 wxid"), - transferid: str = Body("transferid", description="转账消息里的 transferid"), - transactionid: str = Body("transactionid", description="转账消息里的 transactionid")) -> dict: - """接收转账 - - Args: - wxid (str): 转账消息里的发送人 wxid - transferid (str): 转账消息里的 transferid - transactionid (str): 转账消息里的 transactionid - - Returns: - int: 1 为成功,其他失败 - """ - ret = self.wcf.receive_transfer(wxid, transferid, transactionid) - return {"status": ret, "message": "成功"if ret == 1 else "失败"} - - def refresh_pyq(self, id: int = Query(0, description="开始 id,0 为最新页")) -> dict: - """刷新朋友圈 - - Args: - id (int): 开始 id,0 为最新页 - - Returns: - int: 1 为成功,其他失败 - """ - ret = self.wcf.refresh_pyq(id) - return {"status": ret, "message": "成功"if ret == 1 else "失败"} - - def decrypt_image(self, - src: str = Body("C:\\...", description="加密的图片路径,从图片消息中获取"), - dst: str = Body("C:\\...", description="解密的图片路径")) -> dict: - """解密图片: - - Args: - src (str): 加密的图片路径 - dst (str): 解密的图片路径 - - Returns: - bool: 是否成功 - """ - ret = self.wcf.decrypt_image(src, dst) - return {"status": ret, "message": "成功"if ret else "废弃,请使用 save-image"} - - def download_attachment(self, - id: int = Body("0", description="消息中的id"), - thumb: str = Body("C:/...", description="消息中的 thumb"), - extra: str = Body("C:/...", description="消息中的 extra")) -> dict: - """下载附件(图片、视频、文件) - - Args: - id (int): 消息中 id - thumb (str): 消息中的 thumb - extra (str): 消息中的 extra - - Returns: - str: 成功返回存储路径;空字符串为失败,原因见日志。 - """ - ret = self.wcf.download_attach(id, thumb, extra) - if ret: - return {"status": 0, "message": "成功", "data": {"path": ret}} - - return {"status": -1, "message": "废弃,请使用 save-image"} - - def download_image(self, - id: int = Body("0", description="消息中的id"), - extra: str = Body("C:/...", description="消息中的 extra"), - dir: str = Body("C:/...", description="保存图片的目录"), - timeout: int = Body("30", description="超时时间(秒)")) -> dict: - """下载图片 - - Args: - id (int): 消息中 id - extra (str): 消息中的 extra - dir (str): 存放图片的目录 - timeout (int): 超时时间(秒) - - Returns: - str: 成功返回存储路径;空字符串为失败,原因见日志。 - """ - ret = self.wcf.download_image(id, extra, dir, timeout) - if ret: - return {"status": 0, "message": "成功", "data": {"path": ret}} - - return {"status": -1, "message": "失败,原因见日志"} - - def get_audio_msg(self, - id: int = Body("0", description="消息中的id"), - dir: str = Body("C:/...", description="保存语音的目录"), - timeout: int = Body("30", description="超时时间(秒)")) -> dict: - """保存语音 - - Args: - id (int): 消息中 id - dir (str): 存放图片的目录 - timeout (int): 超时时间(秒) - - Returns: - str: 成功返回存储路径;空字符串为失败,原因见日志。 - """ - ret = self.wcf.get_audio_msg(id, dir, timeout) - if ret: - return {"status": 0, "message": "成功", "data": {"path": ret}} - - return {"status": -1, "message": "失败,原因见日志"} - - def get_chatroom_members(self, roomid: str = Query("xxxxxxxx@chatroom", description="群的 id")) -> dict: - """获取群成员 - - Args: - roomid (str): 群的 id - - Returns: - List[dict]: 群成员列表 - """ - ret = self.wcf.get_chatroom_members(roomid) - return {"status": 0, "message": "成功", "data": {"members": ret}} - - def get_alias_in_chatroom(self, wxid: str = Query("wxid_xxxxxxxxxxxxx", description="wxid"), - roomid: str = Query("xxxxxxxx@chatroom", description="群的 id")) -> dict: - """获取群成员名片 - - Args: - roomid (str): 群的 id - wxid (str): wxid - - Returns: - str: 名片 - """ - ret = self.wcf.get_alias_in_chatroom(wxid, roomid) - return {"status": 0, "message": "成功", "data": {"alias": ret}} diff --git a/clients/http/wcfhttp/main.py b/clients/http/wcfhttp/main.py deleted file mode 100644 index 3c5f007..0000000 --- a/clients/http/wcfhttp/main.py +++ /dev/null @@ -1,54 +0,0 @@ -#! /usr/bin/env python3 -# -*- coding: utf-8 -*- - -import logging -import argparse - -import uvicorn -from wcferry import Wcf -from wcfhttp import Http, __version__ - - -def main(): - parse = argparse.ArgumentParser() - parse.add_argument("-v", "--version", action="version", version=f"{__version__}") - parse.add_argument("--wcf_host", type=str, default=None, help="WeChatFerry 监听地址,默认本地启动监听 0.0.0.0") - parse.add_argument("--wcf_port", type=int, default=10086, help="WeChatFerry 监听端口 (同时占用 port + 1 端口),默认 10086") - parse.add_argument("--wcf_debug", type=bool, default=True, help="是否打开 WeChatFerry 调试开关") - parse.add_argument("--host", type=str, default="0.0.0.0", help="wcfhttp 监听地址,默认监听 0.0.0.0") - parse.add_argument("--port", type=int, default=9999, help="wcfhttp 监听端口,默认 9999") - parse.add_argument("--cb", type=str, default="", help="接收消息回调地址") - - logging.basicConfig(level="INFO", format="%(asctime)s %(message)s") - args = parse.parse_args() - cb = args.cb - if not cb: - logging.warning("没有设置接收消息回调,消息直接通过日志打印;请通过 --cb 设置消息回调") - logging.warning(f"回调接口规范参考接收消息回调样例:http://{args.host}:{args.port}/docs") - - wcf = Wcf(args.wcf_host, args.wcf_port, args.wcf_debug) - home = "https://github.com/lich0821/WeChatFerry" - qrcodes = """ - - - - - - - - - - - - -
碲矿赞赏
后台回复 WeChatFerry 加群交流如果你觉得有用
""" - http = Http(wcf=wcf, - cb=cb, - title="WeChatFerry HTTP 客户端", - description=f"Github: WeChatFerry{qrcodes}",) - - uvicorn.run(app=http, host=args.host, port=args.port) - - -if __name__ == "__main__": - main()