@guayaba/workflow-piece-googlechat 0.1.3
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/.eslintrc.json +33 -0
- package/README.md +5 -0
- package/assets/logo.png +0 -0
- package/package.json +22 -0
- package/src/i18n/de.json +52 -0
- package/src/i18n/es.json +52 -0
- package/src/i18n/fr.json +52 -0
- package/src/i18n/ja.json +52 -0
- package/src/i18n/nl.json +52 -0
- package/src/i18n/pt.json +52 -0
- package/src/i18n/translation.json +52 -0
- package/src/i18n/zh.json +52 -0
- package/src/index.ts +33 -0
- package/src/lib/actions/add-a-space-member.ts +31 -0
- package/src/lib/actions/find-member.ts +60 -0
- package/src/lib/actions/get-direct-message-details.ts +27 -0
- package/src/lib/actions/get-message.ts +30 -0
- package/src/lib/actions/search-messages.ts +45 -0
- package/src/lib/actions/send-a-message.ts +110 -0
- package/src/lib/common/constants.ts +22 -0
- package/src/lib/common/index.ts +17 -0
- package/src/lib/common/props.ts +332 -0
- package/src/lib/common/requests.ts +480 -0
- package/src/lib/common/schemas.ts +147 -0
- package/src/lib/triggers/new-mention.ts +111 -0
- package/src/lib/triggers/new-message.ts +86 -0
- package/tsconfig.json +20 -0
- package/tsconfig.lib.json +13 -0
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
import { HttpMethod, httpClient } from '@guayaba/workflows-common';
|
|
2
|
+
import { GOOGLE_SERVICE_ENTITIES } from './constants';
|
|
3
|
+
|
|
4
|
+
async function fireHttpRequest({
|
|
5
|
+
method,
|
|
6
|
+
path,
|
|
7
|
+
entity,
|
|
8
|
+
body,
|
|
9
|
+
accessToken,
|
|
10
|
+
}: {
|
|
11
|
+
accessToken: string;
|
|
12
|
+
method: HttpMethod;
|
|
13
|
+
path: string;
|
|
14
|
+
entity: keyof typeof GOOGLE_SERVICE_ENTITIES;
|
|
15
|
+
body?: unknown;
|
|
16
|
+
}) {
|
|
17
|
+
const BASE_URL = `https://${GOOGLE_SERVICE_ENTITIES[entity]}.googleapis.com`;
|
|
18
|
+
|
|
19
|
+
return await httpClient
|
|
20
|
+
.sendRequest({
|
|
21
|
+
method,
|
|
22
|
+
url: `${BASE_URL}${path}`,
|
|
23
|
+
headers: {
|
|
24
|
+
Accept: 'application/json',
|
|
25
|
+
'Content-Type': 'application/json',
|
|
26
|
+
Authorization: `Bearer ${accessToken}`,
|
|
27
|
+
},
|
|
28
|
+
body,
|
|
29
|
+
})
|
|
30
|
+
.then((res) => res.body)
|
|
31
|
+
.catch((err) => {
|
|
32
|
+
throw new Error(err);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const googleChatAPIService = {
|
|
37
|
+
async fetchProjects(accessToken: string) {
|
|
38
|
+
const response = await fireHttpRequest({
|
|
39
|
+
method: HttpMethod.GET,
|
|
40
|
+
path: '/v1/projects',
|
|
41
|
+
entity: 'cloudresourcemanager',
|
|
42
|
+
accessToken,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
return response.projects;
|
|
46
|
+
},
|
|
47
|
+
async sendMessage({
|
|
48
|
+
accessToken,
|
|
49
|
+
spaceId,
|
|
50
|
+
text,
|
|
51
|
+
thread,
|
|
52
|
+
messageReplyOption,
|
|
53
|
+
customMessageId,
|
|
54
|
+
isPrivate,
|
|
55
|
+
privateMessageViewer,
|
|
56
|
+
}: {
|
|
57
|
+
accessToken: string;
|
|
58
|
+
spaceId: string;
|
|
59
|
+
text: string;
|
|
60
|
+
thread?: string;
|
|
61
|
+
messageReplyOption?: string;
|
|
62
|
+
customMessageId?: string;
|
|
63
|
+
isPrivate?: boolean;
|
|
64
|
+
privateMessageViewer?: string;
|
|
65
|
+
}) {
|
|
66
|
+
const body: any = { text };
|
|
67
|
+
|
|
68
|
+
if (thread) {
|
|
69
|
+
body.thread = { name: thread };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (messageReplyOption) {
|
|
73
|
+
body.messageReplyOption = messageReplyOption;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (customMessageId) {
|
|
77
|
+
const cleanId = customMessageId.toLowerCase().replace(/[^a-z0-9-]/g, '');
|
|
78
|
+
body.messageId = `client-${cleanId}`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (isPrivate && privateMessageViewer) {
|
|
82
|
+
body.privateMessageViewer = { name: privateMessageViewer };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return await fireHttpRequest({
|
|
86
|
+
method: HttpMethod.POST,
|
|
87
|
+
entity: 'chat',
|
|
88
|
+
accessToken,
|
|
89
|
+
path: `/v1/${spaceId}/messages`,
|
|
90
|
+
body,
|
|
91
|
+
});
|
|
92
|
+
},
|
|
93
|
+
async AddASpaceMember({
|
|
94
|
+
accessToken,
|
|
95
|
+
spaceId,
|
|
96
|
+
userId,
|
|
97
|
+
}: {
|
|
98
|
+
accessToken: string;
|
|
99
|
+
spaceId: string;
|
|
100
|
+
userId: string;
|
|
101
|
+
}) {
|
|
102
|
+
return await fireHttpRequest({
|
|
103
|
+
method: HttpMethod.POST,
|
|
104
|
+
accessToken: accessToken,
|
|
105
|
+
entity: 'chat',
|
|
106
|
+
path: `/v1/${spaceId}/members`,
|
|
107
|
+
body: {
|
|
108
|
+
member: {
|
|
109
|
+
name: userId,
|
|
110
|
+
type: 'HUMAN',
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
},
|
|
115
|
+
async getMessage(accessToken: string, messageName: string) {
|
|
116
|
+
return await fireHttpRequest({
|
|
117
|
+
method: HttpMethod.GET,
|
|
118
|
+
entity: 'chat',
|
|
119
|
+
accessToken,
|
|
120
|
+
path: `/v1/${messageName}`,
|
|
121
|
+
});
|
|
122
|
+
},
|
|
123
|
+
async getSpace({
|
|
124
|
+
accessToken,
|
|
125
|
+
spaceId,
|
|
126
|
+
}: {
|
|
127
|
+
accessToken: string;
|
|
128
|
+
spaceId: string;
|
|
129
|
+
}) {
|
|
130
|
+
return await fireHttpRequest({
|
|
131
|
+
method: HttpMethod.GET,
|
|
132
|
+
entity: 'chat',
|
|
133
|
+
path: `/v1/${spaceId}`,
|
|
134
|
+
accessToken,
|
|
135
|
+
});
|
|
136
|
+
},
|
|
137
|
+
async listMessages(
|
|
138
|
+
accessToken: string,
|
|
139
|
+
spaceId: string,
|
|
140
|
+
pageSize = 50
|
|
141
|
+
) {
|
|
142
|
+
return await fireHttpRequest({
|
|
143
|
+
method: HttpMethod.GET,
|
|
144
|
+
entity: 'chat',
|
|
145
|
+
accessToken,
|
|
146
|
+
path: `/v1/${spaceId}/messages?pageSize=${pageSize}`,
|
|
147
|
+
});
|
|
148
|
+
},
|
|
149
|
+
async fetchAllSpaces(accessToken: string) {
|
|
150
|
+
const response = await fireHttpRequest({
|
|
151
|
+
method: HttpMethod.GET,
|
|
152
|
+
path: `/v1/spaces`,
|
|
153
|
+
entity: 'chat',
|
|
154
|
+
accessToken,
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
return response.spaces;
|
|
158
|
+
},
|
|
159
|
+
async fetchSpaces(accessToken: string) {
|
|
160
|
+
const filter = encodeURIComponent('spaceType = "SPACE"');
|
|
161
|
+
const response = await fireHttpRequest({
|
|
162
|
+
method: HttpMethod.GET,
|
|
163
|
+
path: `/v1/spaces?filter=${filter}`,
|
|
164
|
+
entity: 'chat',
|
|
165
|
+
accessToken,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
return response.spaces;
|
|
169
|
+
},
|
|
170
|
+
async fetchDirectMessages(accessToken: string) {
|
|
171
|
+
const filter = encodeURIComponent('spaceType = "DIRECT_MESSAGE"');
|
|
172
|
+
const response = await fireHttpRequest({
|
|
173
|
+
method: HttpMethod.GET,
|
|
174
|
+
path: `/v1/spaces?filter=${filter}`,
|
|
175
|
+
entity: 'chat',
|
|
176
|
+
accessToken,
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
return response.spaces;
|
|
180
|
+
},
|
|
181
|
+
async fetchThreads(accessToken: string, spaceId: string) {
|
|
182
|
+
const response = await fireHttpRequest({
|
|
183
|
+
method: HttpMethod.GET,
|
|
184
|
+
path: `/v1/${spaceId}/messages?pageSize=50`,
|
|
185
|
+
entity: 'chat',
|
|
186
|
+
accessToken,
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const threads = new Map();
|
|
190
|
+
response.messages?.forEach((message: any) => {
|
|
191
|
+
if (message.thread && message.thread.name && !message.threadReply) {
|
|
192
|
+
threads.set(message.thread.name, {
|
|
193
|
+
name: message.thread.name,
|
|
194
|
+
displayName: message.text?.substring(0, 50) + (message.text?.length > 50 ? '...' : ''),
|
|
195
|
+
lastActivity: message.createTime,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
return Array.from(threads.values());
|
|
201
|
+
},
|
|
202
|
+
async fetchSpaceMembers(accessToken: string, spaceId: string) {
|
|
203
|
+
const response = await fireHttpRequest({
|
|
204
|
+
method: HttpMethod.GET,
|
|
205
|
+
path: `/v1/${spaceId}/members`,
|
|
206
|
+
entity: 'chat',
|
|
207
|
+
accessToken,
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
return response.memberships;
|
|
211
|
+
},
|
|
212
|
+
async fetchPeople(accessToken: string) {
|
|
213
|
+
const response = await fireHttpRequest({
|
|
214
|
+
method: HttpMethod.GET,
|
|
215
|
+
path: `/v1/people:listDirectoryPeople?sources=DIRECTORY_SOURCE_TYPE_DOMAIN_PROFILE&sources=DIRECTORY_SOURCE_TYPE_DOMAIN_CONTACT&readMask=names,emailAddresses`,
|
|
216
|
+
entity: 'people',
|
|
217
|
+
accessToken,
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
return response.people;
|
|
221
|
+
},
|
|
222
|
+
async deleteWorkspaceEventsSubscription({
|
|
223
|
+
accessToken,
|
|
224
|
+
subscriptionName,
|
|
225
|
+
}: {
|
|
226
|
+
accessToken: string;
|
|
227
|
+
subscriptionName: string;
|
|
228
|
+
}) {
|
|
229
|
+
return await fireHttpRequest({
|
|
230
|
+
method: HttpMethod.DELETE,
|
|
231
|
+
entity: 'workspaceevents',
|
|
232
|
+
accessToken,
|
|
233
|
+
path: `/v1/${subscriptionName}`,
|
|
234
|
+
});
|
|
235
|
+
},
|
|
236
|
+
async grantTopicPermissions({
|
|
237
|
+
accessToken,
|
|
238
|
+
projectId,
|
|
239
|
+
topicName,
|
|
240
|
+
}: {
|
|
241
|
+
accessToken: string;
|
|
242
|
+
projectId: string;
|
|
243
|
+
topicName: string;
|
|
244
|
+
}) {
|
|
245
|
+
const policy = {
|
|
246
|
+
bindings: [
|
|
247
|
+
{
|
|
248
|
+
role: 'roles/pubsub.publisher',
|
|
249
|
+
members: [`serviceAccount:chat-api-push@system.gserviceaccount.com`],
|
|
250
|
+
},
|
|
251
|
+
],
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
return await fireHttpRequest({
|
|
255
|
+
method: HttpMethod.POST,
|
|
256
|
+
entity: 'pubsub',
|
|
257
|
+
accessToken,
|
|
258
|
+
path: `/v1/projects/${projectId}/topics/${topicName}:setIamPolicy`,
|
|
259
|
+
body: { policy },
|
|
260
|
+
});
|
|
261
|
+
},
|
|
262
|
+
async createPubSubTopic({
|
|
263
|
+
accessToken,
|
|
264
|
+
projectId,
|
|
265
|
+
topicName,
|
|
266
|
+
}: {
|
|
267
|
+
accessToken: string;
|
|
268
|
+
projectId: string;
|
|
269
|
+
topicName: string;
|
|
270
|
+
}) {
|
|
271
|
+
return await fireHttpRequest({
|
|
272
|
+
method: HttpMethod.PUT,
|
|
273
|
+
entity: 'pubsub',
|
|
274
|
+
accessToken,
|
|
275
|
+
path: `/v1/projects/${projectId}/topics/${topicName}`,
|
|
276
|
+
});
|
|
277
|
+
},
|
|
278
|
+
async deletePubSubTopic({
|
|
279
|
+
accessToken,
|
|
280
|
+
projectId,
|
|
281
|
+
topicName,
|
|
282
|
+
}: {
|
|
283
|
+
accessToken: string;
|
|
284
|
+
projectId: string;
|
|
285
|
+
topicName: string;
|
|
286
|
+
}) {
|
|
287
|
+
return await fireHttpRequest({
|
|
288
|
+
method: HttpMethod.DELETE,
|
|
289
|
+
entity: 'pubsub',
|
|
290
|
+
accessToken,
|
|
291
|
+
path: `/v1/projects/${projectId}/topics/${topicName}`,
|
|
292
|
+
});
|
|
293
|
+
},
|
|
294
|
+
async createWorkspaceEventsSubscription({
|
|
295
|
+
accessToken,
|
|
296
|
+
projectId,
|
|
297
|
+
subscriptionName,
|
|
298
|
+
targetResource,
|
|
299
|
+
eventTypes,
|
|
300
|
+
topicName,
|
|
301
|
+
includeResource = false,
|
|
302
|
+
}: {
|
|
303
|
+
accessToken: string;
|
|
304
|
+
projectId: string;
|
|
305
|
+
subscriptionName: string;
|
|
306
|
+
targetResource: string;
|
|
307
|
+
eventTypes: string[];
|
|
308
|
+
topicName: string;
|
|
309
|
+
includeResource?: boolean;
|
|
310
|
+
}) {
|
|
311
|
+
const subscription = {
|
|
312
|
+
targetResource,
|
|
313
|
+
eventTypes,
|
|
314
|
+
notificationEndpoint: {
|
|
315
|
+
pubsubTopic: `projects/${projectId}/topics/${topicName}`,
|
|
316
|
+
},
|
|
317
|
+
payloadOptions: {
|
|
318
|
+
includeResource,
|
|
319
|
+
},
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
return await fireHttpRequest({
|
|
323
|
+
method: HttpMethod.POST,
|
|
324
|
+
entity: 'workspaceevents',
|
|
325
|
+
accessToken,
|
|
326
|
+
path: `/v1/subscriptions`,
|
|
327
|
+
body: subscription,
|
|
328
|
+
});
|
|
329
|
+
},
|
|
330
|
+
async createPubSubSubscription({
|
|
331
|
+
accessToken,
|
|
332
|
+
projectId,
|
|
333
|
+
subscriptionName,
|
|
334
|
+
topicName,
|
|
335
|
+
pushEndpoint,
|
|
336
|
+
}: {
|
|
337
|
+
accessToken: string;
|
|
338
|
+
projectId: string;
|
|
339
|
+
subscriptionName: string;
|
|
340
|
+
topicName: string;
|
|
341
|
+
pushEndpoint: string;
|
|
342
|
+
}) {
|
|
343
|
+
const subscription = {
|
|
344
|
+
topic: `projects/${projectId}/topics/${topicName}`,
|
|
345
|
+
pushConfig: {
|
|
346
|
+
pushEndpoint,
|
|
347
|
+
},
|
|
348
|
+
ackDeadlineSeconds: 600,
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
return await fireHttpRequest({
|
|
352
|
+
method: HttpMethod.PUT,
|
|
353
|
+
entity: 'pubsub',
|
|
354
|
+
accessToken,
|
|
355
|
+
path: `/v1/projects/${projectId}/subscriptions/${subscriptionName}`,
|
|
356
|
+
body: subscription,
|
|
357
|
+
});
|
|
358
|
+
},
|
|
359
|
+
async createWebhookSubscription({
|
|
360
|
+
accessToken,
|
|
361
|
+
projectId,
|
|
362
|
+
topic,
|
|
363
|
+
subscriptionName,
|
|
364
|
+
webhookUrl,
|
|
365
|
+
eventTypes,
|
|
366
|
+
targetResource,
|
|
367
|
+
}: {
|
|
368
|
+
accessToken: string;
|
|
369
|
+
projectId: string;
|
|
370
|
+
topic: string;
|
|
371
|
+
webhookUrl: string;
|
|
372
|
+
subscriptionName: string;
|
|
373
|
+
eventTypes: string[];
|
|
374
|
+
targetResource: string;
|
|
375
|
+
}) {
|
|
376
|
+
const workspaceSubscription = await this.createWorkspaceEventsSubscription({
|
|
377
|
+
accessToken,
|
|
378
|
+
projectId,
|
|
379
|
+
subscriptionName,
|
|
380
|
+
targetResource,
|
|
381
|
+
eventTypes,
|
|
382
|
+
topicName: topic,
|
|
383
|
+
includeResource: true,
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
const pubsubSubscription = await this.createPubSubSubscription({
|
|
387
|
+
accessToken,
|
|
388
|
+
projectId,
|
|
389
|
+
subscriptionName,
|
|
390
|
+
topicName: topic,
|
|
391
|
+
pushEndpoint: webhookUrl,
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
return {
|
|
395
|
+
workspaceSubscription,
|
|
396
|
+
pubsubSubscription,
|
|
397
|
+
};
|
|
398
|
+
},
|
|
399
|
+
async deletePubSubSubscription({
|
|
400
|
+
accessToken,
|
|
401
|
+
projectId,
|
|
402
|
+
subscriptionName,
|
|
403
|
+
}: {
|
|
404
|
+
accessToken: string;
|
|
405
|
+
projectId: string;
|
|
406
|
+
subscriptionName: string;
|
|
407
|
+
}) {
|
|
408
|
+
return await fireHttpRequest({
|
|
409
|
+
method: HttpMethod.DELETE,
|
|
410
|
+
entity: 'pubsub',
|
|
411
|
+
accessToken,
|
|
412
|
+
path: `/v1/projects/${projectId}/subscriptions/${subscriptionName}`,
|
|
413
|
+
});
|
|
414
|
+
},
|
|
415
|
+
async deleteWebhookSubscription({
|
|
416
|
+
accessToken,
|
|
417
|
+
projectId,
|
|
418
|
+
subscriptionName,
|
|
419
|
+
topicName,
|
|
420
|
+
event_type,
|
|
421
|
+
}: {
|
|
422
|
+
accessToken: string;
|
|
423
|
+
projectId: string;
|
|
424
|
+
subscriptionName: string;
|
|
425
|
+
topicName: string;
|
|
426
|
+
event_type: string;
|
|
427
|
+
}) {
|
|
428
|
+
return await this.cleanupWebhookResources({
|
|
429
|
+
accessToken,
|
|
430
|
+
projectId,
|
|
431
|
+
event_type,
|
|
432
|
+
});
|
|
433
|
+
},
|
|
434
|
+
async fetchWorkSpaceSubscriptions({
|
|
435
|
+
accessToken,
|
|
436
|
+
event_type,
|
|
437
|
+
}: {
|
|
438
|
+
accessToken: string;
|
|
439
|
+
event_type: string;
|
|
440
|
+
}) {
|
|
441
|
+
const response = await fireHttpRequest({
|
|
442
|
+
method: HttpMethod.GET,
|
|
443
|
+
entity: 'workspaceevents',
|
|
444
|
+
accessToken,
|
|
445
|
+
path: `/v1/subscriptions?filter=event_types:"${event_type}"`,
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
return response.subscriptions;
|
|
449
|
+
},
|
|
450
|
+
async cleanupWebhookResources({
|
|
451
|
+
accessToken,
|
|
452
|
+
projectId,
|
|
453
|
+
event_type,
|
|
454
|
+
}: {
|
|
455
|
+
accessToken: string;
|
|
456
|
+
projectId: string;
|
|
457
|
+
event_type: string;
|
|
458
|
+
}) {
|
|
459
|
+
try {
|
|
460
|
+
const workspaceSubscriptions = await this.fetchWorkSpaceSubscriptions({
|
|
461
|
+
accessToken,
|
|
462
|
+
event_type,
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
for (const sub of workspaceSubscriptions || []) {
|
|
466
|
+
try {
|
|
467
|
+
await this.deleteWorkspaceEventsSubscription({
|
|
468
|
+
accessToken,
|
|
469
|
+
subscriptionName: sub.name,
|
|
470
|
+
});
|
|
471
|
+
} catch (err: any) {
|
|
472
|
+
console.log(err);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
} catch (err: any) {
|
|
476
|
+
console.error('Error cleaning up workspace subscriptions:', err);
|
|
477
|
+
throw err;
|
|
478
|
+
}
|
|
479
|
+
},
|
|
480
|
+
};
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import z from 'zod';
|
|
2
|
+
|
|
3
|
+
export const sendMessageSchema = {
|
|
4
|
+
spaceId: z.string().min(1, 'Space ID is required'),
|
|
5
|
+
text: z.string().min(1, 'Message text is required'),
|
|
6
|
+
thread: z.string().optional(),
|
|
7
|
+
messageReplyOption: z.enum([
|
|
8
|
+
'REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD',
|
|
9
|
+
'REPLY_MESSAGE_OR_FAIL'
|
|
10
|
+
]).optional(),
|
|
11
|
+
customMessageId: z.string().regex(
|
|
12
|
+
/^[a-z0-9-]+$/,
|
|
13
|
+
'Custom message ID must contain only lowercase letters, numbers, and hyphens'
|
|
14
|
+
).max(63, 'Custom message ID must be 63 characters or less').optional(),
|
|
15
|
+
isPrivate: z.boolean().optional(),
|
|
16
|
+
privateMessageViewer: z.string().optional(),
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const spaceIdSchema = z.string().regex(
|
|
20
|
+
/^spaces\/[a-zA-Z0-9_-]+$/,
|
|
21
|
+
'Space ID must be in format: spaces/{space}'
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
export const threadIdSchema = z.string().regex(
|
|
25
|
+
/^spaces\/[a-zA-Z0-9_-]+\/threads\/[a-zA-Z0-9_-]+$/,
|
|
26
|
+
'Thread ID must be in format: spaces/{space}/threads/{thread}'
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
export const userResourceNameSchema = z.string().regex(
|
|
30
|
+
/^people\/[a-zA-Z0-9_-]+$/,
|
|
31
|
+
'User resource name must be in format: people/{person}'
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
export const customMessageIdSchema = z.string()
|
|
35
|
+
.regex(
|
|
36
|
+
/^client-[a-z0-9-]+$/,
|
|
37
|
+
'Custom message ID must start with "client-" and contain only lowercase letters, numbers, and hyphens'
|
|
38
|
+
)
|
|
39
|
+
.max(63, 'Custom message ID must be 63 characters or less');
|
|
40
|
+
|
|
41
|
+
export const messageTextSchema = z.string()
|
|
42
|
+
.min(1, 'Message text cannot be empty')
|
|
43
|
+
.max(32000, 'Message text cannot exceed 32,000 characters');
|
|
44
|
+
|
|
45
|
+
export const validateSpaceFromDropdown = z.object({
|
|
46
|
+
value: spaceIdSchema,
|
|
47
|
+
label: z.string(),
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export const validateThreadFromDropdown = z.object({
|
|
51
|
+
value: z.union([z.literal(''), threadIdSchema]),
|
|
52
|
+
label: z.string(),
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
export const validateUserFromDropdown = z.object({
|
|
56
|
+
value: userResourceNameSchema,
|
|
57
|
+
label: z.string(),
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
export const getMessageSchema = {
|
|
61
|
+
name: z.string()
|
|
62
|
+
.min(1, 'Message resource name is required')
|
|
63
|
+
.regex(
|
|
64
|
+
/^spaces\/[a-zA-Z0-9_-]+\/messages\/[a-zA-Z0-9_-]+$/,
|
|
65
|
+
'Message resource name must be in format: spaces/{space}/messages/{message}'
|
|
66
|
+
),
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const addSpaceMemberSchema = {
|
|
70
|
+
spaceId: z.string()
|
|
71
|
+
.min(1, 'Space ID is required')
|
|
72
|
+
.regex(
|
|
73
|
+
/^spaces\/[a-zA-Z0-9_-]+$/,
|
|
74
|
+
'Space ID must be in format: spaces/{space}'
|
|
75
|
+
),
|
|
76
|
+
personId: z.string()
|
|
77
|
+
.min(1, 'Person ID is required')
|
|
78
|
+
.regex(
|
|
79
|
+
/^people\/[a-zA-Z0-9_-]+$/,
|
|
80
|
+
'Person ID must be in format: people/{person}'
|
|
81
|
+
),
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export const findMemberSchema = {
|
|
85
|
+
spaceId: z.string()
|
|
86
|
+
.min(1, 'Space ID is required')
|
|
87
|
+
.regex(
|
|
88
|
+
/^spaces\/[a-zA-Z0-9_-]+$/,
|
|
89
|
+
'Space ID must be in format: spaces/{space}'
|
|
90
|
+
),
|
|
91
|
+
email: z.string()
|
|
92
|
+
.min(1, 'Email is required')
|
|
93
|
+
.email('Please enter a valid email address'),
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export const searchMessagesSchema = {
|
|
97
|
+
spaceId: z.string()
|
|
98
|
+
.min(1, 'Space ID is required')
|
|
99
|
+
.regex(
|
|
100
|
+
/^spaces\/[a-zA-Z0-9_-]+$/,
|
|
101
|
+
'Space ID must be in format: spaces/{space}'
|
|
102
|
+
),
|
|
103
|
+
keyword: z.string()
|
|
104
|
+
.min(1, 'Search keyword is required')
|
|
105
|
+
.min(2, 'Search keyword must be at least 2 characters long'),
|
|
106
|
+
limit: z.number()
|
|
107
|
+
.min(1, 'Limit must be at least 1')
|
|
108
|
+
.max(1000, 'Limit cannot exceed 1000')
|
|
109
|
+
.optional(),
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export const getDirectMessageDetailsSchema = {
|
|
113
|
+
directMessageId: z.string()
|
|
114
|
+
.min(1, 'Direct message ID is required')
|
|
115
|
+
.regex(
|
|
116
|
+
/^spaces\/[a-zA-Z0-9_-]+$/,
|
|
117
|
+
'Direct message ID must be in format: spaces/{space}'
|
|
118
|
+
),
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export const newMessageTriggerSchema = {
|
|
122
|
+
projectId: z.string()
|
|
123
|
+
.min(1, 'Project ID is required'),
|
|
124
|
+
spaceId: z.string()
|
|
125
|
+
.regex(
|
|
126
|
+
/^spaces\/[a-zA-Z0-9_-]+$/,
|
|
127
|
+
'Space ID must be in format: spaces/{space}'
|
|
128
|
+
)
|
|
129
|
+
.optional(),
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export const newMentionTriggerSchema = {
|
|
133
|
+
projectId: z.string()
|
|
134
|
+
.min(1, 'Project ID is required'),
|
|
135
|
+
spaceId: z.string()
|
|
136
|
+
.regex(
|
|
137
|
+
/^spaces\/[a-zA-Z0-9_-]+$/,
|
|
138
|
+
'Space ID must be in format: spaces/{space}'
|
|
139
|
+
)
|
|
140
|
+
.optional(),
|
|
141
|
+
spaceMemberId: z.string()
|
|
142
|
+
.regex(
|
|
143
|
+
/^users\/[a-zA-Z0-9_-]+$/,
|
|
144
|
+
'Space member ID must be in format: users/{user}'
|
|
145
|
+
)
|
|
146
|
+
.optional(),
|
|
147
|
+
};
|