install
source · Clone the upstream repo
git clone https://github.com/openclaw/skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/ababen/add-pi-events-d1" ~/.claude/skills/clawdbot-skills-add-pi-events-d1 && rm -rf "$T"
manifest:
skills/ababen/add-pi-events-d1/SKILL.mdsource content
SKILL: Add PI Events to Cloudflare D1
Trigger
Use this skill when Alex says:
- "Add an event to the site"
- "Add this event to D1"
- "Update PI events"
- "Add [event name] on [date] to babenchuk.com"
- Sends a CSV or list of events to add
Context
- Database:
(Cloudflare D1)mb-events - Env vars: load from
— use~/.env/.env
,$CF_API_TOKEN
,$CF_ACCOUNT_ID$CF_ZONE_BABENCHUK_COM - Repo:
/Users/viki/Projects/projects/marketing-bull/babenchuk-com/ - Live site: https://babenchuk.com/#events
Schema
CREATE TABLE events ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, address TEXT, date_start TEXT, -- ISO format: "2026-06-06T08:00:00" or "2026-06-06" date_end TEXT, -- ISO format or NULL location TEXT, -- venue name/description rsvp_contact TEXT, -- phone/email to RSVP rsvp_to TEXT, -- person/org name to RSVP to register_url TEXT, -- registration/info URL tags TEXT, -- comma-separated: "PI,networking,Miller" created_at TEXT DEFAULT (datetime('now')) );
Steps
1. Load credentials
source ~/.env/.env # Provides: $CF_API_TOKEN, $CF_ACCOUNT_ID
2. Build the INSERT SQL
Parse the event data Alex provides. Convert dates to ISO 8601:
- "March 14, 2026 6:00 PM (EDT)" →
2026-03-14T18:00:00 - "June 6, 2026" →
2026-06-06 - Date ranges: set
+date_startdate_end
Escape single quotes in text fields by doubling them:
O'Brien → O''Brien
INSERT INTO events (name, address, date_start, date_end, location, rsvp_contact, rsvp_to, register_url, tags) VALUES ('Event Name', NULL, '2026-06-06T08:00:00', '2026-06-06T18:00:00', 'Venue, City FL', 'contact@example.com', 'Organizer Name', 'https://register-url.com', 'PI,conference');
3. Execute against D1 (remote)
source ~/.env/.env cd /Users/viki/Projects/projects/marketing-bull/babenchuk-com CLOUDFLARE_API_TOKEN="$CF_API_TOKEN" \ CLOUDFLARE_ACCOUNT_ID="$CF_ACCOUNT_ID" \ npx wrangler d1 execute mb-events --remote \ --command "INSERT INTO events (name, address, date_start, date_end, location, rsvp_contact, rsvp_to, register_url, tags) VALUES ('...', ...);"
For multiple events at once, use a SQL file:
CLOUDFLARE_API_TOKEN="$CF_API_TOKEN" \ CLOUDFLARE_ACCOUNT_ID="$CF_ACCOUNT_ID" \ npx wrangler d1 execute mb-events --remote --file=/tmp/new-events.sql
4. Verify insertion
CLOUDFLARE_API_TOKEN="$CF_API_TOKEN" \ CLOUDFLARE_ACCOUNT_ID="$CF_ACCOUNT_ID" \ npx wrangler d1 execute mb-events --remote \ --command "SELECT id, name, date_start FROM events ORDER BY date_start DESC LIMIT 5;"
Or hit the live API:
curl -s "https://babenchuk-com.pages.dev/api/events?all=true" | jq '[.events[] | {id, name, date: .date}]'
5. No redeploy needed
D1 is a live database. Events appear on the site immediately — no wrangler deploy required.
Useful Queries
List all upcoming events:
source ~/.env/.env CLOUDFLARE_API_TOKEN="$CF_API_TOKEN" CLOUDFLARE_ACCOUNT_ID="$CF_ACCOUNT_ID" \ npx wrangler d1 execute mb-events --remote --command "SELECT id, name, date_start FROM events WHERE date_start >= date('now') ORDER BY date_start ASC;"
Delete an event by ID:
CLOUDFLARE_API_TOKEN="$CF_API_TOKEN" CLOUDFLARE_ACCOUNT_ID="$CF_ACCOUNT_ID" \ npx wrangler d1 execute mb-events --remote --command "DELETE FROM events WHERE id = 42;"
Update an event:
CLOUDFLARE_API_TOKEN="$CF_API_TOKEN" CLOUDFLARE_ACCOUNT_ID="$CF_ACCOUNT_ID" \ npx wrangler d1 execute mb-events --remote --command "UPDATE events SET register_url = 'https://new-url.com' WHERE id = 42;"
Bulk insert from CSV: Convert CSV to SQL INSERTs manually or ask Viki to parse and generate the SQL.
Tag Conventions
Use consistent comma-separated tags (no spaces after commas):
— general PI networkingPI
— Andrew Miller eventsMiller
— PT Now eventsPT Now
— multi-day summitsconference
— attorney-focusedattorney
— medical professional eventsmedical
— FL bar eventsbar association
— general networkingnetworking
— MRI/imaging provider eventsMRI
— continuing legal educationCLE
Notes
anddate_start
must be ISO 8601 strings — the frontend parses them withdate_endnew Date()- NULL is fine for optional fields (address, location, rsvp_contact, rsvp_to, register_url)
- Tags field is plain text — frontend splits on commas
- No redeploy needed after DB changes — site fetches live from D1 on every page load