@doist/comms-sdk 0.5.2 → 0.6.0
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 +25 -0
- package/dist/cjs/clients/hooks-client.js +52 -0
- package/dist/cjs/comms-api.js +2 -0
- package/dist/cjs/consts/endpoints.js +2 -1
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/types/entities.js +4 -1
- package/dist/cjs/types/requests.js +63 -1
- package/dist/esm/clients/hooks-client.js +48 -0
- package/dist/esm/comms-api.js +2 -0
- package/dist/esm/consts/endpoints.js +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/types/entities.js +3 -0
- package/dist/esm/types/requests.js +62 -0
- package/dist/types/clients/hooks-client.d.ts +29 -0
- package/dist/types/comms-api.d.ts +2 -0
- package/dist/types/consts/endpoints.d.ts +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/types/entities.d.ts +5 -0
- package/dist/types/types/requests.d.ts +155 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -121,6 +121,31 @@ const refreshed = await refreshAuthToken({
|
|
|
121
121
|
const api = new CommsApi(refreshed.accessToken)
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
+
### REST hooks
|
|
125
|
+
|
|
126
|
+
REST hooks require a Todoist OAuth access token with Todoist Comms audience. Subscribe
|
|
127
|
+
with an HTTPS target URL up to 150 characters and one of the exported
|
|
128
|
+
`HOOK_EVENTS`; the backend will POST webhook payloads to that URL when
|
|
129
|
+
matching events happen:
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import { CommsApi, HOOK_EVENTS } from '@doist/comms-sdk'
|
|
133
|
+
|
|
134
|
+
const api = new CommsApi('TODOIST_OAUTH_ACCESS_TOKEN')
|
|
135
|
+
|
|
136
|
+
const subscription = await api.hooks.subscribe({
|
|
137
|
+
targetUrl: 'https://example.com/comms-hook',
|
|
138
|
+
event: 'thread_added',
|
|
139
|
+
workspaceId: 1,
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
console.log(subscription.id, HOOK_EVENTS)
|
|
143
|
+
|
|
144
|
+
await api.hooks.unsubscribe({
|
|
145
|
+
targetUrl: 'https://example.com/comms-hook',
|
|
146
|
+
})
|
|
147
|
+
```
|
|
148
|
+
|
|
124
149
|
### Short-lived processes (CLIs, scripts)
|
|
125
150
|
|
|
126
151
|
On Node, the SDK keeps a connection pool alive across requests so HTTP/2
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HooksClient = void 0;
|
|
4
|
+
const endpoints_1 = require("../consts/endpoints");
|
|
5
|
+
const http_client_1 = require("../transport/http-client");
|
|
6
|
+
const entities_1 = require("../types/entities");
|
|
7
|
+
const base_client_1 = require("./base-client");
|
|
8
|
+
/**
|
|
9
|
+
* Client for `/api/v1/hooks/`. REST hooks require Todoist OAuth bearer tokens
|
|
10
|
+
* that include Comms audience; session tokens are rejected by the backend.
|
|
11
|
+
*/
|
|
12
|
+
class HooksClient extends base_client_1.BaseClient {
|
|
13
|
+
/**
|
|
14
|
+
* Subscribes the current OAuth app to a REST hook event.
|
|
15
|
+
*
|
|
16
|
+
* @param args - The hook subscription parameters.
|
|
17
|
+
* @param args.targetUrl - HTTPS endpoint, up to 150 characters, that will receive webhook POSTs.
|
|
18
|
+
* @param args.event - Event name to subscribe to.
|
|
19
|
+
* @param args.workspaceId - Optional workspace filter.
|
|
20
|
+
* @param args.channelId - Optional channel filter.
|
|
21
|
+
* @param args.threadId - Optional thread filter.
|
|
22
|
+
* @param args.conversationId - Optional conversation filter for message events.
|
|
23
|
+
* @returns The `{ status: 'ok', id }` response for the subscription.
|
|
24
|
+
*/
|
|
25
|
+
subscribe(args) {
|
|
26
|
+
return (0, http_client_1.request)({
|
|
27
|
+
httpMethod: 'POST',
|
|
28
|
+
baseUri: this.getBaseUri(),
|
|
29
|
+
relativePath: `${endpoints_1.ENDPOINT_HOOKS}/subscribe`,
|
|
30
|
+
apiToken: this.apiToken,
|
|
31
|
+
payload: args,
|
|
32
|
+
customFetch: this.customFetch,
|
|
33
|
+
}).then((response) => entities_1.HookSubscribeResponseSchema.parse(response.data));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Unsubscribes all hooks with the target URL for the current OAuth app.
|
|
37
|
+
*
|
|
38
|
+
* @param args - The hook unsubscribe parameters.
|
|
39
|
+
* @param args.targetUrl - Target URL to remove.
|
|
40
|
+
*/
|
|
41
|
+
unsubscribe(args) {
|
|
42
|
+
return (0, http_client_1.request)({
|
|
43
|
+
httpMethod: 'POST',
|
|
44
|
+
baseUri: this.getBaseUri(),
|
|
45
|
+
relativePath: `${endpoints_1.ENDPOINT_HOOKS}/unsubscribe`,
|
|
46
|
+
apiToken: this.apiToken,
|
|
47
|
+
payload: args,
|
|
48
|
+
customFetch: this.customFetch,
|
|
49
|
+
}).then((response) => entities_1.StatusOkSchema.parse(response.data));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.HooksClient = HooksClient;
|
package/dist/cjs/comms-api.js
CHANGED
|
@@ -7,6 +7,7 @@ const comments_client_1 = require("./clients/comments-client");
|
|
|
7
7
|
const conversation_messages_client_1 = require("./clients/conversation-messages-client");
|
|
8
8
|
const conversations_client_1 = require("./clients/conversations-client");
|
|
9
9
|
const groups_client_1 = require("./clients/groups-client");
|
|
10
|
+
const hooks_client_1 = require("./clients/hooks-client");
|
|
10
11
|
const inbox_client_1 = require("./clients/inbox-client");
|
|
11
12
|
const reactions_client_1 = require("./clients/reactions-client");
|
|
12
13
|
const search_client_1 = require("./clients/search-client");
|
|
@@ -53,6 +54,7 @@ class CommsApi {
|
|
|
53
54
|
this.reactions = new reactions_client_1.ReactionsClient(clientConfig);
|
|
54
55
|
this.search = new search_client_1.SearchClient(clientConfig);
|
|
55
56
|
this.attachments = new attachments_client_1.AttachmentsClient(clientConfig);
|
|
57
|
+
this.hooks = new hooks_client_1.HooksClient(clientConfig);
|
|
56
58
|
}
|
|
57
59
|
/**
|
|
58
60
|
* Drains the SDK's process-global connection pool. CLIs and scripts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ENDPOINT_ATTACHMENTS = exports.ENDPOINT_CONVERSATION_MESSAGES = exports.ENDPOINT_SEARCH = exports.ENDPOINT_REACTIONS = exports.ENDPOINT_INBOX = exports.ENDPOINT_NOTIFICATIONS = exports.ENDPOINT_COMMENTS = exports.ENDPOINT_CONVERSATIONS = exports.ENDPOINT_GROUPS = exports.ENDPOINT_THREADS = exports.ENDPOINT_CHANNELS = exports.ENDPOINT_WORKSPACES = exports.ENDPOINT_USERS = void 0;
|
|
3
|
+
exports.ENDPOINT_HOOKS = exports.ENDPOINT_ATTACHMENTS = exports.ENDPOINT_CONVERSATION_MESSAGES = exports.ENDPOINT_SEARCH = exports.ENDPOINT_REACTIONS = exports.ENDPOINT_INBOX = exports.ENDPOINT_NOTIFICATIONS = exports.ENDPOINT_COMMENTS = exports.ENDPOINT_CONVERSATIONS = exports.ENDPOINT_GROUPS = exports.ENDPOINT_THREADS = exports.ENDPOINT_CHANNELS = exports.ENDPOINT_WORKSPACES = exports.ENDPOINT_USERS = void 0;
|
|
4
4
|
exports.getCommsBaseUri = getCommsBaseUri;
|
|
5
5
|
const api_version_1 = require("../types/api-version");
|
|
6
6
|
const BASE_URI = 'https://comms.todoist.com';
|
|
@@ -31,3 +31,4 @@ exports.ENDPOINT_REACTIONS = 'reactions';
|
|
|
31
31
|
exports.ENDPOINT_SEARCH = 'search';
|
|
32
32
|
exports.ENDPOINT_CONVERSATION_MESSAGES = 'conversation_messages';
|
|
33
33
|
exports.ENDPOINT_ATTACHMENTS = 'attachments';
|
|
34
|
+
exports.ENDPOINT_HOOKS = 'hooks';
|
package/dist/cjs/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.closeDefaultDispatcher = exports.CommsApi = exports.WorkspacesClient = exports.WorkspaceUsersClient = exports.UsersClient = exports.ThreadsClient = exports.SearchClient = exports.ReactionsClient = exports.InboxClient = exports.GroupsClient = exports.ConversationsClient = exports.ConversationMessagesClient = exports.CommentsClient = exports.ChannelsClient = exports.AttachmentsClient = void 0;
|
|
17
|
+
exports.closeDefaultDispatcher = exports.CommsApi = exports.WorkspacesClient = exports.WorkspaceUsersClient = exports.UsersClient = exports.ThreadsClient = exports.SearchClient = exports.ReactionsClient = exports.InboxClient = exports.HooksClient = exports.GroupsClient = exports.ConversationsClient = exports.ConversationMessagesClient = exports.CommentsClient = exports.ChannelsClient = exports.AttachmentsClient = void 0;
|
|
18
18
|
__exportStar(require("./authentication"), exports);
|
|
19
19
|
var attachments_client_1 = require("./clients/attachments-client");
|
|
20
20
|
Object.defineProperty(exports, "AttachmentsClient", { enumerable: true, get: function () { return attachments_client_1.AttachmentsClient; } });
|
|
@@ -28,6 +28,8 @@ var conversations_client_1 = require("./clients/conversations-client");
|
|
|
28
28
|
Object.defineProperty(exports, "ConversationsClient", { enumerable: true, get: function () { return conversations_client_1.ConversationsClient; } });
|
|
29
29
|
var groups_client_1 = require("./clients/groups-client");
|
|
30
30
|
Object.defineProperty(exports, "GroupsClient", { enumerable: true, get: function () { return groups_client_1.GroupsClient; } });
|
|
31
|
+
var hooks_client_1 = require("./clients/hooks-client");
|
|
32
|
+
Object.defineProperty(exports, "HooksClient", { enumerable: true, get: function () { return hooks_client_1.HooksClient; } });
|
|
31
33
|
var inbox_client_1 = require("./clients/inbox-client");
|
|
32
34
|
Object.defineProperty(exports, "InboxClient", { enumerable: true, get: function () { return inbox_client_1.InboxClient; } });
|
|
33
35
|
var reactions_client_1 = require("./clients/reactions-client");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SearchResultSchema = exports.SEARCH_RESULT_TYPES = exports.UnreadConversationSchema = exports.UnreadThreadSchema = exports.InboxThreadSchema = exports.ConversationMessageSchema = exports.ConversationMessageObjectSchema = exports.WorkspaceUserSchema = exports.CommentSchema = exports.CommentObjectSchema = exports.ConversationSchema = exports.ConversationObjectSchema = exports.GroupSchema = exports.ThreadSchema = exports.ThreadObjectSchema = exports.ChannelSchema = exports.ChannelObjectSchema = exports.WorkspaceSchema = exports.UserSchema = exports.BaseUserSchema = exports.RequestAttachmentSchema = exports.AttachmentSchema = exports.StatusOkSchema = exports.SystemMessageSchema = void 0;
|
|
3
|
+
exports.SearchResultSchema = exports.SEARCH_RESULT_TYPES = exports.UnreadConversationSchema = exports.UnreadThreadSchema = exports.InboxThreadSchema = exports.ConversationMessageSchema = exports.ConversationMessageObjectSchema = exports.WorkspaceUserSchema = exports.CommentSchema = exports.CommentObjectSchema = exports.ConversationSchema = exports.ConversationObjectSchema = exports.GroupSchema = exports.ThreadSchema = exports.ThreadObjectSchema = exports.ChannelSchema = exports.ChannelObjectSchema = exports.WorkspaceSchema = exports.UserSchema = exports.BaseUserSchema = exports.RequestAttachmentSchema = exports.AttachmentSchema = exports.HookSubscribeResponseSchema = exports.StatusOkSchema = exports.SystemMessageSchema = void 0;
|
|
4
4
|
exports.createChannelSchema = createChannelSchema;
|
|
5
5
|
exports.createThreadSchema = createThreadSchema;
|
|
6
6
|
exports.createConversationSchema = createConversationSchema;
|
|
@@ -27,6 +27,9 @@ exports.SystemMessageSchema = zod_1.z.union([zod_1.z.string(), zod_1.z.unknown()
|
|
|
27
27
|
* mark-read / mark-all-read / mute / clear-unread / etc.
|
|
28
28
|
*/
|
|
29
29
|
exports.StatusOkSchema = zod_1.z.object({ status: zod_1.z.literal('ok') });
|
|
30
|
+
exports.HookSubscribeResponseSchema = exports.StatusOkSchema.extend({
|
|
31
|
+
id: zod_1.z.number().int(),
|
|
32
|
+
});
|
|
30
33
|
// Attachment entity from API. Mirrors the canonical backend shape produced
|
|
31
34
|
// by `unify_attachments` / `validate_file_attachment_json`. Only
|
|
32
35
|
// `attachmentId` and `urlType` are guaranteed; everything else depends on
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.THREAD_ACTIONS = exports.ARCHIVE_FILTER_VALUES = exports.GetOrCreateConversationArgsSchema = exports.GetConversationsArgsSchema = exports.GetCommentsArgsSchema = exports.GetThreadsArgsSchema = exports.GetChannelsArgsSchema = exports.CreateMessageArgsSchema = exports.CreateConversationArgsSchema = exports.UpdateCommentArgsSchema = exports.CreateCommentArgsSchema = exports.UpdateThreadArgsSchema = exports.CreateThreadArgsSchema = exports.UpdateChannelArgsSchema = exports.CreateChannelArgsSchema = void 0;
|
|
3
|
+
exports.THREAD_ACTIONS = exports.UnsubscribeHookArgsSchema = exports.SubscribeHookArgsSchema = exports.SubscribeMessageHookArgsSchema = exports.SubscribeNonMessageHookArgsSchema = exports.SubscribeHookArgsBaseSchema = exports.HookTargetUrlSchema = exports.HookEventSchema = exports.MessageHookEventSchema = exports.NonMessageHookEventSchema = exports.HOOK_EVENTS = exports.MESSAGE_HOOK_EVENTS = exports.NON_MESSAGE_HOOK_EVENTS = exports.ARCHIVE_FILTER_VALUES = exports.GetOrCreateConversationArgsSchema = exports.GetConversationsArgsSchema = exports.GetCommentsArgsSchema = exports.GetThreadsArgsSchema = exports.GetChannelsArgsSchema = exports.CreateMessageArgsSchema = exports.CreateConversationArgsSchema = exports.UpdateCommentArgsSchema = exports.CreateCommentArgsSchema = exports.UpdateThreadArgsSchema = exports.CreateThreadArgsSchema = exports.UpdateChannelArgsSchema = exports.CreateChannelArgsSchema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const entities_1 = require("./entities");
|
|
6
6
|
const enums_1 = require("./enums");
|
|
@@ -113,5 +113,67 @@ exports.GetOrCreateConversationArgsSchema = zod_1.z.object({
|
|
|
113
113
|
});
|
|
114
114
|
// Inbox
|
|
115
115
|
exports.ARCHIVE_FILTER_VALUES = ['active', 'archived', 'all'];
|
|
116
|
+
// Hooks
|
|
117
|
+
exports.NON_MESSAGE_HOOK_EVENTS = [
|
|
118
|
+
'workspace_added',
|
|
119
|
+
'workspace_updated',
|
|
120
|
+
'workspace_deleted',
|
|
121
|
+
'workspace_user_added',
|
|
122
|
+
'workspace_user_updated',
|
|
123
|
+
'workspace_user_removed',
|
|
124
|
+
'channel_added',
|
|
125
|
+
'channel_updated',
|
|
126
|
+
'channel_deleted',
|
|
127
|
+
'channel_user_added',
|
|
128
|
+
'channel_user_removed',
|
|
129
|
+
'thread_added',
|
|
130
|
+
'thread_updated',
|
|
131
|
+
'thread_deleted',
|
|
132
|
+
'comment_added',
|
|
133
|
+
'comment_updated',
|
|
134
|
+
'comment_deleted',
|
|
135
|
+
'group_added',
|
|
136
|
+
'group_updated',
|
|
137
|
+
'group_deleted',
|
|
138
|
+
'group_user_added',
|
|
139
|
+
'group_user_removed',
|
|
140
|
+
];
|
|
141
|
+
exports.MESSAGE_HOOK_EVENTS = ['message_added', 'message_updated'];
|
|
142
|
+
exports.HOOK_EVENTS = [...exports.NON_MESSAGE_HOOK_EVENTS, ...exports.MESSAGE_HOOK_EVENTS];
|
|
143
|
+
exports.NonMessageHookEventSchema = zod_1.z.enum(exports.NON_MESSAGE_HOOK_EVENTS);
|
|
144
|
+
exports.MessageHookEventSchema = zod_1.z.enum(exports.MESSAGE_HOOK_EVENTS);
|
|
145
|
+
exports.HookEventSchema = zod_1.z.enum(exports.HOOK_EVENTS);
|
|
146
|
+
exports.HookTargetUrlSchema = zod_1.z
|
|
147
|
+
.url()
|
|
148
|
+
.max(150)
|
|
149
|
+
.refine((value) => {
|
|
150
|
+
try {
|
|
151
|
+
return new URL(value).protocol === 'https:';
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
}, { message: 'URL must use HTTPS' });
|
|
157
|
+
exports.SubscribeHookArgsBaseSchema = zod_1.z.object({
|
|
158
|
+
targetUrl: exports.HookTargetUrlSchema,
|
|
159
|
+
workspaceId: zod_1.z.number().nullable().optional(),
|
|
160
|
+
channelId: zod_1.z.string().nullable().optional(),
|
|
161
|
+
threadId: zod_1.z.string().nullable().optional(),
|
|
162
|
+
});
|
|
163
|
+
exports.SubscribeNonMessageHookArgsSchema = exports.SubscribeHookArgsBaseSchema.extend({
|
|
164
|
+
event: exports.NonMessageHookEventSchema,
|
|
165
|
+
conversationId: zod_1.z.never().optional(),
|
|
166
|
+
});
|
|
167
|
+
exports.SubscribeMessageHookArgsSchema = exports.SubscribeHookArgsBaseSchema.extend({
|
|
168
|
+
event: exports.MessageHookEventSchema,
|
|
169
|
+
conversationId: zod_1.z.string().nullable().optional(),
|
|
170
|
+
});
|
|
171
|
+
exports.SubscribeHookArgsSchema = zod_1.z.union([
|
|
172
|
+
exports.SubscribeNonMessageHookArgsSchema,
|
|
173
|
+
exports.SubscribeMessageHookArgsSchema,
|
|
174
|
+
]);
|
|
175
|
+
exports.UnsubscribeHookArgsSchema = zod_1.z.object({
|
|
176
|
+
targetUrl: exports.HookTargetUrlSchema,
|
|
177
|
+
});
|
|
116
178
|
// Threads
|
|
117
179
|
exports.THREAD_ACTIONS = ['close', 'reopen'];
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ENDPOINT_HOOKS } from '../consts/endpoints.js';
|
|
2
|
+
import { request } from '../transport/http-client.js';
|
|
3
|
+
import { HookSubscribeResponseSchema, StatusOkSchema, } from '../types/entities.js';
|
|
4
|
+
import { BaseClient } from './base-client.js';
|
|
5
|
+
/**
|
|
6
|
+
* Client for `/api/v1/hooks/`. REST hooks require Todoist OAuth bearer tokens
|
|
7
|
+
* that include Comms audience; session tokens are rejected by the backend.
|
|
8
|
+
*/
|
|
9
|
+
export class HooksClient extends BaseClient {
|
|
10
|
+
/**
|
|
11
|
+
* Subscribes the current OAuth app to a REST hook event.
|
|
12
|
+
*
|
|
13
|
+
* @param args - The hook subscription parameters.
|
|
14
|
+
* @param args.targetUrl - HTTPS endpoint, up to 150 characters, that will receive webhook POSTs.
|
|
15
|
+
* @param args.event - Event name to subscribe to.
|
|
16
|
+
* @param args.workspaceId - Optional workspace filter.
|
|
17
|
+
* @param args.channelId - Optional channel filter.
|
|
18
|
+
* @param args.threadId - Optional thread filter.
|
|
19
|
+
* @param args.conversationId - Optional conversation filter for message events.
|
|
20
|
+
* @returns The `{ status: 'ok', id }` response for the subscription.
|
|
21
|
+
*/
|
|
22
|
+
subscribe(args) {
|
|
23
|
+
return request({
|
|
24
|
+
httpMethod: 'POST',
|
|
25
|
+
baseUri: this.getBaseUri(),
|
|
26
|
+
relativePath: `${ENDPOINT_HOOKS}/subscribe`,
|
|
27
|
+
apiToken: this.apiToken,
|
|
28
|
+
payload: args,
|
|
29
|
+
customFetch: this.customFetch,
|
|
30
|
+
}).then((response) => HookSubscribeResponseSchema.parse(response.data));
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Unsubscribes all hooks with the target URL for the current OAuth app.
|
|
34
|
+
*
|
|
35
|
+
* @param args - The hook unsubscribe parameters.
|
|
36
|
+
* @param args.targetUrl - Target URL to remove.
|
|
37
|
+
*/
|
|
38
|
+
unsubscribe(args) {
|
|
39
|
+
return request({
|
|
40
|
+
httpMethod: 'POST',
|
|
41
|
+
baseUri: this.getBaseUri(),
|
|
42
|
+
relativePath: `${ENDPOINT_HOOKS}/unsubscribe`,
|
|
43
|
+
apiToken: this.apiToken,
|
|
44
|
+
payload: args,
|
|
45
|
+
customFetch: this.customFetch,
|
|
46
|
+
}).then((response) => StatusOkSchema.parse(response.data));
|
|
47
|
+
}
|
|
48
|
+
}
|
package/dist/esm/comms-api.js
CHANGED
|
@@ -4,6 +4,7 @@ import { CommentsClient } from './clients/comments-client.js';
|
|
|
4
4
|
import { ConversationMessagesClient } from './clients/conversation-messages-client.js';
|
|
5
5
|
import { ConversationsClient } from './clients/conversations-client.js';
|
|
6
6
|
import { GroupsClient } from './clients/groups-client.js';
|
|
7
|
+
import { HooksClient } from './clients/hooks-client.js';
|
|
7
8
|
import { InboxClient } from './clients/inbox-client.js';
|
|
8
9
|
import { ReactionsClient } from './clients/reactions-client.js';
|
|
9
10
|
import { SearchClient } from './clients/search-client.js';
|
|
@@ -50,6 +51,7 @@ export class CommsApi {
|
|
|
50
51
|
this.reactions = new ReactionsClient(clientConfig);
|
|
51
52
|
this.search = new SearchClient(clientConfig);
|
|
52
53
|
this.attachments = new AttachmentsClient(clientConfig);
|
|
54
|
+
this.hooks = new HooksClient(clientConfig);
|
|
53
55
|
}
|
|
54
56
|
/**
|
|
55
57
|
* Drains the SDK's process-global connection pool. CLIs and scripts
|
package/dist/esm/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export { CommentsClient } from './clients/comments-client.js';
|
|
|
5
5
|
export { ConversationMessagesClient } from './clients/conversation-messages-client.js';
|
|
6
6
|
export { ConversationsClient } from './clients/conversations-client.js';
|
|
7
7
|
export { GroupsClient } from './clients/groups-client.js';
|
|
8
|
+
export { HooksClient } from './clients/hooks-client.js';
|
|
8
9
|
export { InboxClient } from './clients/inbox-client.js';
|
|
9
10
|
export { ReactionsClient } from './clients/reactions-client.js';
|
|
10
11
|
export { SearchClient } from './clients/search-client.js';
|
|
@@ -17,6 +17,9 @@ export const SystemMessageSchema = z.union([z.string(), z.unknown()]).nullable()
|
|
|
17
17
|
* mark-read / mark-all-read / mute / clear-unread / etc.
|
|
18
18
|
*/
|
|
19
19
|
export const StatusOkSchema = z.object({ status: z.literal('ok') });
|
|
20
|
+
export const HookSubscribeResponseSchema = StatusOkSchema.extend({
|
|
21
|
+
id: z.number().int(),
|
|
22
|
+
});
|
|
20
23
|
// Attachment entity from API. Mirrors the canonical backend shape produced
|
|
21
24
|
// by `unify_attachments` / `validate_file_attachment_json`. Only
|
|
22
25
|
// `attachmentId` and `urlType` are guaranteed; everything else depends on
|
|
@@ -110,5 +110,67 @@ export const GetOrCreateConversationArgsSchema = z.object({
|
|
|
110
110
|
});
|
|
111
111
|
// Inbox
|
|
112
112
|
export const ARCHIVE_FILTER_VALUES = ['active', 'archived', 'all'];
|
|
113
|
+
// Hooks
|
|
114
|
+
export const NON_MESSAGE_HOOK_EVENTS = [
|
|
115
|
+
'workspace_added',
|
|
116
|
+
'workspace_updated',
|
|
117
|
+
'workspace_deleted',
|
|
118
|
+
'workspace_user_added',
|
|
119
|
+
'workspace_user_updated',
|
|
120
|
+
'workspace_user_removed',
|
|
121
|
+
'channel_added',
|
|
122
|
+
'channel_updated',
|
|
123
|
+
'channel_deleted',
|
|
124
|
+
'channel_user_added',
|
|
125
|
+
'channel_user_removed',
|
|
126
|
+
'thread_added',
|
|
127
|
+
'thread_updated',
|
|
128
|
+
'thread_deleted',
|
|
129
|
+
'comment_added',
|
|
130
|
+
'comment_updated',
|
|
131
|
+
'comment_deleted',
|
|
132
|
+
'group_added',
|
|
133
|
+
'group_updated',
|
|
134
|
+
'group_deleted',
|
|
135
|
+
'group_user_added',
|
|
136
|
+
'group_user_removed',
|
|
137
|
+
];
|
|
138
|
+
export const MESSAGE_HOOK_EVENTS = ['message_added', 'message_updated'];
|
|
139
|
+
export const HOOK_EVENTS = [...NON_MESSAGE_HOOK_EVENTS, ...MESSAGE_HOOK_EVENTS];
|
|
140
|
+
export const NonMessageHookEventSchema = z.enum(NON_MESSAGE_HOOK_EVENTS);
|
|
141
|
+
export const MessageHookEventSchema = z.enum(MESSAGE_HOOK_EVENTS);
|
|
142
|
+
export const HookEventSchema = z.enum(HOOK_EVENTS);
|
|
143
|
+
export const HookTargetUrlSchema = z
|
|
144
|
+
.url()
|
|
145
|
+
.max(150)
|
|
146
|
+
.refine((value) => {
|
|
147
|
+
try {
|
|
148
|
+
return new URL(value).protocol === 'https:';
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
}, { message: 'URL must use HTTPS' });
|
|
154
|
+
export const SubscribeHookArgsBaseSchema = z.object({
|
|
155
|
+
targetUrl: HookTargetUrlSchema,
|
|
156
|
+
workspaceId: z.number().nullable().optional(),
|
|
157
|
+
channelId: z.string().nullable().optional(),
|
|
158
|
+
threadId: z.string().nullable().optional(),
|
|
159
|
+
});
|
|
160
|
+
export const SubscribeNonMessageHookArgsSchema = SubscribeHookArgsBaseSchema.extend({
|
|
161
|
+
event: NonMessageHookEventSchema,
|
|
162
|
+
conversationId: z.never().optional(),
|
|
163
|
+
});
|
|
164
|
+
export const SubscribeMessageHookArgsSchema = SubscribeHookArgsBaseSchema.extend({
|
|
165
|
+
event: MessageHookEventSchema,
|
|
166
|
+
conversationId: z.string().nullable().optional(),
|
|
167
|
+
});
|
|
168
|
+
export const SubscribeHookArgsSchema = z.union([
|
|
169
|
+
SubscribeNonMessageHookArgsSchema,
|
|
170
|
+
SubscribeMessageHookArgsSchema,
|
|
171
|
+
]);
|
|
172
|
+
export const UnsubscribeHookArgsSchema = z.object({
|
|
173
|
+
targetUrl: HookTargetUrlSchema,
|
|
174
|
+
});
|
|
113
175
|
// Threads
|
|
114
176
|
export const THREAD_ACTIONS = ['close', 'reopen'];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type HookSubscribeResponse, type StatusOk } from '../types/entities.js';
|
|
2
|
+
import type { SubscribeHookArgs, UnsubscribeHookArgs } from '../types/requests.js';
|
|
3
|
+
import { BaseClient } from './base-client.js';
|
|
4
|
+
/**
|
|
5
|
+
* Client for `/api/v1/hooks/`. REST hooks require Todoist OAuth bearer tokens
|
|
6
|
+
* that include Comms audience; session tokens are rejected by the backend.
|
|
7
|
+
*/
|
|
8
|
+
export declare class HooksClient extends BaseClient {
|
|
9
|
+
/**
|
|
10
|
+
* Subscribes the current OAuth app to a REST hook event.
|
|
11
|
+
*
|
|
12
|
+
* @param args - The hook subscription parameters.
|
|
13
|
+
* @param args.targetUrl - HTTPS endpoint, up to 150 characters, that will receive webhook POSTs.
|
|
14
|
+
* @param args.event - Event name to subscribe to.
|
|
15
|
+
* @param args.workspaceId - Optional workspace filter.
|
|
16
|
+
* @param args.channelId - Optional channel filter.
|
|
17
|
+
* @param args.threadId - Optional thread filter.
|
|
18
|
+
* @param args.conversationId - Optional conversation filter for message events.
|
|
19
|
+
* @returns The `{ status: 'ok', id }` response for the subscription.
|
|
20
|
+
*/
|
|
21
|
+
subscribe(args: SubscribeHookArgs): Promise<HookSubscribeResponse>;
|
|
22
|
+
/**
|
|
23
|
+
* Unsubscribes all hooks with the target URL for the current OAuth app.
|
|
24
|
+
*
|
|
25
|
+
* @param args - The hook unsubscribe parameters.
|
|
26
|
+
* @param args.targetUrl - Target URL to remove.
|
|
27
|
+
*/
|
|
28
|
+
unsubscribe(args: UnsubscribeHookArgs): Promise<StatusOk>;
|
|
29
|
+
}
|
|
@@ -4,6 +4,7 @@ import { CommentsClient } from './clients/comments-client.js';
|
|
|
4
4
|
import { ConversationMessagesClient } from './clients/conversation-messages-client.js';
|
|
5
5
|
import { ConversationsClient } from './clients/conversations-client.js';
|
|
6
6
|
import { GroupsClient } from './clients/groups-client.js';
|
|
7
|
+
import { HooksClient } from './clients/hooks-client.js';
|
|
7
8
|
import { InboxClient } from './clients/inbox-client.js';
|
|
8
9
|
import { ReactionsClient } from './clients/reactions-client.js';
|
|
9
10
|
import { SearchClient } from './clients/search-client.js';
|
|
@@ -46,6 +47,7 @@ export declare class CommsApi {
|
|
|
46
47
|
reactions: ReactionsClient;
|
|
47
48
|
search: SearchClient;
|
|
48
49
|
attachments: AttachmentsClient;
|
|
50
|
+
hooks: HooksClient;
|
|
49
51
|
/**
|
|
50
52
|
* Creates a new Comms API client.
|
|
51
53
|
*
|
|
@@ -23,3 +23,4 @@ export declare const ENDPOINT_REACTIONS = "reactions";
|
|
|
23
23
|
export declare const ENDPOINT_SEARCH = "search";
|
|
24
24
|
export declare const ENDPOINT_CONVERSATION_MESSAGES = "conversation_messages";
|
|
25
25
|
export declare const ENDPOINT_ATTACHMENTS = "attachments";
|
|
26
|
+
export declare const ENDPOINT_HOOKS = "hooks";
|
package/dist/types/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { CommentsClient } from './clients/comments-client.js';
|
|
|
5
5
|
export { ConversationMessagesClient } from './clients/conversation-messages-client.js';
|
|
6
6
|
export { ConversationsClient } from './clients/conversations-client.js';
|
|
7
7
|
export { GroupsClient } from './clients/groups-client.js';
|
|
8
|
+
export { HooksClient } from './clients/hooks-client.js';
|
|
8
9
|
export { InboxClient } from './clients/inbox-client.js';
|
|
9
10
|
export { ReactionsClient } from './clients/reactions-client.js';
|
|
10
11
|
export { SearchClient } from './clients/search-client.js';
|
|
@@ -11,6 +11,11 @@ export declare const StatusOkSchema: z.ZodObject<{
|
|
|
11
11
|
status: z.ZodLiteral<"ok">;
|
|
12
12
|
}, z.core.$strip>;
|
|
13
13
|
export type StatusOk = z.infer<typeof StatusOkSchema>;
|
|
14
|
+
export declare const HookSubscribeResponseSchema: z.ZodObject<{
|
|
15
|
+
status: z.ZodLiteral<"ok">;
|
|
16
|
+
id: z.ZodNumber;
|
|
17
|
+
}, z.core.$strip>;
|
|
18
|
+
export type HookSubscribeResponse = z.infer<typeof HookSubscribeResponseSchema>;
|
|
14
19
|
export declare const AttachmentSchema: z.ZodObject<{
|
|
15
20
|
attachmentId: z.ZodString;
|
|
16
21
|
urlType: z.ZodString;
|
|
@@ -264,6 +264,161 @@ export type GetReactionsArgs = {
|
|
|
264
264
|
commentId?: string;
|
|
265
265
|
messageId?: string;
|
|
266
266
|
};
|
|
267
|
+
export declare const NON_MESSAGE_HOOK_EVENTS: readonly ["workspace_added", "workspace_updated", "workspace_deleted", "workspace_user_added", "workspace_user_updated", "workspace_user_removed", "channel_added", "channel_updated", "channel_deleted", "channel_user_added", "channel_user_removed", "thread_added", "thread_updated", "thread_deleted", "comment_added", "comment_updated", "comment_deleted", "group_added", "group_updated", "group_deleted", "group_user_added", "group_user_removed"];
|
|
268
|
+
export type NonMessageHookEvent = (typeof NON_MESSAGE_HOOK_EVENTS)[number];
|
|
269
|
+
export declare const MESSAGE_HOOK_EVENTS: readonly ["message_added", "message_updated"];
|
|
270
|
+
export type MessageHookEvent = (typeof MESSAGE_HOOK_EVENTS)[number];
|
|
271
|
+
export declare const HOOK_EVENTS: readonly ["workspace_added", "workspace_updated", "workspace_deleted", "workspace_user_added", "workspace_user_updated", "workspace_user_removed", "channel_added", "channel_updated", "channel_deleted", "channel_user_added", "channel_user_removed", "thread_added", "thread_updated", "thread_deleted", "comment_added", "comment_updated", "comment_deleted", "group_added", "group_updated", "group_deleted", "group_user_added", "group_user_removed", "message_added", "message_updated"];
|
|
272
|
+
export type HookEvent = (typeof HOOK_EVENTS)[number];
|
|
273
|
+
export declare const NonMessageHookEventSchema: z.ZodEnum<{
|
|
274
|
+
workspace_added: "workspace_added";
|
|
275
|
+
workspace_updated: "workspace_updated";
|
|
276
|
+
workspace_deleted: "workspace_deleted";
|
|
277
|
+
workspace_user_added: "workspace_user_added";
|
|
278
|
+
workspace_user_updated: "workspace_user_updated";
|
|
279
|
+
workspace_user_removed: "workspace_user_removed";
|
|
280
|
+
channel_added: "channel_added";
|
|
281
|
+
channel_updated: "channel_updated";
|
|
282
|
+
channel_deleted: "channel_deleted";
|
|
283
|
+
channel_user_added: "channel_user_added";
|
|
284
|
+
channel_user_removed: "channel_user_removed";
|
|
285
|
+
thread_added: "thread_added";
|
|
286
|
+
thread_updated: "thread_updated";
|
|
287
|
+
thread_deleted: "thread_deleted";
|
|
288
|
+
comment_added: "comment_added";
|
|
289
|
+
comment_updated: "comment_updated";
|
|
290
|
+
comment_deleted: "comment_deleted";
|
|
291
|
+
group_added: "group_added";
|
|
292
|
+
group_updated: "group_updated";
|
|
293
|
+
group_deleted: "group_deleted";
|
|
294
|
+
group_user_added: "group_user_added";
|
|
295
|
+
group_user_removed: "group_user_removed";
|
|
296
|
+
}>;
|
|
297
|
+
export declare const MessageHookEventSchema: z.ZodEnum<{
|
|
298
|
+
message_added: "message_added";
|
|
299
|
+
message_updated: "message_updated";
|
|
300
|
+
}>;
|
|
301
|
+
export declare const HookEventSchema: z.ZodEnum<{
|
|
302
|
+
workspace_added: "workspace_added";
|
|
303
|
+
workspace_updated: "workspace_updated";
|
|
304
|
+
workspace_deleted: "workspace_deleted";
|
|
305
|
+
workspace_user_added: "workspace_user_added";
|
|
306
|
+
workspace_user_updated: "workspace_user_updated";
|
|
307
|
+
workspace_user_removed: "workspace_user_removed";
|
|
308
|
+
channel_added: "channel_added";
|
|
309
|
+
channel_updated: "channel_updated";
|
|
310
|
+
channel_deleted: "channel_deleted";
|
|
311
|
+
channel_user_added: "channel_user_added";
|
|
312
|
+
channel_user_removed: "channel_user_removed";
|
|
313
|
+
thread_added: "thread_added";
|
|
314
|
+
thread_updated: "thread_updated";
|
|
315
|
+
thread_deleted: "thread_deleted";
|
|
316
|
+
comment_added: "comment_added";
|
|
317
|
+
comment_updated: "comment_updated";
|
|
318
|
+
comment_deleted: "comment_deleted";
|
|
319
|
+
group_added: "group_added";
|
|
320
|
+
group_updated: "group_updated";
|
|
321
|
+
group_deleted: "group_deleted";
|
|
322
|
+
group_user_added: "group_user_added";
|
|
323
|
+
group_user_removed: "group_user_removed";
|
|
324
|
+
message_added: "message_added";
|
|
325
|
+
message_updated: "message_updated";
|
|
326
|
+
}>;
|
|
327
|
+
export declare const HookTargetUrlSchema: z.ZodURL;
|
|
328
|
+
export declare const SubscribeHookArgsBaseSchema: z.ZodObject<{
|
|
329
|
+
targetUrl: z.ZodURL;
|
|
330
|
+
workspaceId: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
331
|
+
channelId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
332
|
+
threadId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
333
|
+
}, z.core.$strip>;
|
|
334
|
+
export declare const SubscribeNonMessageHookArgsSchema: z.ZodObject<{
|
|
335
|
+
targetUrl: z.ZodURL;
|
|
336
|
+
workspaceId: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
337
|
+
channelId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
338
|
+
threadId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
339
|
+
event: z.ZodEnum<{
|
|
340
|
+
workspace_added: "workspace_added";
|
|
341
|
+
workspace_updated: "workspace_updated";
|
|
342
|
+
workspace_deleted: "workspace_deleted";
|
|
343
|
+
workspace_user_added: "workspace_user_added";
|
|
344
|
+
workspace_user_updated: "workspace_user_updated";
|
|
345
|
+
workspace_user_removed: "workspace_user_removed";
|
|
346
|
+
channel_added: "channel_added";
|
|
347
|
+
channel_updated: "channel_updated";
|
|
348
|
+
channel_deleted: "channel_deleted";
|
|
349
|
+
channel_user_added: "channel_user_added";
|
|
350
|
+
channel_user_removed: "channel_user_removed";
|
|
351
|
+
thread_added: "thread_added";
|
|
352
|
+
thread_updated: "thread_updated";
|
|
353
|
+
thread_deleted: "thread_deleted";
|
|
354
|
+
comment_added: "comment_added";
|
|
355
|
+
comment_updated: "comment_updated";
|
|
356
|
+
comment_deleted: "comment_deleted";
|
|
357
|
+
group_added: "group_added";
|
|
358
|
+
group_updated: "group_updated";
|
|
359
|
+
group_deleted: "group_deleted";
|
|
360
|
+
group_user_added: "group_user_added";
|
|
361
|
+
group_user_removed: "group_user_removed";
|
|
362
|
+
}>;
|
|
363
|
+
conversationId: z.ZodOptional<z.ZodNever>;
|
|
364
|
+
}, z.core.$strip>;
|
|
365
|
+
export declare const SubscribeMessageHookArgsSchema: z.ZodObject<{
|
|
366
|
+
targetUrl: z.ZodURL;
|
|
367
|
+
workspaceId: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
368
|
+
channelId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
369
|
+
threadId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
370
|
+
event: z.ZodEnum<{
|
|
371
|
+
message_added: "message_added";
|
|
372
|
+
message_updated: "message_updated";
|
|
373
|
+
}>;
|
|
374
|
+
conversationId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
375
|
+
}, z.core.$strip>;
|
|
376
|
+
export declare const SubscribeHookArgsSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
377
|
+
targetUrl: z.ZodURL;
|
|
378
|
+
workspaceId: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
379
|
+
channelId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
380
|
+
threadId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
381
|
+
event: z.ZodEnum<{
|
|
382
|
+
workspace_added: "workspace_added";
|
|
383
|
+
workspace_updated: "workspace_updated";
|
|
384
|
+
workspace_deleted: "workspace_deleted";
|
|
385
|
+
workspace_user_added: "workspace_user_added";
|
|
386
|
+
workspace_user_updated: "workspace_user_updated";
|
|
387
|
+
workspace_user_removed: "workspace_user_removed";
|
|
388
|
+
channel_added: "channel_added";
|
|
389
|
+
channel_updated: "channel_updated";
|
|
390
|
+
channel_deleted: "channel_deleted";
|
|
391
|
+
channel_user_added: "channel_user_added";
|
|
392
|
+
channel_user_removed: "channel_user_removed";
|
|
393
|
+
thread_added: "thread_added";
|
|
394
|
+
thread_updated: "thread_updated";
|
|
395
|
+
thread_deleted: "thread_deleted";
|
|
396
|
+
comment_added: "comment_added";
|
|
397
|
+
comment_updated: "comment_updated";
|
|
398
|
+
comment_deleted: "comment_deleted";
|
|
399
|
+
group_added: "group_added";
|
|
400
|
+
group_updated: "group_updated";
|
|
401
|
+
group_deleted: "group_deleted";
|
|
402
|
+
group_user_added: "group_user_added";
|
|
403
|
+
group_user_removed: "group_user_removed";
|
|
404
|
+
}>;
|
|
405
|
+
conversationId: z.ZodOptional<z.ZodNever>;
|
|
406
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
407
|
+
targetUrl: z.ZodURL;
|
|
408
|
+
workspaceId: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
409
|
+
channelId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
410
|
+
threadId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
411
|
+
event: z.ZodEnum<{
|
|
412
|
+
message_added: "message_added";
|
|
413
|
+
message_updated: "message_updated";
|
|
414
|
+
}>;
|
|
415
|
+
conversationId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
416
|
+
}, z.core.$strip>]>;
|
|
417
|
+
export type SubscribeHookArgs = z.infer<typeof SubscribeHookArgsSchema>;
|
|
418
|
+
export declare const UnsubscribeHookArgsSchema: z.ZodObject<{
|
|
419
|
+
targetUrl: z.ZodURL;
|
|
420
|
+
}, z.core.$strip>;
|
|
421
|
+
export type UnsubscribeHookArgs = z.infer<typeof UnsubscribeHookArgsSchema>;
|
|
267
422
|
export type AddChannelUserArgs = {
|
|
268
423
|
id: string;
|
|
269
424
|
userId: number;
|