git clone https://github.com/claudeaceae/samara-main
T=$(mktemp -d) && git clone --depth=1 https://github.com/claudeaceae/samara-main "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude/skills/webhook" ~/.claude/skills/claudeaceae-samara-main-webhook && rm -rf "$T"
.claude/skills/webhook/SKILL.md/webhook
name: webhook description: Manage webhook sources - list, add, test, and view incoming events context: fork triggers:
- webhook
- add webhook
- create webhook
- webhook setup
- incoming webhooks
Manage the webhook receiver system. Use this skill to add new webhook sources, test existing ones, and view incoming events.
What You Can Do
- List sources - Show all registered webhook sources
- Add source - Create a new webhook source with secure secret
- Test source - Send a test webhook to verify configuration
- View events - Show recent incoming webhook events
- Setup guide - Get instructions for connecting external services
Quick Reference
Webhook Receiver
- Public URL:
https://webhooks.organelle.co - Config: macOS Keychain (
)credential get webhook-secrets - Events directory:
~/.claude-mind/system/senses/
Endpoints
| Endpoint | Method | Purpose |
|---|---|---|
| POST | Receive webhook from source |
| GET | Health check |
| GET | Show registered sources |
Instructions
When user wants to list sources
Read and display the webhook configuration:
~/.claude-mind/system/bin/credential get webhook-secrets | jq .
Also check service status:
curl -s https://webhooks.organelle.co/status | jq .
When user wants to add a new source
-
Ask for source name (lowercase, no spaces - e.g., "ifttt", "home-assistant", "backup-server")
-
Generate a secure secret:
openssl rand -hex 32
- Read current config, add new source, write back:
The new source should have this structure:
{ "secret": "<generated-secret>", "allowed_ips": null, "rate_limit": "30/minute" }
For IP-restricted sources (more secure), ask if they want to limit to specific IPs.
- Provide setup instructions based on the service type (see Setup Guides below)
When user wants to test a source
Generate and send a signed test webhook:
SOURCE="<source-name>" SECRET=$(~/.claude-mind/system/bin/credential get webhook-secrets | jq -r ".sources.\"$SOURCE\".secret") PAYLOAD='{"event":"test","message":"Test webhook from skill","timestamp":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"}' SIGNATURE=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "$SECRET" | cut -d' ' -f2) curl -s -X POST "https://webhooks.organelle.co/webhook/$SOURCE" \ -H "Content-Type: application/json" \ -H "X-Hub-Signature-256: sha256=$SIGNATURE" \ -d "$PAYLOAD" | jq .
Then check the created event:
ls -lt ~/.claude-mind/system/senses/webhook-*.json | head -3
When user wants to view recent events
# List recent webhook events ls -lt ~/.claude-mind/system/senses/webhook-*.json 2>/dev/null | head -10 # Show content of most recent cat $(ls -t ~/.claude-mind/system/senses/webhook-*.json 2>/dev/null | head -1) | jq .
Setup Guides
Provide these instructions based on what service the user wants to connect:
IFTTT Setup
- Create an IFTTT account at ifttt.com
- Create a new Applet
- For the "Then That" action, choose "Webhooks" > "Make a web request"
- Configure:
- URL:
https://webhooks.organelle.co/webhook/ifttt - Method: POST
- Content Type: application/json
- Additional Headers:
X-Webhook-Secret: <their-secret> - Body:
{ "trigger": "<<<{{EventName}}>>>", "occurred_at": "<<<{{OccurredAt}}>>>", "data": {} } - URL:
Note: IFTTT uses simple secret header, not HMAC signing.
GitHub Setup
- Go to repository Settings > Webhooks > Add webhook
- Configure:
- Payload URL:
https://webhooks.organelle.co/webhook/github - Content type: application/json
- Secret:
<their-secret> - Events: Choose which events to receive
- Payload URL:
- GitHub automatically signs payloads with HMAC-SHA256
Home Assistant Setup
- In
, add a REST command:configuration.yaml
rest_command: notify_claude: url: "https://webhooks.organelle.co/webhook/home-assistant" method: POST headers: Content-Type: application/json X-Webhook-Secret: "<their-secret>" payload: '{"event": "{{ event }}", "data": {{ data | to_json }}}'
- Call from automations:
service: rest_command.notify_claude data: event: "motion_detected" data: location: "front_door"
iOS Shortcut Setup
Create a shortcut with "Get Contents of URL" action:
- URL:
https://webhooks.organelle.co/webhook/shortcut - Method: POST
- Headers:
- Content-Type: application/json
- X-Webhook-Secret:
<their-secret>
- Request Body: JSON with your data
Generic / Custom Script
#!/bin/bash SECRET="<your-secret>" PAYLOAD='{"event":"your_event","data":{}}' SIGNATURE=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "$SECRET" | cut -d' ' -f2) curl -X POST https://webhooks.organelle.co/webhook/your-source \ -H "Content-Type: application/json" \ -H "X-Hub-Signature-256: sha256=$SIGNATURE" \ -d "$PAYLOAD"
Or simpler (less secure, but works):
curl -X POST https://webhooks.organelle.co/webhook/your-source \ -H "Content-Type: application/json" \ -H "X-Webhook-Secret: <your-secret>" \ -d '{"event":"ping"}'
Authentication Methods
The webhook receiver supports two authentication methods:
1. HMAC-SHA256 Signature (Recommended)
Used by GitHub and security-conscious services. Send
X-Hub-Signature-256 header:
X-Hub-Signature-256: sha256=<hmac-sha256-of-body-using-secret>
2. Direct Secret Header (Simpler)
For services that can't compute HMAC (like IFTTT). Send
X-Webhook-Secret header:
X-Webhook-Secret: <your-secret>
Event Processing
Incoming webhooks become "sense events" in
~/.claude-mind/system/senses/. The SenseRouter picks these up and can:
- Trigger immediate attention for high-priority events
- Queue for next wake cycle
- Include in context for relevant conversations
Priority Mapping
You can customize priority in the webhook receiver's
determine_priority() function, but defaults are:
| Source | Condition | Priority |
|---|---|---|
| GitHub | Security-related | |
| GitHub | PR/issue actions | |
| Any | Default | |
Troubleshooting
Webhook not arriving
- Check service is running:
curl -s https://webhooks.organelle.co/health | jq .
- Check source is registered:
curl -s https://webhooks.organelle.co/status | jq .
- Check logs:
tail -50 ~/.claude-mind/system/logs/webhook-receiver.log
Authentication failing
- For HMAC: Ensure payload bytes match exactly (no extra whitespace)
- For direct secret: Check header name is exactly
X-Webhook-Secret - Verify secret matches config file
IP blocked
If using IP allowlist, check the
allowed_ips in config. Cloudflare IPs may differ from original source.