@slates-integrations/attio 0.2.0-rc.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/docs/SPEC.md +126 -0
- package/logo.webp +0 -0
- package/package.json +18 -0
- package/slate.json +21 -0
- package/src/auth.ts +189 -0
- package/src/config.ts +4 -0
- package/src/index.ts +72 -0
- package/src/lib/client.ts +506 -0
- package/src/spec.ts +12 -0
- package/src/tools/create-record.ts +71 -0
- package/src/tools/delete-record.ts +36 -0
- package/src/tools/get-record.ts +50 -0
- package/src/tools/index.ts +13 -0
- package/src/tools/list-attributes.ts +66 -0
- package/src/tools/list-objects.ts +47 -0
- package/src/tools/list-workspace-members.ts +51 -0
- package/src/tools/manage-comments.ts +167 -0
- package/src/tools/manage-list-entries.ts +289 -0
- package/src/tools/manage-notes.ts +139 -0
- package/src/tools/manage-tasks.ts +235 -0
- package/src/tools/query-records.ts +79 -0
- package/src/tools/search-records.ts +68 -0
- package/src/tools/update-record.ts +62 -0
- package/src/triggers/comment-events.ts +104 -0
- package/src/triggers/index.ts +5 -0
- package/src/triggers/list-entry-events.ts +106 -0
- package/src/triggers/note-events.ts +93 -0
- package/src/triggers/record-events.ts +109 -0
- package/src/triggers/task-events.ts +79 -0
- package/tsconfig.json +22 -0
package/README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# <img src="logo.webp" height="20"> Attio
|
|
2
|
+
|
|
3
|
+
Manage a customizable CRM workspace including records, lists, notes, tasks, and comments. Create, read, update, delete, and search records across standard and custom objects (people, companies, deals). Upsert records using unique attributes to avoid duplicates. Organize records into lists (e.g., sales pipelines) and manage list entries. Create and manage notes attached to records, assign and complete tasks, and handle threaded comments. Configure the data model by defining custom objects and attributes. Access workspace member information, meeting data, and call recording transcripts. Subscribe to real-time webhook events for records, lists, notes, tasks, comments, and more.
|
|
4
|
+
|
|
5
|
+
## License
|
|
6
|
+
|
|
7
|
+
This integration is licensed under the [FSL-1.1](https://github.com/metorial/metorial-platform/blob/dev/LICENSE).
|
|
8
|
+
|
|
9
|
+
<div align="center">
|
|
10
|
+
<sub>Built with ❤️ by <a href="https://metorial.com">Metorial</a></sub>
|
|
11
|
+
</div>
|
package/docs/SPEC.md
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
Now let me get the OAuth details and the full list of scopes.Now I have enough information to compile the specification. Let me note the key webhook event categories from the sidebar navigation: Call recording events, Comment events, List events, List attribute events, List entry events, Object attribute events, Note events, Note content events, Record events, Task events, Workspace member events. And Record events include: created, merged, updated, deleted.
|
|
2
|
+
|
|
3
|
+
# Slates Specification for Attio
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Attio is a customizable, data-driven CRM platform. The public API allows you to manipulate records, lists, notes, tasks and more. It allows developers to build apps that read and write information to and from Attio workspaces, and subscribe to events in realtime using webhooks.
|
|
8
|
+
|
|
9
|
+
## Authentication
|
|
10
|
+
|
|
11
|
+
Attio supports two authentication methods:
|
|
12
|
+
|
|
13
|
+
### 1. Access Tokens (API Keys)
|
|
14
|
+
|
|
15
|
+
There are two ways to authenticate with Attio: access tokens, or OAuth. Access tokens are scoped to a single workspace, while OAuth is only required if you plan on publishing an integration.
|
|
16
|
+
|
|
17
|
+
In order to generate an API key for your workspace, you must be an admin. From the dropdown beside your workspace name, click Workspace settings. Click the Developers tab. Click + New access token. Give your new access token a name. Set the appropriate Scopes for the token.
|
|
18
|
+
|
|
19
|
+
Tokens do not expire, but can be deleted at any time.
|
|
20
|
+
|
|
21
|
+
Your access token must be included in the Authorization header using the Bearer scheme. HTTP Basic Authentication is also supported (token as username, blank password) but Bearer is recommended.
|
|
22
|
+
|
|
23
|
+
By default, new access tokens don't have any scopes configured. You'll need to specify the scopes you need, which varies depending on the endpoints you're hitting - for example, reading a record requires both the "object configuration" and "record" scopes.
|
|
24
|
+
|
|
25
|
+
### 2. OAuth 2.0
|
|
26
|
+
|
|
27
|
+
Attio supports OAuth 2.0 using the Authorization Code Grant Flow (RFC 6749 section 4.1).
|
|
28
|
+
|
|
29
|
+
- **Authorization URL:** `https://app.attio.com/authorize`
|
|
30
|
+
- **Token URL:** `https://app.attio.com/oauth/token`
|
|
31
|
+
- Required parameters: `client_id`, `client_secret`, `redirect_uri`, `response_type=code`
|
|
32
|
+
- The token exchange uses `grant_type=authorization_code` with `Content-Type: application/x-www-form-urlencoded`.
|
|
33
|
+
|
|
34
|
+
For security reasons, new OAuth apps require publication approval before being usable across workspaces. While developing, your integration will be able to grant tokens for the workspace it is hosted in.
|
|
35
|
+
|
|
36
|
+
### Scopes
|
|
37
|
+
|
|
38
|
+
Scopes control access granularity. Known scopes include (based on API endpoint requirements): `object_configuration:read`, `record_permission:read`, `record:read`, `record:read-write`, `task:read`, `task:read-write`, `user_management:read`, `note:read`, `note:read-write`, `webhook:read`, `webhook:read-write`, `list:read`, `list:read-write`, `comment:read`, `comment:read-write`. Scopes are configured per token or per OAuth app.
|
|
39
|
+
|
|
40
|
+
## Features
|
|
41
|
+
|
|
42
|
+
### Record Management
|
|
43
|
+
|
|
44
|
+
Manage CRM records across customizable objects (e.g., People, Companies, Deals, and custom objects). Create, read, update, delete, and search/filter records. Records support an "assert" operation (upsert) that matches on a unique attribute (e.g., email address) to create or update without duplicates.
|
|
45
|
+
|
|
46
|
+
### Object & Attribute Configuration
|
|
47
|
+
|
|
48
|
+
Define and manage the data model of your workspace. Create custom objects and configure attributes (fields) on objects or lists. Supports various attribute types including text, email, domain, select, multi-select, currency, status, phone, checkbox, number, and rating. Attributes can be archived.
|
|
49
|
+
|
|
50
|
+
### Lists & Entries
|
|
51
|
+
|
|
52
|
+
Lists allow organizing records into structured collections (e.g., sales pipelines, recruitment pipelines). Add records to lists as entries, manage entry attributes, and query entries with filters. Entries can be asserted (upserted) by parent record.
|
|
53
|
+
|
|
54
|
+
### Notes
|
|
55
|
+
|
|
56
|
+
Create and manage notes attached to records. Notes reference a parent object and record. Supports reading, creating, and deleting notes.
|
|
57
|
+
|
|
58
|
+
### Tasks
|
|
59
|
+
|
|
60
|
+
Create and manage tasks within the workspace. Tasks can be assigned to workspace members and linked to records. Supports creating, listing, updating, and completing tasks.
|
|
61
|
+
|
|
62
|
+
### Comments & Threads
|
|
63
|
+
|
|
64
|
+
Manage threaded comments on records, notes, or other entities. Create, read, and delete comments within threads.
|
|
65
|
+
|
|
66
|
+
### Workspace Members
|
|
67
|
+
|
|
68
|
+
Read information about members of the workspace, including their roles and details.
|
|
69
|
+
|
|
70
|
+
### Meetings & Call Recordings
|
|
71
|
+
|
|
72
|
+
Access meeting data and call recording information including transcripts.
|
|
73
|
+
|
|
74
|
+
### Webhooks Management
|
|
75
|
+
|
|
76
|
+
Programmatically create, list, update, and delete webhook subscriptions. Subscriptions support filters (e.g., filtering events by specific object or record).
|
|
77
|
+
|
|
78
|
+
## Events
|
|
79
|
+
|
|
80
|
+
Attio supports webhooks for real-time event subscriptions. Webhooks are created via the API with a target URL and a list of event subscriptions, which can include filters. Subscriptions can filter events by fields like `parent_object_id` using operators such as `equals`.
|
|
81
|
+
|
|
82
|
+
The following webhook event categories are available:
|
|
83
|
+
|
|
84
|
+
### Record Events
|
|
85
|
+
|
|
86
|
+
Events for when records (people, companies, deals, custom objects) are created, updated, merged, or deleted. Update events include the specific attribute that changed.
|
|
87
|
+
|
|
88
|
+
### List Events
|
|
89
|
+
|
|
90
|
+
Events for when a list is created or updated (e.g., name or icon changes).
|
|
91
|
+
|
|
92
|
+
### List Entry Events
|
|
93
|
+
|
|
94
|
+
Events for when records are added to, updated within, or removed from lists.
|
|
95
|
+
|
|
96
|
+
### List Attribute Events
|
|
97
|
+
|
|
98
|
+
Events for changes to attribute definitions on lists.
|
|
99
|
+
|
|
100
|
+
### Object Attribute Events
|
|
101
|
+
|
|
102
|
+
Events for changes to attribute definitions on objects.
|
|
103
|
+
|
|
104
|
+
### Note Events
|
|
105
|
+
|
|
106
|
+
Events for when notes are created or updated. Note: body content updates do not currently trigger webhooks — this event is fired whenever the title of a note is modified. Body updates do not currently trigger webhooks.
|
|
107
|
+
|
|
108
|
+
### Note Content Events
|
|
109
|
+
|
|
110
|
+
Events related to note content changes (separate from title-level note events).
|
|
111
|
+
|
|
112
|
+
### Task Events
|
|
113
|
+
|
|
114
|
+
Events for when tasks are created, updated, or completed.
|
|
115
|
+
|
|
116
|
+
### Comment Events
|
|
117
|
+
|
|
118
|
+
Events for when comments are created, updated, or deleted.
|
|
119
|
+
|
|
120
|
+
### Call Recording Events
|
|
121
|
+
|
|
122
|
+
Events related to call recording activity.
|
|
123
|
+
|
|
124
|
+
### Workspace Member Events
|
|
125
|
+
|
|
126
|
+
Events for changes to workspace membership.
|
package/logo.webp
ADDED
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@slates-integrations/attio",
|
|
3
|
+
"main": "src/index.ts",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "bunx @vercel/ncc build src/index.ts -o dist -m -s",
|
|
7
|
+
"typecheck": "tsc --noEmit"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"@types/node": "^20",
|
|
11
|
+
"slates": "1.0.0-rc.10",
|
|
12
|
+
"zod": "^4.2"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"typescript": "^5"
|
|
16
|
+
},
|
|
17
|
+
"version": "0.2.0-rc.5"
|
|
18
|
+
}
|
package/slate.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@metorial/attio",
|
|
3
|
+
"description": "Manage a customizable CRM workspace including records, lists, notes, tasks, and comments. Create, read, update, delete, and search records across standard and custom objects (people, companies, deals). Upsert records using unique attributes to avoid duplicates. Organize records into lists (e.g., sales pipelines) and manage list entries. Create and manage notes attached to records, assign and complete tasks, and handle threaded comments. Configure the data model by defining custom objects and attributes. Access workspace member information, meeting data, and call recording transcripts. Subscribe to real-time webhook events for records, lists, notes, tasks, comments, and more.",
|
|
4
|
+
"categories": [
|
|
5
|
+
"crm-and-sales-tools",
|
|
6
|
+
"task-and-project-management"
|
|
7
|
+
],
|
|
8
|
+
"skills": [
|
|
9
|
+
"create and manage records",
|
|
10
|
+
"search and filter records",
|
|
11
|
+
"manage lists and entries",
|
|
12
|
+
"create and delete notes",
|
|
13
|
+
"assign and complete tasks",
|
|
14
|
+
"manage threaded comments",
|
|
15
|
+
"configure objects and attributes",
|
|
16
|
+
"subscribe to webhook events",
|
|
17
|
+
"access call recordings",
|
|
18
|
+
"manage workspace members"
|
|
19
|
+
],
|
|
20
|
+
"logoUrl": "https://provider-logos.metorial-cdn.com/attio.webp"
|
|
21
|
+
}
|
package/src/auth.ts
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { SlateAuth, createAxios } from 'slates';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
export let auth = SlateAuth.create()
|
|
5
|
+
.output(
|
|
6
|
+
z.object({
|
|
7
|
+
token: z.string()
|
|
8
|
+
})
|
|
9
|
+
)
|
|
10
|
+
.addOauth({
|
|
11
|
+
type: 'auth.oauth',
|
|
12
|
+
name: 'OAuth',
|
|
13
|
+
key: 'oauth',
|
|
14
|
+
|
|
15
|
+
scopes: [
|
|
16
|
+
{
|
|
17
|
+
title: 'Object Configuration (Read)',
|
|
18
|
+
description: 'Read object and attribute definitions',
|
|
19
|
+
scope: 'object_configuration:read'
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
title: 'Record Permission (Read)',
|
|
23
|
+
description: 'Read record-level permissions',
|
|
24
|
+
scope: 'record_permission:read'
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
title: 'Record Permission (Read/Write)',
|
|
28
|
+
description: 'Create, update, and delete records',
|
|
29
|
+
scope: 'record_permission:read-write'
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
title: 'Tasks (Read)',
|
|
33
|
+
description: 'Read tasks',
|
|
34
|
+
scope: 'task:read'
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
title: 'Tasks (Read/Write)',
|
|
38
|
+
description: 'Create, update, and delete tasks',
|
|
39
|
+
scope: 'task:read-write'
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
title: 'User Management (Read)',
|
|
43
|
+
description: 'Read workspace member information',
|
|
44
|
+
scope: 'user_management:read'
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
title: 'Notes (Read)',
|
|
48
|
+
description: 'Read notes',
|
|
49
|
+
scope: 'note:read'
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
title: 'Notes (Read/Write)',
|
|
53
|
+
description: 'Create and delete notes',
|
|
54
|
+
scope: 'note:read-write'
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
title: 'Webhooks (Read)',
|
|
58
|
+
description: 'Read webhook subscriptions',
|
|
59
|
+
scope: 'webhook:read'
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
title: 'Webhooks (Read/Write)',
|
|
63
|
+
description: 'Create, update, and delete webhook subscriptions',
|
|
64
|
+
scope: 'webhook:read-write'
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
title: 'List Configuration (Read)',
|
|
68
|
+
description: 'Read list definitions and configuration',
|
|
69
|
+
scope: 'list_configuration:read'
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
title: 'List Configuration (Read/Write)',
|
|
73
|
+
description: 'Create, update, and delete list definitions',
|
|
74
|
+
scope: 'list_configuration:read-write'
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
title: 'List Entries (Read)',
|
|
78
|
+
description: 'Read list entries',
|
|
79
|
+
scope: 'list_entry:read'
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
title: 'List Entries (Read/Write)',
|
|
83
|
+
description: 'Create, update, and delete list entries',
|
|
84
|
+
scope: 'list_entry:read-write'
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
title: 'Comments (Read)',
|
|
88
|
+
description: 'Read comments and threads',
|
|
89
|
+
scope: 'comment:read'
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
title: 'Comments (Read/Write)',
|
|
93
|
+
description: 'Create and delete comments',
|
|
94
|
+
scope: 'comment:read-write'
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
|
|
98
|
+
getAuthorizationUrl: async ctx => {
|
|
99
|
+
let params = new URLSearchParams({
|
|
100
|
+
client_id: ctx.clientId,
|
|
101
|
+
redirect_uri: ctx.redirectUri,
|
|
102
|
+
response_type: 'code',
|
|
103
|
+
state: ctx.state
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
url: `https://app.attio.com/authorize?${params.toString()}`
|
|
108
|
+
};
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
handleCallback: async ctx => {
|
|
112
|
+
let axios = createAxios();
|
|
113
|
+
|
|
114
|
+
let response = await axios.post(
|
|
115
|
+
'https://app.attio.com/oauth/token',
|
|
116
|
+
new URLSearchParams({
|
|
117
|
+
grant_type: 'authorization_code',
|
|
118
|
+
code: ctx.code,
|
|
119
|
+
redirect_uri: ctx.redirectUri,
|
|
120
|
+
client_id: ctx.clientId,
|
|
121
|
+
client_secret: ctx.clientSecret
|
|
122
|
+
}).toString(),
|
|
123
|
+
{
|
|
124
|
+
headers: {
|
|
125
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
output: {
|
|
132
|
+
token: response.data.access_token
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
getProfile: async (ctx: any) => {
|
|
138
|
+
let axios = createAxios({
|
|
139
|
+
baseURL: 'https://api.attio.com',
|
|
140
|
+
headers: {
|
|
141
|
+
Authorization: `Bearer ${ctx.output.token}`
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
let response = await axios.get('/v2/self');
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
profile: {
|
|
149
|
+
id: response.data.data?.id?.workspace_id,
|
|
150
|
+
name: response.data.data?.workspace?.name
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
})
|
|
155
|
+
.addTokenAuth({
|
|
156
|
+
type: 'auth.token',
|
|
157
|
+
name: 'Access Token',
|
|
158
|
+
key: 'access_token',
|
|
159
|
+
|
|
160
|
+
inputSchema: z.object({
|
|
161
|
+
token: z.string().describe('Attio API access token')
|
|
162
|
+
}),
|
|
163
|
+
|
|
164
|
+
getOutput: async ctx => {
|
|
165
|
+
return {
|
|
166
|
+
output: {
|
|
167
|
+
token: ctx.input.token
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
getProfile: async (ctx: any) => {
|
|
173
|
+
let axios = createAxios({
|
|
174
|
+
baseURL: 'https://api.attio.com',
|
|
175
|
+
headers: {
|
|
176
|
+
Authorization: `Bearer ${ctx.output.token}`
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
let response = await axios.get('/v2/self');
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
profile: {
|
|
184
|
+
id: response.data.data?.id?.workspace_id,
|
|
185
|
+
name: response.data.data?.workspace?.name
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
});
|
package/src/config.ts
ADDED
package/src/index.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Slate } from 'slates';
|
|
2
|
+
import { spec } from './spec';
|
|
3
|
+
import {
|
|
4
|
+
getRecordTool,
|
|
5
|
+
createRecordTool,
|
|
6
|
+
updateRecordTool,
|
|
7
|
+
deleteRecordTool,
|
|
8
|
+
queryRecordsTool,
|
|
9
|
+
searchRecordsTool,
|
|
10
|
+
listObjectsTool,
|
|
11
|
+
listAttributesTool,
|
|
12
|
+
getListsTool,
|
|
13
|
+
addListEntryTool,
|
|
14
|
+
updateListEntryTool,
|
|
15
|
+
deleteListEntryTool,
|
|
16
|
+
queryListEntriesTool,
|
|
17
|
+
listNotesTool,
|
|
18
|
+
createNoteTool,
|
|
19
|
+
deleteNoteTool,
|
|
20
|
+
listTasksTool,
|
|
21
|
+
createTaskTool,
|
|
22
|
+
updateTaskTool,
|
|
23
|
+
deleteTaskTool,
|
|
24
|
+
createCommentTool,
|
|
25
|
+
getThreadTool,
|
|
26
|
+
deleteCommentTool,
|
|
27
|
+
listWorkspaceMembersTool
|
|
28
|
+
} from './tools';
|
|
29
|
+
import {
|
|
30
|
+
recordEventsTrigger,
|
|
31
|
+
listEntryEventsTrigger,
|
|
32
|
+
noteEventsTrigger,
|
|
33
|
+
taskEventsTrigger,
|
|
34
|
+
commentEventsTrigger
|
|
35
|
+
} from './triggers';
|
|
36
|
+
|
|
37
|
+
export let provider = Slate.create({
|
|
38
|
+
spec,
|
|
39
|
+
tools: [
|
|
40
|
+
getRecordTool,
|
|
41
|
+
createRecordTool,
|
|
42
|
+
updateRecordTool,
|
|
43
|
+
deleteRecordTool,
|
|
44
|
+
queryRecordsTool,
|
|
45
|
+
searchRecordsTool,
|
|
46
|
+
listObjectsTool,
|
|
47
|
+
listAttributesTool,
|
|
48
|
+
getListsTool,
|
|
49
|
+
addListEntryTool,
|
|
50
|
+
updateListEntryTool,
|
|
51
|
+
deleteListEntryTool,
|
|
52
|
+
queryListEntriesTool,
|
|
53
|
+
listNotesTool,
|
|
54
|
+
createNoteTool,
|
|
55
|
+
deleteNoteTool,
|
|
56
|
+
listTasksTool,
|
|
57
|
+
createTaskTool,
|
|
58
|
+
updateTaskTool,
|
|
59
|
+
deleteTaskTool,
|
|
60
|
+
createCommentTool,
|
|
61
|
+
getThreadTool,
|
|
62
|
+
deleteCommentTool,
|
|
63
|
+
listWorkspaceMembersTool
|
|
64
|
+
],
|
|
65
|
+
triggers: [
|
|
66
|
+
recordEventsTrigger,
|
|
67
|
+
listEntryEventsTrigger,
|
|
68
|
+
noteEventsTrigger,
|
|
69
|
+
taskEventsTrigger,
|
|
70
|
+
commentEventsTrigger
|
|
71
|
+
]
|
|
72
|
+
});
|