• 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
11
core
5
scripts
2
.vtignore
CUSTOMIZATION.md
DETAILS.md
README.md
C
alert.ts
formatters.ts
slack.ts
types.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
/
DETAILS.md
Code
/
DETAILS.md
Search
9/9/2025
Viewing readonly version of main branch: v32
View latest version
DETAILS.md

Details

The vals uses Attio webhooks to receive real-time notifications about changes to your lists. Each webhook event triggers:

  1. Event Reception webhook.ts - Validates and filters incoming events
  2. State Storage webhook-handler.ts - Stores current state in SQLite
  3. Change Detection alert-processor.ts - Compares states to detect changes
  4. Message Generation formatters.ts - Formats changes into human readable strings
  5. Slack Delivery slack.ts - Sends formatted messages to Slack

Attio webhooks return very thin events. They contain only IDs, not human-readable data or change details. In order to send human readable messages to Slack, we need do a lot of work to enrich the events with data fro the Attio API.

The most involved part in this codebase was figuring out how to transform these events into data that could be used to track the state of list entries and comments. I've accomplished this here by getting the state of the entry/comment when a webhook event comes in, storing that state in the database. We go from a webhook event that looks like this:

{ "event_type": "list-entry.updated", "id": { "workspace_id": "d1cf50ae-67ee-4109-b25a-d6223d6a780f", "list_id": "ea3b198f-859a-41fa-bb39-e0972cb71051", "entry_id": "255c52fc-85e8-4d90-8127-c6b139e3ca37", "attribute_id": "a6336f45-006c-4f08-b371-14ee9546ebee" }, "parent_object_id": "54439a10-8518-49e7-b268-41663063cdab", "parent_record_id": "6bc23aa2-5c5c-4341-949f-9177fd0e6bd5", "actor": { "type": "workspace-member", "id": "f2bbd1ae-29b5-4020-9590-f9afe2b4a276" } }

To a typescript state object that looks like this:

Create val
// Stored state includes complete API response const stateData = { id: "255c52fc-85e8-4d90-8127-c6b139e3ca37", type: "entry", action: "updated", timestamp: 1757439109123, listId: "ea3b198f-859a-41fa-bb39-e0972cb71051", entryId: "255c52fc-85e8-4d90-8127-c6b139e3ca37", rawData: { // Stored state includes complete API response id: { ... }, parent_record_id: "6bc23aa2-5c5c-4341-949f-9177fd0e6bd5", parent_object: "companies", created_at: "2025-09-09T16:55:11.986000000Z", entry_values: { // Crucially, includes data about the entry's attributes stage: [ { active_from: "2025-09-09T16:55:11.986000000Z", active_until: null, created_by_actor: { ... }, status: { id: { ... }, title: "Prospecting", ... }, attribute_type: "status", }, ], // more attributes... }, metadata: {...}, }};

Messages are generated by comparing consecutive states to detect changes. Diffing and message generation is done at run-time when the cron job triggers. This cuts down on the complexity of the database schema (differences and messages are not stored). By storing the entire raw API response, we also get a rich set of data that can be used to customize notifications.

What will you get notifications about?

Currently, the system only tracks the state of two things: list entries and comments on those list entries. The Attio webhook is set up to accept the following events:

  • list-entry.created
  • list-entry.deleted
  • list-entry.updated
  • comment.created
  • comment.resolved
  • comment.unresolved
  • comment.deleted

The logic of generating messages is not set up to handle states outside these two categories. The database is not set up to store data related to things other without both a list id and an entry id (see here).

This is especially relevant for comments. Attio comments can be associated with a record or a list entry (among other things). When a comment is added to a record, it is associated with the record, not the list entry. When a comment is added to a list entry, it is associated with the list entry, not the record. Because of this, you will not see notifications for comments on records, even if those records are in a list you track.

See this Attio help center article for more on Attio's data model. See this Attio API documentation for more information on the types of events that Attio can send.

Appendix: Data flow diagram

The diagram below gives a more complete picture of how data flows through the system. Sample of Slack notifications

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.