Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Opencode Watch Notify

Opencode 插件:当 AI 任务完成或需要权限批准时,自动通过 Gotify / 桌面通知 / Webhook / 邮件 / 自定义命令 推送消息。


目录


快速开始

1. 安装插件

# 复制插件到 Opencode 的全局插件目录
cp plugin/webhook-notify.js ~/.config/opencode/plugins/

# 重启 Opencode 即可自动加载(无需修改任何配置文件)

2. 写配置文件

在当前目录或 ~/.config/opencode/ 下创建 watch-notify.json

{
  "gotify": {
    "url": "http://你的服务器:8080",
    "token": "你的应用Token"
  }
}

3. 完成

重启 Opencode,执行任务。任务结束后 Gotify 自动收到通知。


安装

# 复制插件到 Opencode 插件目录
cp plugin/webhook-notify.js ~/.config/opencode/plugins/

插件会自动加载,无需在 opencode.json 中声明


配置文件

配置文件是 watch-notify.json,支持 5 种推送渠道。每个渠道是 JSON 的顶级字段,填了就启用,不填就不用。

配置查找顺序

  1. 当前工作目录 watch-notify.json — 项目级配置,优先级最高
  2. 全局目录 ~/.config/opencode/watch-notify.json — 用户级配置
  3. 都不存在 — 使用默认行为(写日志到 /tmp/opencode-notify.log

Gotify 推送

Gotify 是一个自托管的消息推送服务,支持 Android、Web 等客户端。最推荐的方式,配置最简单。

{
  "gotify": {
    "url": "http://192.168.1.100:8080",
    "token": "Axxxxxxxxxxxxxx",
    "priority": 5
  }
}
字段 必填 说明 默认值
url Gotify 服务器地址
token 应用 Token(在 Gotify Web 界面创建应用获取)
priority 消息优先级 1-10 5

桌面通知

{
  "desktop": true
}
  • Linux:使用 notify-send(一般桌面环境已自带)
  • macOS:使用 osascript 原生通知
  • Windows:暂不支持

Webhook 推送

{
  "webhook": {
    "url": "https://hooks.example.com/notify",
    "method": "POST",
    "headers": {
      "Authorization": "Bearer xxxxx"
    }
  }
}
字段 必填 说明 默认值
url Webhook 地址
method HTTP 方法 POST
headers 自定义请求头 {}
template 请求体模板(JSON 对象,支持变量占位符)
timeout 超时时间(毫秒) 10000

SMTP 邮件推送

{
  "smtp": {
    "host": "smtp.gmail.com",
    "port": 587,
    "secure": false,
    "user": "your@gmail.com",
    "pass": "你的应用专用密码",
    "from": "your@gmail.com",
    "to": ["admin@example.com"],
    "subject": "$TITLE"
  }
}
字段 必填 说明 默认值
host SMTP 服务器地址
port 端口 587
secure true=直接 SSL,false=STARTTLS false
user 登录用户名
pass 登录密码或应用专用密码
from 发件人地址 user
to 收件人(字符串或字符串数组)
subject 邮件主题 $TITLE

Gmail 用户请注意:密码需要使用"应用专用密码",而不是 Gmail 登录密码。如何生成应用专用密码


自定义命令

{
  "cmd": "curl -d '通知: $TITLE' http://my-bot/api"
}

通过 /bin/sh -c 执行任意命令,支持所有变量占位符。

字段 必填 说明 默认值
cmd Shell 命令
cmdTimeout 超时(毫秒) 30000

同时使用多个渠道

多个渠道可以同时启用,全部生效:

{
  "gotify": {
    "url": "http://192.168.1.100:8080",
    "token": "Axxxxxxxxxxxxxx",
    "priority": 8
  },
  "desktop": true,
  "webhook": {
    "url": "https://hooks.example.com/notify"
  },
  "smtp": {
    "host": "smtp.gmail.com",
    "port": 587,
    "user": "your@gmail.com",
    "pass": "your-app-password",
    "to": "admin@example.com"
  },
  "cmd": "echo 任务完成: $TITLE >> /tmp/my-log.txt"
}

变量占位符

cmd 命令中可以使用以下占位符,插件会自动替换为实际值:

变量 说明 示例值
$SOURCE 来源名称 opencode
$SOURCE_LABEL 来源显示名 Opencode
$TITLE 通知标题(由人格档案决定) Opencode 任务完成
$DETAILS 通知详情 项目:my-project\n会话:代码重构\n模型:gpt-4o
$SESSION_ID 会话 ID cm-xxxxx
$TTY 调用者终端号 /dev/pts/0
$NICKNAME 自定义称呼(见下文) 主任
$EMOJI_PREFIX 自定义表情前缀(见下文) 🔔
$SIGNATURE 自定义签名字(见下文) —— 自动通知
$DIRECTORY 项目完整路径 /home/user/projects/my-project
$PROJECT 项目名(路径最后一级) my-project

自定义功能

watch-notify.json 顶层添加以下字段,即可定制通知内容:

称呼 / 表情 / 签名

{
  "nickname": "主任",
  "emojiPrefix": "🔔",
  "signature": "—— 来自 Opencode 机器人"
}
字段 效果 模板变量
nickname 自动拼接到标题前缀并覆盖人格默认称呼 $NICKNAME
emojiPrefix 自动拼接到标题最前面 $EMOJI_PREFIX
signature 自动追加到通知详情底部 $SIGNATURE

标题拼接规则

表情前缀 + 自定义称呼 + 人格标题

默认人格示例:
🔔 主任 Opencode 任务完成
(没配 emoji)主任 Opencode 任务完成
(都没配)Opencode 任务完成

nickname 会覆盖人格默认称呼,并继续显示在标题中。

通知人格档案

通过顶层 persona 字段切换内置通知风格,影响标题、开场和收尾,但不会隐藏项目、会话、权限、问题等事实信息。未知值自动回退 default

{
  "persona": "emperor"
}
配置值 风格 默认称呼
default 默认版
boss 总裁版 总裁
heir_male 少爷版 少爷
heir_female 大小姐版 大小姐
emperor 皇上版 皇上
palace 宫廷版 主子

配合称呼组合示例:

{
  "persona": "boss",
  "nickname": "老许",
  "emojiPrefix": "🔔",
  "signature": "—— 自动通知"
}

项目忽略名单

配置后,匹配的项目不会触发任何通知:

{
  "ignoreProjects": ["temp-test", "/mnt/e/temp"]
}

匹配规则:同时支持完整路径和**项目名(basename)**匹配。


事件说明

插件监听 Opencode 的以下事件:

事件 触发时机
任务完成 AI 执行完任务进入 idle 状态
权限申请 AI 需要用户批准执行命令或访问文件
用户提问 AI 需要用户回答问题或做出选择

默认通知文案会区分三种状态:

  • 任务完成:标题以“Opencode 任务完成”开头,正文包含项目、会话和模型。
  • 权限申请:标题为“Opencode 需要你批准操作”,正文包含项目、权限、操作和会话。
  • 用户提问:标题为“Opencode 需要你回答问题”,正文包含项目、问题、选项和会话。

去重机制

  • 同一会话 5 秒内重复的 idle 事件只推送一次
  • 同一 permission ID 只会推送一次(避免重复弹窗)

开发日志

排查问题时可以开启开发日志:

export WATCH_NOTIFY_DEV=true

# 启动 Opencode 后,在另一个终端查看实时日志
tail -f /tmp/watch-notify-dev.log

项目结构

opencode-watch-notify/
├── AGENT.md                  # 项目说明(AI 阅读用)
├── README.md                 # 使用文档
├── plugin/
│   └── webhook-notify.js     # Opencode 通知插件(JSON 配置)
├── test/
    ├── test.js               # 单元测试
    ├── e2e-test.js           # 端到端模拟测试
    └── persona-test.js       # 通知人格测试

开发测试

# 运行全部单元测试
node test/test.js

# 启用开发日志运行测试
WATCH_NOTIFY_DEV=true node test/test.js

# 端到端模拟测试(模拟完整事件流)
node test/e2e-test.js

测试内容:

  1. 插件初始化 — 验证能正常加载
  2. permission 事件 — 权限申请触发通知
  3. idle 事件 — 任务完成触发通知
  4. 会话去重 — 5 秒内重复事件被过滤
  5. 权限去重 — 同一权限 ID 只发一次
  6. question 事件 — 用户提问触发通知
  7. 任务完成文案 — 标题与正文事实字段
  8. 权限申请文案 — 权限类型与操作说明
  9. 问题通知文案 — 问题与选项
  10. 自定义称呼/表情/签名 — 标题拼接与收尾签名
  11. 项目忽略名单 — 匹配项目不触发通知
  12. Gotify JSON 配置 — 从 JSON 文件读取 Gotify 配置
  13. 桌面通知 JSON 配置 — 从 JSON 文件读取桌面通知配置
  14. Webhook JSON 配置 — 从 JSON 文件读取 Webhook 配置
  15. 自定义命令 JSON 配置 — 从 JSON 文件读取命令配置
  16. 多渠道 JSON 配置 — 多个渠道同时生效

技术要点

  • 单文件自包含:插件逻辑在 webhook-notify.js 中,零外部依赖
  • 原生 SMTP:手写 SMTP 协议实现邮件发送,不依赖 nodemailer 等第三方库
  • Opencode 标准 API:使用 $ Bun Shell API、client.app.logclient.session.get
  • 事件驱动:监听 permission.askedpermission.updatedsession.idlesession.status
  • iOS 过滤:通过 MIMOCODE_IOS_SESSION_TITLE / OPENCODE_IOS_SESSION_TITLE 环境变量过滤 iOS Chat 会话
  • 优雅降级:单个推送渠道失败不影响其他渠道,失败信息记录到开发日志

许可证

MIT

About

opencode发送webhook 插件 可以搭配手环手表使用

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages