cc-notifier
v0.1.2
Published
Claude Code hook notifier for Feishu, WeCom, Ruliu, and generic webhooks.
Maintainers
Readme
cc-notifier
cc-notifier is a small Claude Code hook notifier. It sends notifications when Claude Code finishes a turn (Stop) or asks for tool permission (PermissionRequest).
Supported providers:
- Feishu bot webhook
- WeCom bot webhook
- Baidu IM / 如流 webhook
- Generic webhook
Requirements
- Node.js 18+
- Claude Code with hook support
- A bot/webhook URL from one of the supported providers
Install
For Claude Code hooks, global installation is recommended:
npm install -g cc-notifier
npx cc-notifier initis not recommended for hook installation because hooks may capture a temporarynpxcache path. Use a global install for a stable command path.
Quick start
Feishu
npm install -g cc-notifier
cc-notifier init --provider feishu --env FEISHU_BOT_WEBHOOK
export FEISHU_BOT_WEBHOOK="https://open.feishu.cn/open-apis/bot/v2/hook/..."
cc-notifier doctor
cc-notifier testBaidu IM / 如流
Simple setup, stores the webhook URL directly in ~/.cc-notifier/config.json:
npm install -g cc-notifier
cc-notifier init --provider ruliu --url 'https://apiin.im.baidu.com/api/msg/groupmsgsend?access_token=...' --yes
cc-notifier doctor
cc-notifier testSafer setup, stores only an environment variable reference in the config file:
npm install -g cc-notifier
export RULIU_BOT_WEBHOOK="https://apiin.im.baidu.com/api/msg/groupmsgsend?access_token=..."
cc-notifier init --provider ruliu --env RULIU_BOT_WEBHOOK --yes
cc-notifier doctor
cc-notifier test--env expects the environment variable name (RULIU_BOT_WEBHOOK), not the webhook URL itself. Use --url if you want to pass the webhook URL directly.
WeCom
npm install -g cc-notifier
cc-notifier init --provider wecom --env WECOM_BOT_WEBHOOK
export WECOM_BOT_WEBHOOK="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=..."
cc-notifier doctor
cc-notifier testGeneric webhook
npm install -g cc-notifier
cc-notifier init --provider webhook --env GENERIC_WEBHOOK_URL
export GENERIC_WEBHOOK_URL="https://example.com/webhook"
cc-notifier doctor
cc-notifier testcc-notifier test sends a real test notification to enabled providers.
Persist webhook environment variables
Shell export only affects the current terminal session. To persist your webhook URL, add it to your shell startup file.
For zsh:
echo 'export FEISHU_BOT_WEBHOOK="https://open.feishu.cn/open-apis/bot/v2/hook/..."' >> ~/.zshrc
source ~/.zshrcFor bash:
echo 'export FEISHU_BOT_WEBHOOK="https://open.feishu.cn/open-apis/bot/v2/hook/..."' >> ~/.bashrc
source ~/.bashrcFor fish:
set -Ux FEISHU_BOT_WEBHOOK "https://open.feishu.cn/open-apis/bot/v2/hook/..."What init changes
cc-notifier init does two things:
Writes or merges the global config at:
~/.cc-notifier/config.jsonInstalls Claude Code hooks into:
~/.claude/settings.json
It preserves unrelated Claude Code settings and hooks.
Config files
cc-notifier loads config from:
- Built-in defaults
- Global config:
~/.cc-notifier/config.json - Project override:
.cc-notifier.json, searched upward from the hook working directory
Project config overrides global config. Arrays replace arrays, while objects are deep-merged.
Example global config:
{
"enabled": true,
"notifyOn": ["Stop", "PermissionRequest"],
"summary": {
"enabled": true,
"maxUserChars": 120,
"maxAssistantChars": 240
},
"quietHours": {
"enabled": false,
"timezone": "local",
"ranges": [{ "start": "22:00", "end": "08:00" }],
"behavior": "suppress"
},
"dedupe": {
"enabled": true,
"windowSeconds": 300
},
"template": {
"title": "✅ Claude 完成:{{projectName}}",
"text": "Project: {{projectName}}\nPath: {{cwd}}\n\nUser:\n{{lastUserMessage}}\n\nClaude:\n{{lastAssistantSummary}} 等待下一步"
},
"providers": [
{
"type": "feishu",
"enabled": true,
"webhookUrl": "env:FEISHU_BOT_WEBHOOK"
}
]
}Secrets should usually be referenced through environment variables using the env:NAME syntax. Avoid committing real webhook URLs to project repositories.
When running cc-notifier init, choose one of these modes:
# Simple: store the webhook URL directly in ~/.cc-notifier/config.json
cc-notifier init --provider ruliu --url "https://apiin.im.baidu.com/api/msg/groupmsgsend?access_token=..."
# Safer: store only an environment variable reference in config
export RULIU_BOT_WEBHOOK="https://apiin.im.baidu.com/api/msg/groupmsgsend?access_token=..."
cc-notifier init --provider ruliu --env RULIU_BOT_WEBHOOK
# Incorrect: --env is not for webhook URLs
cc-notifier init --provider ruliu --env "https://apiin.im.baidu.com/api/msg/groupmsgsend?access_token=..."Change webhook or provider
To change only the webhook URL, update the environment variable:
export FEISHU_BOT_WEBHOOK="https://open.feishu.cn/open-apis/bot/v2/hook/new-token"
cc-notifier doctorTo switch or add a provider, run init again:
cc-notifier init --provider ruliu --env RULIU_BOT_WEBHOOKTo edit config manually:
cc-notifier config
vim ~/.cc-notifier/config.jsonCommands
cc-notifier init [--provider feishu|wecom|ruliu|webhook (--env ENV_NAME | --url WEBHOOK_URL)] [--yes]
cc-notifier uninstall
cc-notifier doctor
cc-notifier test
cc-notifier config
cc-notifier hook --event Stop|PermissionRequestdoctor
Checks whether:
- Claude Code hooks are installed
- Hook script paths still exist
- Global config exists
- Required webhook environment variables are set
- At least one provider is enabled
If doctor reports a stale hook path after moving or reinstalling the package, run:
cc-notifier inituninstall
Removes only cc-notifier hooks from Claude Code settings. It preserves unrelated hooks.
cc-notifier uninstallNotification behavior
Stop
Sends the completion template and, when available, includes a short summary from the Claude Code transcript:
✅ Claude 完成:{{projectName}}
Project: {{projectName}}
Path: {{cwd}}
User:
{{lastUserMessage}}
Claude:
{{lastAssistantSummary}} 等待下一步PermissionRequest
Sends a safe summary of the permission request, such as project, path, tool name, target file/path, or a short command summary.
It intentionally does not:
- include raw hook payloads
- output
hookSpecificOutput - approve or deny permissions remotely
- change Claude Code's original terminal permission flow
You still need to return to the terminal to approve or deny the request.
Development
npm install
npm run build
npm run check
npm testRun local CLI smoke checks after building:
node bin/cc-notifier.js --help
node bin/cc-notifier.js config
node bin/cc-notifier.js doctorInspect the package contents before publishing:
npm pack --dry-runPublish
Before publishing:
npm run check
npm test
npm pack --dry-runThen publish to npm:
npm publish --registry=https://registry.npmjs.orgLicense
MIT
