1. 为什么要把公众号发布交给 Codex 这类 AI 智能体
公众号文章自动发布这件事,真正麻烦的从来不是写,而是写完之后那一串机械动作:复制正文、调字号、配图、填摘要、选封面、点保存、再点群发。一个人偶尔发一篇还能忍,一旦要日更或者多账号运营,这些动作就会把创作时间切得稀碎。我试过用纯脚本硬怼公众号接口,结果卡在素材上传和草稿字段拼装上,调了两天才跑通一篇,后来换成 Codex 这类 AI 智能体来编排,整个链路才顺起来。
Codex 在这里扮演的角色,不是替你写文章的“代笔”,而是一个能读文件、能跑命令、能调 HTTP 接口的执行体。你把目标用自然语言讲清楚,它自己拆步骤:先拿热点、再生成正文、然后调公众号 API 建草稿、最后挂一个定时任务。对小白来说,这比啃微信官方文档友好太多,因为文档里那些 access_token 刷新、thumb_media_id 上传、draft/add 字段嵌套,Codex 会帮你拼。
这篇要解决的核心检索词就是Codex 公众号文章自动发布,顺带覆盖 AI 智能体做自动化任务、公众号 API 接入、定时推送这几个长尾。适合三类人:一个人运营多个号的独立创作者、需要统一发布规范的内容团队、以及想把重复发布流程沉淀成可复用技能的技术同学。下面从环境准备讲到定时任务落地,每一步都给可复制的配置和命令,你跟着敲就能跑通。
需要先说明一个边界:公众号的“发布”分两步,一步是建草稿(draft/add),一步是群发或发布(freepublish/submit)。自动化只做到草稿箱,最终点发布仍然建议人工确认,这既是平台规则要求,也能避免误发。Codex 的价值在于把“准备到最后一步”这件事做扎实。
2. TaoToken 前置准备:给 Codex 配一个稳定的模型入口
Codex 本身是执行框架,它背后要调大模型来理解任务、生成文章、写调用代码。如果你直接用官方入口,网络和额度这两件事就够折腾半天。我现在的做法是给 Codex 配一个兼容 OpenAI 协议的模型入口,TaoToken 就是干这个的,官网在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 地址是 https://taotoken.net/api ,注意 API 这条不带 UTM 参数,配置时别抄错。
为什么要在 Codex 前面加这一层?因为 Codex 的很多配置项(base_url、api_key、model)都遵循 OpenAI 的字段命名,只要入口兼容这个协议,Codex 就能无缝接上。你不需要改 Codex 的源码,也不用装额外插件,改一个配置文件就行。对公众号自动发布这种任务来说,模型要频繁处理长文本(生成 1000 字文章)和结构化输出(拼 draft/add 的 JSON),一个稳定的入口能省掉大量重试。
具体操作分三步。第一步,去控制台建一个 API Key,入口是 https://taotoken.net/console/api-keys ,建完复制那串 sk- 开头的字符串,只显示一次,记得存好。第二步,确认你要用的模型 ID,公众号文章生成建议用长上下文、中文表达顺的模型,模型对话页面 https://taotoken.net/models 可以逐个试,找到合适的把 Model ID 记下来。第三步,把 Base URL、Key、Model ID 这三件套写进 Codex 的配置。
这里有个坑要提前说:Codex 的配置分全局和项目级,公众号项目建议用项目级配置,避免污染你其他编码任务。项目根目录下建.codex/config.toml(不同版本路径可能是~/.codex/config.toml,以你本地为准),内容长这样:
# .codex/config.toml model = "你的Model ID" model_provider = "taotoken" [model_providers.taotoken] name = "TaoToken" base_url = "https://taotoken.net/api" env_key = "TAOTOKEN_API_KEY" wire_api = "chat"然后在系统环境变量里设置TAOTOKEN_API_KEY,Linux/macOS 用export TAOTOKEN_API_KEY="sk-你的key",Windows 用setx TAOTOKEN_API_KEY "sk-你的key"。这样 Codex 启动时会自动读取,不用把 Key 硬编码进文件,安全一些。
如果你用的是 Cline 或 Claude Code 这类工具,配置逻辑一样,都是填 Base URL、Key、Model ID 三件套。Cline 的 MCP 配置里,把 provider 指向自定义 OpenAI 兼容端点即可。Codex 的 auth.json 如果存在,也要确认里面的 base_url 指向 https://taotoken.net/api ,别指向默认地址。配完之后跑一句codex --version确认能起来,再让它随便生成一段文字,能出结果就说明模型入口通了。
这一步做完,Codex 就有了“大脑”,接下来才是公众号 API 的对接。
3. 可复制配置:公众号 API 对接与 Codex 任务文件
公众号 API 对接的核心是三样东西:AppID、AppSecret、IP 白名单。前两个在公众号后台“设置与开发 - 基本配置”里拿,IP 白名单在同一个页面配置。Codex 要调接口,就必须让请求从白名单 IP 发出,否则会报 40164 错误(invalid ip)。
先让 Codex 帮你理清步骤。在项目目录里打开 Codex,输入这段提示词:
我现在要做公众号文章自动发布。目标:Codex 抓取最新 AI 热点, 生成一篇 1000 字以内的文章,调用公众号 API 发到草稿箱, 最后做成每天早上 8 点自动执行的定时任务。 请先给我完整的实现步骤和需要的文件清单。Codex 会生成一个任务规划,通常包括fetch_hotspot.py(抓热点)、gen_article.py(生成文章)、wechat_draft.py(调公众号接口)、config.json(存密钥)、schedule.md(定时任务说明)。文件多了别慌,逐个看。
接下来配置密钥。在项目根目录建config.json,注意这个文件要加进.gitignore,别提交到仓库:
{ "wechat": { "appid": "wx你的appid", "appsecret": "你的appsecret", "draft_api": "https://api.weixin.qq.com/cgi-bin/draft/add", "token_api": "https://api.weixin.qq.com/cgi-bin/token" }, "model": { "base_url": "https://taotoken.net/api", "model_id": "你的Model ID" } }公众号接口调用有个关键点:access_token 有效期 7200 秒,且获取次数有限,必须缓存。Codex 生成的wechat_draft.py里通常会有这段逻辑,你要检查它是不是把 token 存到了本地文件并判断过期时间。一个可用的 token 获取片段长这样:
import json, time, requests def get_access_token(appid, appsecret, cache_file="token_cache.json"): try: with open(cache_file) as f: cache = json.load(f) if cache.get("expires_at", 0) > time.time() + 300: return cache["access_token"] except FileNotFoundError: pass url = "https://api.weixin.qq.com/cgi-bin/token" params = {"grant_type": "client_credential", "appid": appid, "appsecret": appsecret} resp = requests.get(url, params=params, timeout=10).json() if "access_token" not in resp: raise RuntimeError(f"获取 token 失败: {resp}") cache = {"access_token": resp["access_token"], "expires_at": time.time() + resp.get("expires_in", 7200)} with open(cache_file, "w") as f: json.dump(cache, f) return cache["access_token"]建草稿的接口是draft/add,请求体里articles是数组,每篇要有title、author、digest、content、thumb_media_id、need_open_comment等字段。其中thumb_media_id是封面图的素材 ID,必须先调material/add_material上传图片拿到。这一步最容易漏,漏了会报 40007(invalid media_id)。Codex 生成的代码里如果没处理封面,你要补一句提示词让它加上。
IP 白名单怎么拿?让 Codex 给你一个查公网 IP 的命令,Linux/macOS 用curl ifconfig.me,Windows 用curl ipinfo.io/ip。拿到 IP 后,去公众号后台“基本配置 - IP 白名单”里填进去。注意有些云服务器出口 IP 和入口 IP 不同,如果报 40164,就把两个都加上。
配置阶段还有个细节:公众号草稿的content字段是 HTML,不是 Markdown。Codex 生成的文章如果是 Markdown,要让它转成 HTML 再塞进去,否则草稿里会显示一堆##和**。你可以在提示词里明确写“content 字段请输出公众号兼容的内联样式 HTML”。
4. 验证请求:跑通一次完整的草稿发布
配置齐了,先别急着上定时任务,手动跑一次完整链路,确认每一步都通。给 Codex 的提示词:
AppID、AppSecret、IP 白名单都配好了。 现在抓取最新的 AI 热点,生成一篇 1000 字以内的公众号文章, 标题自拟要有吸引力,排版简约清新,转成内联样式 HTML, 调用 draft/add 发到我的草稿箱。执行前先告诉我你会调哪些接口。Codex 会先列接口清单:cgi-bin/token拿 token、cgi-bin/material/add_material传封面、cgi-bin/draft/add建草稿。确认无误后让它执行。执行过程中它会打印每一步的返回,你要盯这几个字段:token 返回里有没有access_token、素材上传返回里有没有media_id、草稿返回里errcode是不是 0。
如果草稿返回{"errcode":0,"errmsg":"ok"},说明成功了。去公众号后台“草稿箱”看,应该有一篇新文章。检查三件事:标题对不对、正文排版有没有乱、封面图在不在。如果正文里出现 HTML 标签裸露,说明 content 转义有问题;如果封面空白,说明 thumb_media_id 没传对。
验证阶段我建议加一个“干跑”模式,就是先生成文章存本地,不调接口,确认内容质量后再发。Codex 的提示词可以这样写:
先不要调公众号接口,把生成的文章和 HTML 存到本地 article_preview.html, 我确认后再发草稿箱。这样能避免反复调接口触发频率限制。公众号草稿接口有调用频次限制,短时间内反复调可能被限流,报 45009(api freq out of limit)。真遇到了就等几分钟再试,或者把 token 缓存做好,减少 token 接口调用。
跑通一次之后,把整个流程固化成脚本。Codex 会生成run_publish.py,你手动执行python run_publish.py能复现成功,才算真正跑通。这一步别偷懒,因为定时任务本质就是定时执行这个脚本,脚本本身不稳定,定时只会放大问题。
验证成功的标志很明确:草稿箱出现文章、排版正常、封面正常、日志里没有 error。到这一步,单次发布链路就闭环了。
5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth
自动化链路跑起来,报错是常态。下面这几个是我和身边同学踩过的坑,对照着查能省不少时间。
401 与 40164:401 通常是模型入口的 Key 不对或过期,检查TAOTOKEN_API_KEY环境变量有没有生效,echo $TAOTOKEN_API_KEY看输出。40164 是公众号的 IP 白名单问题,报错原文是invalid ip xxx, not in whitelist,把报错里的 IP 加到公众号后台白名单即可。注意服务器多网卡时出口 IP 可能变,用curl ifconfig.me确认当前出口。
local proxy failed:这个报错一般出现在 Codex 或底层 HTTP 库尝试走本地代理时。检查环境变量里有没有HTTP_PROXY、HTTPS_PROXY、ALL_PROXY,有的话先unset掉再跑。有些工具会读~/.curlrc或系统代理设置,一并检查。公众号接口和模型入口都建议直连,别挂代理,否则容易出现连接超时或证书错误。
reading choices 报错:这个通常出现在解析模型返回时,报错类似KeyError: 'choices'或list index out of range。原因是模型返回结构和你代码里取字段的路径不一致,比如返回的是{"data": {...}}而你按resp["choices"][0]取。解决办法是先把原始返回print(json.dumps(resp, ensure_ascii=False))打出来,看清结构再改取值路径。Codex 生成的代码如果没做异常兜底,让它补一个if "choices" not in resp的判断。
OAuth 相关报错:如果你用 Claude Code 或某些 CLI 工具,可能会遇到 OAuth token 过期或回调失败。这类工具如果支持自定义端点,优先用 API Key 模式而不是 OAuth,配置更简单。Codex 的 auth.json 里如果残留了旧的 OAuth 字段,清掉,只保留 base_url 和 api_key。
thumb_media_id 报 40007:封面素材 ID 无效。检查上传素材时用的类型是不是image,返回的media_id有没有正确传给 draft/add。素材上传接口是material/add_material?type=image,注意是 POST 且用 multipart 传文件。
content 字段报 40008 或排版乱:content 必须是 HTML 字符串,且不能有公众号不支持的标签(如<script>)。把 Markdown 转 HTML 后,再过滤一遍危险标签。Codex 生成的转换代码如果用的是通用 markdown 库,记得加白名单。
排查的通用思路是:先看报错原文,再去公众号官方文档搜 errcode,最后让 Codex 解释这个错误并给修复方案。Codex 对这类接口报错的解释通常挺准,把完整报错贴给它,它能直接定位到是哪一步的字段问题。
6. 定时任务落地与后续接入入口
单次跑通后,做定时任务。最简单的方式是用系统自带的 cron(Linux/macOS)或任务计划程序(Windows)。让 Codex 帮你生成 cron 配置:
把 run_publish.py 做成定时任务,每天早上 8 点执行, 日志输出到 logs/publish_$(date +%F).log。Linux 下 crontab 写法:
# 每天早上 8 点执行公众号自动发布 0 8 * * * cd /path/to/project && /usr/bin/python3 run_publish.py >> logs/publish_$(date +\%F).log 2>&1注意 cron 里的%要转义成\%,否则会被当成换行。另外 cron 执行时的环境变量和交互式 shell 不同,TAOTOKEN_API_KEY可能读不到,稳妥做法是在脚本里显式加载.env文件,或者把环境变量写进 crontab 顶部。
Windows 用任务计划程序,触发器设每天 8 点,操作选“启动程序”,程序填 python 路径,参数填脚本路径,起始位置填项目目录。日志重定向在 Windows 下用>>不太方便,可以在 Python 脚本里用 logging 模块写文件。
定时任务跑起来后,建议加一个失败通知。最简单的做法是脚本末尾判断退出码,非 0 就调一个 webhook 发消息。Codex 可以帮你写这段,提示词:“如果 run_publish.py 执行失败,调用 webhook 通知我,webhook 地址是 xxx”。
如果你想把发布流程沉淀成可复用的技能,Codex 支持把一套操作固化成 Skill,下次换个文章类型(比如产品周报、行业观察)直接复用,不用重新写提示词。这个属于进阶玩法,先把定时任务跑稳再说。
后续要扩展的话,几个入口可以收藏:模型对话 https://taotoken.net/models 用来试不同模型对中文排版的适配;Coding Plan https://taotoken.net/coding-plan 适合长期跑 Agent 任务的场景,额度更划算;API Keys 管理 https://taotoken.net/console/api-keys 用来轮换密钥;接入文档 https://taotoken.net/doc 里有各工具的配置示例。公众号这边,草稿箱审查这一步别省,自动化只负责准备,发布权始终留给人。