Start with a scoped bot token and a running com1-bot-ingest Edge Function. Each recipe posts from a trusted server/script, never from client-side JavaScript.
Recipe A — Linux disk warning (Bash)
#!/usr/bin/env bash
set -euo pipefail
: "${COM1_PROJECT_URL:?set COM1_PROJECT_URL}"
: "${COM1_BOT_TOKEN:?set COM1_BOT_TOKEN}"
used=$(df -P / | awk 'NR==2 {gsub("%", "", $5); print $5}')
if (( used >= 90 )); then
export USED_PERCENT="$used"
python3 - <<'PYIN'
import json, os, urllib.request
payload = {
'event_id': 'disk-' + str(__import__('time').time_ns()),
'kind': 'alert', 'title': 'DISK SPACE LOW',
'message': 'Root partition threshold reached',
'level': 'warning',
'fields': {'host': __import__('socket').gethostname(), 'used_percent': int(os.environ['USED_PERCENT'])}
}
url = os.environ['COM1_PROJECT_URL'].rstrip('/') + '/functions/v1/com1-bot-ingest'
req = urllib.request.Request(url, data=json.dumps(payload).encode(), method='POST', headers={
'Content-Type': 'application/json', 'Authorization': 'Bearer ' + os.environ['COM1_BOT_TOKEN']})
with urllib.request.urlopen(req, timeout=15) as r: print(r.status)
PYIN
fi
Schedule the script with your own cron/systemd timer. Add local alert suppression/deduplication to avoid flooding chat every minute while the disk remains above threshold.
Recipe B — Website uptime status (Python)
import os, json, time, urllib.request, urllib.error
site = 'https://example.com/health'
try:
with urllib.request.urlopen(site, timeout=8) as response:
healthy, http_status = 200 <= response.status < 400, response.status
except Exception:
healthy, http_status = False, 0
payload = {
'event_id': 'health-' + str(int(time.time())),
'kind': 'alert',
'title': 'WEB HEALTH',
'message': 'Service reachable' if healthy else 'Service unreachable',
'level': 'success' if healthy else 'critical',
'fields': {'site': site, 'status': http_status},
}
url = os.environ['COM1_PROJECT_URL'].rstrip('/') + '/functions/v1/com1-bot-ingest'
req = urllib.request.Request(url,
data=json.dumps(payload).encode(), method='POST',
headers={'Authorization': 'Bearer ' + os.environ['COM1_BOT_TOKEN'],
'Content-Type': 'application/json'})
with urllib.request.urlopen(req, timeout=15) as r:
print(r.status, r.read().decode())
This example is a single health check, not a hosted COM1 health-monitoring service. Run it from an environment you control and choose a sensible schedule.
Recipe C — CI completion alert (Node.js)
// Run as a Node 18+ server-side CI step.
const eventId = `ci-${process.env.BUILD_ID || Date.now()}`;
const payload = {
event_id: eventId,
kind: 'structured',
title: 'BUILD FINISHED',
message: 'Pipeline completed',
fields: { repository: 'com1', branch: 'main', build: process.env.BUILD_ID || 'manual' },
};
const resp = await fetch(`${process.env.COM1_PROJECT_URL.replace(/\/$/, '')}/functions/v1/com1-bot-ingest`, {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.COM1_BOT_TOKEN}`, 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
if (!resp.ok) throw new Error(`COM1 bot ingest failed: HTTP ${resp.status}`);
console.log(await resp.text());
Recipe D — IoT home-server bridge
ESP32 sensors can POST telemetry to your own authenticated server, which validates, aggregates and rate-limits it before publishing a structured event into COM1. Avoid embedding the bot token in device firmware that may be extracted. A bot event can contain scalar fields like temperature_c, uptime_s and battery_pct. MQTT-to-COM1 bridging requires your own adapter until a native subscriber is deployed.
Bot API troubleshooting
| Symptom | What to check |
|---|---|
| No message appears | Correct project URL/function name, deployed Edge Function, token destination, bot enabled, standard channel and owner membership. |
| 401/403 or token rejected | Token copied fully? Revoked/expired? Permission for kind? Never swap in your Supabase service-role key. |
| Duplicate event / conflict | Same event_id with changed JSON is a conflict; reuse ID only for an identical retry. |
| Rate limit response | Slow down, back off and check per-token minute/day limits in the bot console. |
| Invalid fields | Only scalar field values; 20 keys max, key names and lengths limited by migration. |
| Cannot use Secure Link channel | Bot token destinations intentionally require a standard conversation. |
/bot @name not working | Owner enabled command link? User has command access? Public HTTPS callback configured? Deployed com1-bot-command working? |
| Private callback unreachable | A local 192.168.x.x or localhost URL is not reachable from Supabase; use a properly protected public HTTPS endpoint. |
Privacy: Do not post full request headers, raw tokens, personal messages or callback secrets when asking for debugging help.