• 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: v533
View latest version
README.md

Attio Slack Summaries

This val summarizes recent Attio events on Slack.

It receives webhooks from Attio, stores them in a SQLite database, and periodically sends AI-generated summaries of recent activity to Slack. The system uses OpenAI to transform raw webhook data into human-readable summaries, helping teams stay informed about CRM activity without being overwhelmed by individual notifications.

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
├── README.md                   

├── 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/               
│       └── handle-webhook.ts            # Webhook event processing logic
├── shared/                   
│   ├── 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/                    
│   ├── index.ts              # Core application types
│   └── webhook.ts            # Attio webhook payload type definitions
├── database/                 
│   ├── schema.ts             # SQLite table definitions (events, messages, entries)
│   └── sqlite.ts             # Database operations - CRUD for webhook events & messages
└── scripts/                  
    ├── setup.ts              # One-time setup - creates DB tables & Attio webhook
    └── add-list.ts           # Add new Attio list to tracking

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.