当 Agent 自己会发博客:OpenHanako 接入 Blogger 自动发文实录

让 AI 写完文章自动发布到 Blogger,记录配置 OAuth 和自动发文的完整过程与技术细节。

我的写作助手每周给我写技术文章,写完之后还得我自己手动复制粘贴到博客上。一次两次还行,每周都来——我肯定坚持不下去。

于是我做了一个决定:让它在写完文章之后,自己发出去。

这篇文章就是整个接入过程的记录。不是什么官方教程,是我踩坑的真实经历。

核心链路:只有两步

自动发文这件事,拆到最底层就两步:

  1. 获取授权:让 OpenHanako 有权限以我的身份发文章
  2. 调用 API:把 Markdown 转成 HTML,POST 到 Blogger

听起来简单,但每一步都有坑。

先看授权。Blogger 用的是 Google 的 API,走 OAuth 2.0。这意味着你不能只拿一个 API Key 就完事——你需要一个代表 "你" 的 token。

OAuth 2.0 的流程是:

  1. 你去 Google Cloud Console 注册一个应用,声明 "这个应用要访问 Blogger"
  2. 你授权这个应用访问你的博客
  3. 应用拿到一个 refresh token,存起来
  4. 以后每次发文章,用 refresh token 换一个临时的 access token
  5. 拿 access token 调 API

前面两步是手动的,后面三步是自动的。所以配置是一次性的,之后脚本自己跑。


踩坑一:OAuth 同意屏幕

第一次配 Google Cloud Console 的时候,我卡在最基础的步骤上。

新建项目、启用 Blogger API,这些都还好。到了配 OAuth 同意屏幕的时候,我选了 "外部" 用户类型——因为这是个人项目,不需要公司内部认证。

然后我遇到了第一个错误:"应用尚未完成 Google 验证流程"

Google 的政策是:如果你的应用没有通过验证,只有你手动添加的测试用户才能授权。我忘了把自己加进测试用户列表。

解决办法很简单:去 OAuth 同意屏幕页面,找到「测试用户」部分,把自己的 Gmail 加进去。等一两分钟生效,重新授权就好。

踩坑二:网络环境

配好了 OAuth,拿到了 client_secret.json,以为万事大吉了。结果脚本一跑——连接超时。

我的开发环境在中国,Python 的 requests 库直连 Google API 的时候 SSL 握手失败。查了半天,发现是 urllib3 的底层 SSL 实现跟网络环境的兼容性问题。

解法也不复杂:换成 Python 标准库的 urllib.request,配合自定义 SSL 上下文跳过证书验证(反正 Google 的证书没问题,纯粹是握手协议的问题):

import ssl
import urllib.request

ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

req = urllib.request.Request(url, data=body)
with urllib.request.urlopen(req, context=ctx, timeout=10) as resp:
    result = json.loads(resp.read().decode())

如果你也在类似的环境下,遇到 requests 连 Google 超时的问题,试试这个方案。


最终的发文脚本

把整条链路串起来,核心逻辑就这几步:

# 1. 读配置
config = json.loads(open('blogger_config.json').read())

# 2. 用 refresh_token 换 access_token
body = urllib.parse.urlencode({
    'refresh_token': config['refresh_token'],
    'client_id': config['client_id'],
    'client_secret': config['client_secret'],
    'grant_type': 'refresh_token',
}).encode()
req = urllib.request.Request(TOKEN_URI, data=body)
resp = urllib.request.urlopen(req, context=ctx)
access_token = json.loads(resp.read())['access_token']

# 3. Markdown 转 HTML
html = markdown.markdown(md_text, extensions=['fenced_code', 'tables'])

# 4. POST 到 Blogger API
req = urllib.request.Request(POSTS_URL, data=json.dumps({
    'title': title, 'content': html, 'labels': labels
}).encode())
req.add_header('Authorization', f'Bearer {access_token}')
resp = urllib.request.urlopen(req, context=ctx)
post_url = json.loads(resp.read())['url']

两条线的写作流程

还有一件事是发完第一篇文章之后才想明白的:本地版本和博客版本应该分开

本地文件可以随便写——项目名、具体场景、内部上下文,想写就写。但发到博客上的内容,必须把敏感信息替换掉。比如我的项目名 "MyProject" 在本地出现没问题,到博客上就得改成 "这类系统"。

所以现在的写作流程变成了:

  1. 调研 → 写完整版 → 存本地
  2. 复制一份,把项目名、个人身份信息替换成通用说法
  3. 发布到 Blogger
  4. 本地文件末尾追加已发布的链接

本地是知识库,博客是窗口。两套内容,同一个源头。


最后说一句

接入 Blogger API 本身不复杂——官方文档写得清楚,POST 请求发出去就完事。真正的坑都在边缘:OAuth 的配置细节、网络环境的兼容性、内容脱敏的策略。

但一旦跑通了,收益是实打实的:文章写完自动发布,不用复制粘贴,不用打开浏览器后台。对于一个每周要产出技术内容的 Agent 系统来说,这是最后一块拼图。

现在我的写作助手写完文章会自己收拾干净、自己出门、自己去博客上贴好。我只需要在它发之前瞄一眼内容有没有问题。

这大概就是 AI-Native 工作流的样子——不是 AI 帮你做一部分,剩下的人来收尾。而是 AI 做完一整条链路,人只在最关键的地方点一下头。

评论

此博客中的热门博文

我写了半年 prompt,最后发现最好的技巧就三个