• Townie
    AI
  • Blog
  • Docs
  • Pricing
Log inSign up
nbbaier

nbbaier

attio-slack-summaries

Remix of stevekrouse/attio-slack-summaries
Public
Like
attio-slack-summaries
Home
Code
9
database
2
scripts
2
services
4
shared
4
types
2
.vtignore
README.md
config.ts
H
webhook.ts
Branches
4
Pull requests
Remixes
1
History
Environment variables
2
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
README.md
Code
/
README.md
Search
9/5/2025
Viewing readonly version of experimenting branch: v537
View latest version
README.md

Attio Slack Summaries

This val summarizes recent events on Attio lists on Slack

This project receives Attio webhooks, verifies and processes them, and stores events, messages, and list entry state data in SQLite. A scheduled cron job uses then periodically sends summaries with these stored messages to Slack.

Set up

  1. Remix this val
  2. Get a Slack webhook & set it as SLACK_WEBHOOK_URL in this val's Environment variables in the left sidebar
  3. Get an Attio Access Token (with all read & write permissions) & set it as ATTIO_API_KEY in this val's Environment variables in the left sidebar
  4. Get the name of your Attio workspace and set it as ATTIO_WORKSPACE_NAME in this val's Environment variables in the left sidebar
  5. Set SALES_LIST_ID to the ID of your Sales List in this val's Environment variables in the left sidebar
  6. Go to setup.ts and click run to set up the events database and Attio webhook
  7. Go trigger some Attio events and see the message in Slack!

Project Structure

attio-slack-summaries/ ├── webhook.ts # 🎯 Main HTTP endpoint - receives Attio webhooks via Hono framework ├── config.ts # ⚙️ Configuration - workspace name & list IDs for different CRM lists ├── deno.json # 📦 Deno configuration - dependencies, compiler options, Val Town types ├── biome.json # 🧹 Code formatting/linting configuration ├── README.md # 📖 Documentation - setup instructions & file explanations ├── TODO.md # 📋 Task tracking │ ├── services/ # 🏢 Core business logic modules │ ├── alert/ │ │ └── alert.ts # ⏰ Cron job - processes recent events & sends Slack summaries │ ├── attio/ │ │ ├── webhook.ts # 🔗 Attio webhook management - creates/stores webhook configs │ │ └── utils.ts # 🛠️ Attio API utilities & helpers │ ├── auth.ts # 🔐 HMAC signature verification for webhook security │ └── webhook/ # 📨 Webhook event processing logic │ ├── shared/ # 🔄 Reusable utility functions │ ├── slack.ts # 💬 Slack integration - message formatting & webhook sending │ ├── format.ts # 📝 Message formatting utilities for human-readable text │ ├── enrich-entry.ts # 📈 Data enrichment for CRM entries │ └── initialize-entries.ts # 🆕 Entry initialization logic │ ├── types/ # 📋 TypeScript type definitions │ ├── index.ts # 🔖 Core application types │ └── webhook.ts # 📡 Attio webhook payload type definitions │ ├── database/ # 🗄️ Data persistence layer │ ├── schema.ts # 🏗️ SQLite table definitions (events, messages, entries) │ └── sqlite.ts # 💾 Database operations - CRUD for webhook events & messages │ ├── scripts/ # 🔧 Setup & maintenance scripts │ ├── setup.ts # 🚀 One-time setup - creates DB tables & Attio webhook │ └── add-list.ts # ➕ Add new CRM list configuration │ ├── dev-helpers/ # 🛠️ Development & debugging tools │ ├── scratch.ts # 🧪 Development scratchpad for testing functions │ └── fetchAttioData.ts # 📥 Manual data fetching utilities │ └── .vt/ # 🏠 Val Town specific files .cursor/ # 👆 Cursor IDE configuration .vscode/ # 💻 VS Code configuration node_modules/ # 📦 Dependencies

Attio webhooks

Attio webhooks return thin events, which contain a bunch of IDs, but no human-readable data, such as:

{ "event_type": "record.merged", "id": { "workspace_id": "b6c564a6-2cf7-49ab-9320-dea013196bd7", "object_id": "a87cf74e-5ca1-4a8d-b8d3-fcca5413d4c3", "record_id": "d64ff9f2-d1f1-424c-8be6-e41129e35697" }, "duplicate_object_id": "a87cf74e-5ca1-4a8d-b8d3-fcca5413d4c3", "duplicate_record_id": "112b5c78-1ffe-457a-8366-181b482888b4", "actor": { "type": "system", "id": null } }

The trickiest part of this val was hydrating these events into human readable form, like "Steve commented on OpenAI: they're using Val Town!"

After trying and failing (for hours!) to get LLMs to write this code for me, I eventually bit the bullet and wrote it by hand. I only handled some of the more common event types, and left myself comments of other example events of types I haven't handled yet.

In theory, Attio has a better way to handle this, analgous to Stripe's method to fetch data for thin events, but I wasn't able to find it. If you figure it out, please send me a pull request or let me know at steve@val.town.

FeaturesVersion controlCode intelligenceCLI
Use cases
TeamsAI agentsSlackGTM
ExploreDocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareersBrandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Terms of usePrivacy policyAbuse contact
© 2025 Val Town, Inc.