I have tried to organize the codebase for easy customization.
formatters.ts
, slack.ts
)core/
directoryThe sections below cover the customization options.
The formatters.ts
file controls how Attio attribute values appear in Slack messages. Formatters are functions that take an object of a type in AttioAttributeValue
and return a string
. Type-safety ensures that custom formatters match Attio attribute types. The formatter file is organized into sections for easy customization:
Text & Selections:
const textFormatters = {
text: (av: AttioTextValue) => av.value,
status: (av: AttioStatusValue) => av.status.title,
select: (av: AttioSelectValue) => av.option.title,
checkbox: (av: AttioCheckboxValue) => av.value.toString(),
};
Numbers & Currency:
const numberFormatters = {
currency: (av: AttioCurrencyValue) => {
return new Intl.NumberFormat("en-US", {
style: "currency",
currency: av.currency_code,
}).format(Number(av.currency_value));
},
number: (av: AttioNumberValue) => av.value.toString(),
};
Dates, People, Links, etc. - Each category has its own section with examples showing input / output.
The slack.ts
file controls Slack message appearance. See the file for more examples and details.
Message Settings:
const SLACK_CONFIG = {
maxCommentLength: 150, // Comment truncation
groupByEntry: true, // Group changes by entry (as in the image above)
allowEmojis: true, // Enable emoji in headers
};
Message Templates:
const MESSAGE_TEMPLATES = {
entryCreated: (actor: string, name: string) => `${actor} added ${name}`,
entryDeleted: (actor: string, name: string) => `${actor} removed ${name}`,
fieldChanged: (field: string, oldValue: string, newValue: string) =>
`*${field}*: ${oldValue} → ${newValue}`,
// ... more templates
};
Link Formats:
const LINK_FORMATS = {
entry: (
workspaceSlug: string,
objectSlug: string,
recordId: string,
name: string
) =>
`<https://app.attio.com/${workspaceSlug}/${objectSlug}/${recordId}/overview|${name}>`,
// ... more link formats
};