From 4f4ad99d49b4647a5a018100afabaec4314ee92c Mon Sep 17 00:00:00 2001 From: Pnant <73925474+Panniantong@users.noreply.github.com> Date: Wed, 4 Mar 2026 17:53:39 +0800 Subject: [PATCH] feat: add WeChat Official Account channel (#54) (#67) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New channel: wechat (微信公众号文章) - Backend: wechat-article-for-ai (Camoufox stealth browser) - Can read mp.weixin.qq.com article URLs → clean Markdown - Bypasses WeChat anti-bot detection via stealth Firefox - Doctor checks for camoufox package availability - SKILL.md updated with usage examples Co-authored-by: Panniantong --- agent_reach/channels/__init__.py | 2 ++ agent_reach/channels/wechat.py | 32 ++++++++++++++++++++++++++++++++ agent_reach/skill/SKILL.md | 19 ++++++++++++++++++- 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 agent_reach/channels/wechat.py diff --git a/agent_reach/channels/__init__.py b/agent_reach/channels/__init__.py index d1a8417..3e79dbd 100644 --- a/agent_reach/channels/__init__.py +++ b/agent_reach/channels/__init__.py @@ -19,6 +19,7 @@ from .xiaohongshu import XiaoHongShuChannel from .douyin import DouyinChannel from .linkedin import LinkedInChannel from .bosszhipin import BossZhipinChannel +from .wechat import WeChatChannel # Channel registry @@ -32,6 +33,7 @@ ALL_CHANNELS: List[Channel] = [ DouyinChannel(), LinkedInChannel(), BossZhipinChannel(), + WeChatChannel(), RSSChannel(), ExaSearchChannel(), WebChannel(), diff --git a/agent_reach/channels/wechat.py b/agent_reach/channels/wechat.py new file mode 100644 index 0000000..369d016 --- /dev/null +++ b/agent_reach/channels/wechat.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +"""WeChat Official Account articles — check if wechat-article-for-ai is available.""" + +import shutil +import subprocess +from .base import Channel + + +class WeChatChannel(Channel): + name = "wechat" + description = "微信公众号文章" + backends = ["wechat-article-for-ai (Camoufox)"] + tier = 2 + + def can_handle(self, url: str) -> bool: + from urllib.parse import urlparse + d = urlparse(url).netloc.lower() + return "mp.weixin.qq.com" in d or "weixin.qq.com" in d + + def check(self, config=None): + try: + import camoufox # noqa: F401 + except ImportError: + return "off", ( + "需要 wechat-article-for-ai。安装:\n" + " pip install camoufox[geoip] markdownify beautifulsoup4 httpx mcp\n" + " # 或完整安装:\n" + " git clone https://github.com/bzd6661/wechat-article-for-ai.git\n" + " cd wechat-article-for-ai && pip install -r requirements.txt\n" + " 详见 https://github.com/bzd6661/wechat-article-for-ai" + ) + return "ok", "可读取微信公众号文章(URL → Markdown)" diff --git a/agent_reach/skill/SKILL.md b/agent_reach/skill/SKILL.md index 2510e4a..dc11870 100644 --- a/agent_reach/skill/SKILL.md +++ b/agent_reach/skill/SKILL.md @@ -3,7 +3,7 @@ name: agent-reach description: > Give your AI agent eyes to see the entire internet. Install and configure upstream tools for Twitter/X, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu, - Douyin, LinkedIn, Boss直聘, RSS, and any web page — then call them directly. + Douyin, LinkedIn, Boss直聘, WeChat (微信公众号), RSS, and any web page — then call them directly. Use when: (1) setting up platform access tools for the first time, (2) checking which platforms are available, (3) user asks to configure/enable a platform channel. @@ -253,6 +253,23 @@ mcporter call 'bosszhipin.get_job_detail_tool(job_url: "https://www.zhipin.com/j Fallback: `curl -s "https://r.jina.ai/https://www.zhipin.com/job_detail/xxx"` +### 微信公众号 (wechat-article-for-ai) + +Uses Camoufox (stealth Firefox) to bypass WeChat's anti-bot detection and extract full article content. + +```bash +# Read a WeChat article (returns Markdown with images) +cd /path/to/wechat-article-for-ai && python3 main.py "https://mp.weixin.qq.com/s/ARTICLE_ID" + +# Batch convert multiple articles +python3 main.py "URL1" "URL2" "URL3" -o ./output + +# Run as MCP server (for AI agent integration) +python3 mcp_server.py +``` + +Note: WeChat articles require a real browser to render. Jina Reader and curl cannot read them. + ### RSS (feedparser) ```python