@periskope/types 0.6.386 → 0.6.389

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.
@@ -1,983 +1,983 @@
1
- import { Merge, OverrideProperties } from 'type-fest';
2
- import { AppendTypes } from './rules.types';
3
- import { Tables } from './supabase.types';
4
- import { TaskType } from './types';
5
-
6
- /***************************** WORKFLOWS *****************************/
7
-
8
- export type NormalWorkflowActions = {
9
- id: string;
10
- action_metadata: NormalWorkflowActionTypes;
11
- next: string | null;
12
- };
13
-
14
- export type SplitPathActions = {
15
- id: string;
16
- action_metadata: SplitPathWorkflowAction;
17
- };
18
-
19
- export type WorkflowAction = NormalWorkflowActions | SplitPathActions;
20
-
21
- export type WorkflowType = OverrideProperties<
22
- Tables<'tbl_org_workflows'>,
23
- {
24
- trigger_metadata: {
25
- org_phones: string[];
26
- allow_internal_messages?: boolean;
27
- first_action_id: string | null;
28
- };
29
- trigger: Triggers;
30
- actions: Array<NormalWorkflowActions | SplitPathActions>;
31
- }
32
- >;
33
-
34
- export function isNormalWorkflowAction(
35
- workflow_action:
36
- | WorkflowType['actions'][number]
37
- | {
38
- trigger_metadata?: WorkflowType['trigger_metadata'];
39
- trigger: WorkflowType['trigger'];
40
- }
41
- | {}
42
- ): workflow_action is NormalWorkflowActions {
43
- return (
44
- 'action_metadata' in workflow_action &&
45
- workflow_action?.action_metadata?.type !== 'split_path'
46
- );
47
- }
48
-
49
- export function isSplitPathAction(
50
- workflow_action: WorkflowType['actions'][number]
51
- ): workflow_action is SplitPathActions {
52
- return workflow_action.action_metadata.type === 'split_path';
53
- }
54
-
55
- /***************************** CONDITIONS TYPES *****************************/
56
-
57
- // {
58
- // "operator": "AND",
59
- // "conditions": [
60
- // {
61
- // "id": "cond1",
62
- // "variable_name": "message",
63
- // "variable_type": "string",
64
- // "condition": "CONTAINS",
65
- // "value": "urgent"
66
- // },
67
- // {
68
- // "operator": "OR",
69
- // "conditions": [
70
- // {
71
- // "id": "cond2",
72
- // "variable_name": "priority",
73
- // "variable_type": "number",
74
- // "condition": "GT",
75
- // "value": 2
76
- // },
77
- // {
78
- // "id": "cond3",
79
- // "variable_name": "assigned",
80
- // "variable_type": "boolean",
81
- // "condition": "NKNOWN"
82
- // }
83
- // ]
84
- // }
85
- // ]
86
- // }
87
-
88
- enum Conditions {
89
- // string
90
- CONTAINS = 'contains',
91
- NCONTAINS = 'not contains',
92
- EQUALS = 'equals',
93
- NEQUALS = 'not equals',
94
- STARTS_WITH = 'starts with',
95
- ENDS_WITH = 'ends with',
96
-
97
- // number, date, time
98
- GREATER_THAN = 'greater than',
99
- GREATER_THAN_OR_EQUAL = 'greater than or equal',
100
- LESS_THAN = 'less than',
101
- LESS_THAN_OR_EQUAL = 'less than or equal',
102
-
103
- // none
104
- IS_KNOWN = 'is known',
105
- IS_UNKNOWN = 'is unknown',
106
-
107
- // boolean
108
- IS = 'is',
109
- IS_NOT = 'is not',
110
-
111
- // array
112
- IS_ANY_OF = 'is any of',
113
- IS_NOT_ANY_OF = 'is not any of',
114
-
115
- // day
116
- ON = 'on',
117
- }
118
-
119
- type BaseCondition<T extends Triggers> = {
120
- id: string;
121
- variable_name: keyof WorkflowDataType<T>;
122
- };
123
-
124
- type StringCondition = BaseCondition<Triggers> & {
125
- condition:
126
- | 'CONTAINS'
127
- | 'NCONTAINS'
128
- | 'EQUALS'
129
- | 'NEQUALS'
130
- | 'STARTS_WITH'
131
- | 'ENDS_WITH';
132
- value: string;
133
- variable_type: 'string';
134
- };
135
-
136
- type DateTimeNumberCondition = BaseCondition<Triggers> & {
137
- condition:
138
- | 'GREATER_THAN'
139
- | 'GREATER_THAN_OR_EQUAL'
140
- | 'LESS_THAN'
141
- | 'LESS_THAN_OR_EQUAL';
142
- } & (
143
- | {
144
- value: string;
145
- variable_type: 'number';
146
- }
147
- | {
148
- value: string;
149
- timezone: string;
150
- variable_type: 'date' | 'time';
151
- }
152
- );
153
-
154
- type ExistsCondition = BaseCondition<Triggers> & {
155
- condition: 'IS_KNOWN' | 'IS_UNKNOWN';
156
- value: undefined | null;
157
- variable_type: null;
158
- };
159
-
160
- type OnCondition = BaseCondition<Triggers> & {
161
- condition: 'ON';
162
- value: string | string[];
163
- timezone: string;
164
- variable_type: 'day';
165
- };
166
-
167
- type BooleanCondition = BaseCondition<Triggers> & {
168
- condition: 'IS' | 'IS_NOT';
169
- value: boolean | 'true' | 'false';
170
- variable_type: 'boolean';
171
- };
172
-
173
- type ArrayCondition = BaseCondition<Triggers> & {
174
- condition: 'IS_ANY_OF' | 'IS_NOT_ANY_OF';
175
- value: string[];
176
- variable_type: 'array';
177
- };
178
-
179
- export type ConditionLeaf =
180
- | StringCondition
181
- | DateTimeNumberCondition
182
- | ExistsCondition
183
- | OnCondition
184
- | BooleanCondition
185
- | ArrayCondition;
186
-
187
- type ConditionOperator = 'AND' | 'OR';
188
-
189
- export type WorkflowConditionGroup = {
190
- operator: ConditionOperator;
191
- conditions: Array<ConditionLeaf | WorkflowConditionGroup>;
192
- };
193
-
194
- export function isConditionLeaf(
195
- condition: ConditionLeaf | WorkflowConditionGroup
196
- ): condition is ConditionLeaf {
197
- return 'id' in condition && !('operator' in condition);
198
- }
199
-
200
- /***************************** WORKFLOW DATA TYPES *****************************/
201
-
202
- export type WorkflowRawDataTypes = {
203
- message: Tables<'tbl_chat_messages'>;
204
- reaction: Tables<'tbl_chat_reactions'>;
205
- chat: Merge<
206
- Merge<Tables<'tbl_chats'>, Tables<'tbl_chat_properties'>>,
207
- {
208
- has_flagged_messages: boolean;
209
- last_message_self: boolean;
210
- members: string[];
211
- }
212
- >;
213
- chat_label: Tables<'tbl_chat_properties'>;
214
- ticket: Tables<'tbl_chat_tickets'>;
215
- task: TaskType;
216
- sender: Tables<'tbl_contacts'> & Tables<'tbl_chat_participants'>;
217
- };
218
-
219
- export type GetMessageWorkflowDataTypes = {
220
- message: WorkflowRawDataTypes['message'];
221
- sender: WorkflowRawDataTypes['sender'];
222
- chat: WorkflowRawDataTypes['chat'];
223
- };
224
-
225
- export type GetChatWorkflowDataTypes = {
226
- chat: WorkflowRawDataTypes['chat'];
227
- };
228
-
229
- export type GetTicketWorkflowDataTypes = {
230
- ticket: WorkflowRawDataTypes['ticket'];
231
- message: WorkflowRawDataTypes['message'];
232
- sender: WorkflowRawDataTypes['sender'];
233
- chat: WorkflowRawDataTypes['chat'];
234
- };
235
-
236
- export type GetTaskWorkflowDataTypes = {
237
- task: WorkflowRawDataTypes['task'];
238
- associated_object: TaskType['associated_object_metadata'];
239
- };
240
-
241
- export type GetReactionWorkflowDataTypes = {
242
- reaction: WorkflowRawDataTypes['reaction'];
243
- sender: WorkflowRawDataTypes['sender'];
244
- message: WorkflowRawDataTypes['message'];
245
- chat: WorkflowRawDataTypes['chat'];
246
- };
247
-
248
- export type MessageWorkflowDataTypes = AppendTypes<
249
- {
250
- message: WorkflowRawDataTypes['message'];
251
- sender: WorkflowRawDataTypes['sender'];
252
- chat: WorkflowRawDataTypes['chat'];
253
- },
254
- '.'
255
- >;
256
-
257
- export type ReactionWorkflowDataTypes = AppendTypes<
258
- {
259
- reaction: WorkflowRawDataTypes['reaction'];
260
- sender: WorkflowRawDataTypes['sender'];
261
- message: WorkflowRawDataTypes['message'];
262
- chat: WorkflowRawDataTypes['chat'];
263
- },
264
- '.'
265
- >;
266
-
267
- export type TicketWorkflowDataTypes = AppendTypes<
268
- {
269
- ticket: WorkflowRawDataTypes['ticket'];
270
- message: WorkflowRawDataTypes['message'];
271
- sender: WorkflowRawDataTypes['sender'];
272
- chat: WorkflowRawDataTypes['chat'];
273
- },
274
- '.'
275
- >;
276
-
277
- export type TaskWorkflowDataTypes = AppendTypes<
278
- {
279
- task: WorkflowRawDataTypes['task'];
280
- associated_object: TaskType['associated_object_metadata'];
281
- },
282
- '.'
283
- >;
284
-
285
- export type ChatWorkflowDataTypes = AppendTypes<
286
- {
287
- chat: WorkflowRawDataTypes['chat'];
288
- },
289
- '.'
290
- >;
291
-
292
- export enum Triggers {
293
- MESSAGE_CREATED = 'message.created',
294
- MESSAGE_UPDATED = 'message.updated',
295
- MESSAGE_DELETED = 'message.deleted',
296
- MESSAGE_FLAGGED = 'message.flagged',
297
- MESSAGE_UNFLAGGED = 'message.unflagged',
298
- REACTION_ADDED = 'reaction.added',
299
- TICKET_CREATED = 'ticket.created',
300
- TICKET_UPDATED = 'ticket.updated',
301
- TICKET_DELETED = 'ticket.deleted',
302
- TICKET_CLOSED = 'ticket.closed',
303
- TICKET_DUE = 'ticket.due',
304
- CHAT_CREATED = 'chat.created',
305
- CHAT_LABEL_UPDATED = 'chat.label.updated',
306
- CHAT_CLOSED = 'chat.closed',
307
- TASK_CREATED = 'task.created',
308
- TASK_DUE = 'task.due',
309
- }
310
-
311
- export type WorkflowDataType<T extends Triggers = Triggers> = T extends
312
- | Triggers.MESSAGE_CREATED
313
- | Triggers.MESSAGE_DELETED
314
- | Triggers.MESSAGE_UPDATED
315
- | Triggers.MESSAGE_FLAGGED
316
- | Triggers.MESSAGE_UNFLAGGED
317
- ? MessageWorkflowDataTypes
318
- : T extends
319
- | Triggers.CHAT_CREATED
320
- | Triggers.CHAT_LABEL_UPDATED
321
- | Triggers.CHAT_CLOSED
322
- ? ChatWorkflowDataTypes
323
- : T extends
324
- | Triggers.TICKET_CREATED
325
- | Triggers.TICKET_UPDATED
326
- | Triggers.TICKET_DELETED
327
- | Triggers.TICKET_CLOSED
328
- | Triggers.TICKET_DUE
329
- ? TicketWorkflowDataTypes
330
- : T extends Triggers.REACTION_ADDED
331
- ? ReactionWorkflowDataTypes
332
- : T extends Triggers.TASK_CREATED | Triggers.TASK_DUE
333
- ? TaskWorkflowDataTypes
334
- : never;
335
-
336
- /***************************** ACTION TYPES *****************************/
337
-
338
- export type SendMessageToChatWorkflowAction = {
339
- type: 'send_message_to_chat';
340
- metadata: {
341
- message: string;
342
- media?: {
343
- url: string;
344
- type: 'image' | 'video' | 'audio' | 'document';
345
- name: string;
346
- } | null;
347
- debounce?: `${number} ${'seconds' | 'minutes' | 'hours' | 'days'}` | null;
348
- chat_id: `${string}${'@g.us' | '@c.us'}` | 'trigger_chat' | null;
349
- unflag_chat?: boolean;
350
- as_reply?: boolean;
351
- };
352
- };
353
-
354
- export type CreateTicketWorkflowAction = {
355
- type: 'create_ticket';
356
- metadata: {
357
- subject: string | null;
358
- assignee:
359
- | {
360
- round_robin: true;
361
- emails: string[];
362
- assignee_check_for?: 'shift_times' | 'online_offline' | 'all';
363
- }
364
- | {
365
- email: string | null;
366
- round_robin: false;
367
- };
368
- priority?: '0' | '1' | '2' | '3' | '4';
369
- status: 'open' | 'inprogress' | 'closed';
370
- labels: string[];
371
- due_in: `${number} ${'seconds' | 'minutes' | 'hours' | 'days'}` | null;
372
- };
373
- };
374
-
375
- export type AttachToLatestTicket = {
376
- type: 'attach_to_latest_ticket';
377
- metadata: {
378
- status: ('open' | 'inprogress' | 'closed')[];
379
- };
380
- };
381
-
382
- export type NotifyHTTPWorkflowAction = {
383
- type: 'notify_http';
384
- metadata: {
385
- url: string;
386
- method: 'GET' | 'POST' | 'PUT' | 'DELETE';
387
- headers: Record<string, string>;
388
- body: string;
389
- };
390
- };
391
-
392
- export type FlagMessageWorkflowAction = {
393
- type: 'flag_message';
394
- metadata: {};
395
- };
396
-
397
- export type UnflagMessageWorkflowAction = {
398
- type: 'unflag_message';
399
- metadata: {};
400
- };
401
-
402
- export type AssignTicketWorkflowAction = {
403
- type: 'assign_ticket';
404
- metadata: {
405
- assignee:
406
- | {
407
- round_robin: true;
408
- emails: string[];
409
- assignee_check_for?: 'shift_times' | 'online_offline' | 'all';
410
- }
411
- | {
412
- email: string | null;
413
- round_robin: false;
414
- };
415
- };
416
- };
417
-
418
- export type CloseTicketWorkflowAction = {
419
- type: 'close_ticket';
420
- metadata: {
421
- bypass_mandatory_fields?: boolean;
422
- closing_note: string;
423
- };
424
- };
425
-
426
- export type AddChatLabelWorkflowAction = {
427
- type: 'add_chat_label';
428
- metadata: {
429
- labels: string[];
430
- };
431
- };
432
-
433
- export type RemoveChatLabelWorkflowAction = {
434
- type: 'remove_chat_label';
435
- metadata: {
436
- labels: string[];
437
- };
438
- };
439
-
440
- export type AddTicketLabelWorkflowAction = {
441
- type: 'add_ticket_label';
442
- metadata: {
443
- labels: string[];
444
- };
445
- };
446
-
447
- export type RemoveTicketLabelWorkflowAction = {
448
- type: 'remove_ticket_label';
449
- metadata: {
450
- labels: string[];
451
- };
452
- };
453
-
454
- export type AssignChatWorkflowAction = {
455
- type: 'assign_chat';
456
- metadata: {
457
- assignee:
458
- | {
459
- round_robin: true;
460
- emails: string[];
461
- assignee_check_for?: 'shift_times' | 'online_offline' | 'all';
462
- }
463
- | {
464
- email: string | null;
465
- round_robin: false;
466
- };
467
- };
468
- };
469
-
470
- type ChatIdType = `${string}${'@g.us' | '@c.us'}`;
471
-
472
- export type ForwardMessageWorkflowAction = {
473
- type: 'forward_message';
474
- metadata: {
475
- chat_id: `${ChatIdType}${`;${ChatIdType}`}` | null;
476
- };
477
- };
478
-
479
- export type SendEmailWorkflowAction = {
480
- type: 'send_email';
481
- metadata: {
482
- email: string;
483
- subject: string;
484
- body: string;
485
- };
486
- };
487
-
488
- export type DeleteMessageWorkflowAction = {
489
- type: 'delete_message';
490
- metadata: {};
491
- };
492
-
493
- export type CloseChatWorkflowAction = {
494
- type: 'close_chat';
495
- metadata: {};
496
- };
497
-
498
- export type ValidateWorkflowAction = {
499
- type: 'validate_action';
500
- metadata: WorkflowConditionGroup;
501
- };
502
-
503
- export type DelayWorkflowAction = {
504
- type: 'delay';
505
- metadata: {
506
- delay: `${number} ${'seconds' | 'minutes' | 'hours' | 'days'}`;
507
- };
508
- };
509
-
510
- export type SendSlackNotificationWorkflowAction = {
511
- type: 'send_slack_notification';
512
- metadata: {
513
- slack_payload: string;
514
- url: string;
515
- };
516
- };
517
-
518
- export type SplitPathWorkflowAction = {
519
- type: 'split_path';
520
- metadata: {
521
- paths: Array<{
522
- id: string;
523
- condition_action_id: string;
524
- }>;
525
- };
526
- };
527
-
528
- // experimental
529
- export type AIPromptWorkflowAction = {
530
- type: 'ai_prompt';
531
- metadata: {
532
- query: string;
533
- body: string;
534
- };
535
- };
536
-
537
- export type NormalWorkflowActionTypes =
538
- | SendMessageToChatWorkflowAction
539
- | CreateTicketWorkflowAction
540
- | AttachToLatestTicket
541
- | NotifyHTTPWorkflowAction
542
- | FlagMessageWorkflowAction
543
- | UnflagMessageWorkflowAction
544
- | AssignTicketWorkflowAction
545
- | CloseTicketWorkflowAction
546
- | AddChatLabelWorkflowAction
547
- | RemoveChatLabelWorkflowAction
548
- | AddTicketLabelWorkflowAction
549
- | RemoveTicketLabelWorkflowAction
550
- | AssignChatWorkflowAction
551
- | ForwardMessageWorkflowAction
552
- | SendEmailWorkflowAction
553
- | DeleteMessageWorkflowAction
554
- | CloseChatWorkflowAction
555
- | ValidateWorkflowAction
556
- | DelayWorkflowAction
557
- | SendSlackNotificationWorkflowAction
558
- | AIPromptWorkflowAction;
559
-
560
- export type WorkflowActionsTypeMap = {
561
- send_message_to_chat: SendMessageToChatWorkflowAction;
562
- create_ticket: CreateTicketWorkflowAction;
563
- attach_to_latest_ticket: AttachToLatestTicket;
564
- notify_http: NotifyHTTPWorkflowAction;
565
- flag_message: FlagMessageWorkflowAction;
566
- unflag_message: UnflagMessageWorkflowAction;
567
- assign_ticket: AssignTicketWorkflowAction;
568
- close_ticket: CloseTicketWorkflowAction;
569
- add_chat_label: AddChatLabelWorkflowAction;
570
- remove_chat_label: RemoveChatLabelWorkflowAction;
571
- add_ticket_label: AddTicketLabelWorkflowAction;
572
- remove_ticket_label: RemoveTicketLabelWorkflowAction;
573
- assign_chat: AssignChatWorkflowAction;
574
- forward_message: ForwardMessageWorkflowAction;
575
- send_email: SendEmailWorkflowAction;
576
- delete_message: DeleteMessageWorkflowAction;
577
- close_chat: CloseChatWorkflowAction;
578
- validate_action: ValidateWorkflowAction;
579
- delay: DelayWorkflowAction;
580
- send_slack_notification: SendSlackNotificationWorkflowAction;
581
- ai_prompt: AIPromptWorkflowAction;
582
- split_path: SplitPathWorkflowAction;
583
- };
584
-
585
- export type WorkflowActionTypes =
586
- | NormalWorkflowActionTypes
587
- | SplitPathWorkflowAction;
588
-
589
- export type WorkflowActionCategory =
590
- | 'message'
591
- | 'ticket'
592
- | 'chat'
593
- | 'custom'
594
- | 'flow'
595
- | 'ai';
596
-
597
- export const ActionCategoryMap: Record<
598
- WorkflowActionTypes['type'],
599
- WorkflowActionCategory
600
- > = {
601
- send_message_to_chat: 'message',
602
- create_ticket: 'ticket',
603
- attach_to_latest_ticket: 'ticket',
604
- notify_http: 'custom',
605
- flag_message: 'message',
606
- unflag_message: 'message',
607
- assign_ticket: 'ticket',
608
- close_ticket: 'ticket',
609
- add_chat_label: 'chat',
610
- remove_chat_label: 'chat',
611
- add_ticket_label: 'ticket',
612
- remove_ticket_label: 'ticket',
613
- assign_chat: 'chat',
614
- forward_message: 'message',
615
- send_email: 'custom',
616
- delete_message: 'message',
617
- close_chat: 'chat',
618
- validate_action: 'flow',
619
- delay: 'flow',
620
- send_slack_notification: 'custom',
621
- ai_prompt: 'ai',
622
- split_path: 'flow',
623
- };
624
-
625
- export const CategoryNameMap: Record<WorkflowActionCategory, string> = {
626
- message: 'Message',
627
- ticket: 'Ticket',
628
- chat: 'Chat',
629
- custom: 'Custom',
630
- flow: 'Flow',
631
- ai: 'AI',
632
- };
633
-
634
- export const TriggerNameMap: Record<Triggers, string> = {
635
- 'chat.closed': 'Chat Closed',
636
- 'chat.created': 'Chat Created',
637
- 'chat.label.updated': 'Chat Label Updated',
638
- 'message.created': 'Message Created',
639
- 'message.deleted': 'Message Deleted',
640
- 'message.flagged': 'Message Flagged',
641
- 'message.unflagged': 'Message Unflagged',
642
- 'message.updated': 'Message Updated',
643
- 'reaction.added': 'Reaction Added',
644
- 'ticket.closed': 'Ticket Closed',
645
- 'ticket.created': 'Ticket Created',
646
- 'ticket.deleted': 'Ticket Deleted',
647
- 'ticket.due': 'Ticket Due',
648
- 'ticket.updated': 'Ticket Updated',
649
- 'task.created': 'Task Created',
650
- 'task.due': 'Task Due',
651
- };
652
-
653
- export const WorkflowActionNameMap: Record<
654
- WorkflowType['actions'][number]['action_metadata']['type'],
655
- {
656
- title: string;
657
- description: string;
658
- }
659
- > = {
660
- add_chat_label: {
661
- title: 'Add Chat Label',
662
- description: 'Add a label to the trigger chat',
663
- },
664
- add_ticket_label: {
665
- title: 'Add Ticket Label',
666
- description: 'Add a label to the trigger ticket',
667
- },
668
- assign_chat: {
669
- title: 'Assign Chat',
670
- description: 'Assign a chat to org user',
671
- },
672
- attach_to_latest_ticket: {
673
- title: 'Attach to Latest Ticket',
674
- description: 'Attach to the latest ticket of trigger chat',
675
- },
676
- close_chat: {
677
- title: 'Close Chat',
678
- description: 'Close the chat',
679
- },
680
- close_ticket: {
681
- title: 'Close Ticket',
682
- description: 'Close the trigger ticket or ticket attached to the message',
683
- },
684
- create_ticket: {
685
- title: 'Create Ticket',
686
- description: 'Create a ticket attached to the trigger message',
687
- },
688
- delay: {
689
- title: 'Delay',
690
- description: 'Add a delay to next sequential actions',
691
- },
692
- ai_prompt: {
693
- title: 'AI Prompt',
694
- description: 'Analyse, filter, categorise, and generate text using AI',
695
- },
696
- flag_message: {
697
- title: 'Flag Message',
698
- description: 'Flag the trigger message or message attached to the ticket',
699
- },
700
- remove_chat_label: {
701
- title: 'Remove Chat Label',
702
- description: 'Remove a label from the trigger chat',
703
- },
704
- remove_ticket_label: {
705
- title: 'Remove Ticket Label',
706
- description:
707
- 'Remove a label from the trigger ticket or ticket attached to the message',
708
- },
709
- send_email: {
710
- title: 'Send Email',
711
- description: 'Send custom text to an email',
712
- },
713
- send_message_to_chat: {
714
- title: 'Send Message to Chat',
715
- description: 'Send a message to the chat attached to the trigger',
716
- },
717
- send_slack_notification: {
718
- title: 'Send Slack Notification',
719
- description: 'Send a slack notification',
720
- },
721
- split_path: {
722
- title: 'Split Path',
723
- description: 'Split the workflow path based on the condition',
724
- },
725
- unflag_message: {
726
- title: 'Unflag Message',
727
- description: 'Unflag the trigger message or message attached to the ticket',
728
- },
729
- validate_action: {
730
- title: 'Validate Action',
731
- description: 'Validate the action based on multiple criterias',
732
- },
733
- notify_http: {
734
- title: 'Notify HTTP',
735
- description: 'Send a custom HTTP request to an endpoint',
736
- },
737
- assign_ticket: {
738
- title: 'Assign Ticket',
739
- description: 'Assign a ticket to an org user',
740
- },
741
- forward_message: {
742
- title: 'Forward Message',
743
- description: 'Forward a message to a chat',
744
- },
745
- delete_message: {
746
- title: 'Delete Message',
747
- description: 'Delete the trigger message or message attached to the ticket',
748
- },
749
- };
750
-
751
- export type SendMessageToChatActionReturnInfo = {
752
- message_details: {
753
- queue_id: string;
754
- queue_position: number;
755
- };
756
- };
757
-
758
- export type CreateTicketActionReturnInfo = {
759
- ticket_details: Tables<'tbl_chat_tickets'>;
760
- };
761
-
762
- export type AssignChatActionReturnInfo = {
763
- chat_details: {
764
- chat_id: string;
765
- assigned_to: string;
766
- org_id: string;
767
- };
768
- };
769
-
770
- export type AddChatLabelActionReturnInfo = {
771
- chat_details: {
772
- chat_id: string;
773
- org_id: string;
774
- labels: string[];
775
- };
776
- };
777
-
778
- export type NotifyHTTPActionReturnInfo = {
779
- status: number | 'Unknown';
780
- data: Record<string, unknown>;
781
- error: any;
782
- };
783
-
784
- export type ForwardMessageActionReturnInfo = {
785
- [key: string]: boolean;
786
- };
787
-
788
- export type DeleteMessageActionReturnInfo = {};
789
-
790
- export type AssignTicketActionReturnInfo = Tables<'tbl_chat_tickets'>;
791
- export type CloseTicketActionReturnInfo = Tables<'tbl_chat_tickets'>;
792
-
793
- export type AIPromptActionReturnInfo = {
794
- query: string;
795
- input: string;
796
- output: string | Record<string, unknown> | boolean | null;
797
- };
798
-
799
- export type ActionInfo = {
800
- send_message_to_chat: SendMessageToChatActionReturnInfo;
801
- create_ticket: CreateTicketActionReturnInfo;
802
- assign_chat: AssignChatActionReturnInfo;
803
- add_chat_label: AddChatLabelActionReturnInfo;
804
- notify_http: NotifyHTTPActionReturnInfo;
805
- forward_message: ForwardMessageActionReturnInfo;
806
- delete_message: DeleteMessageActionReturnInfo;
807
- assign_ticket: AssignTicketActionReturnInfo;
808
- close_ticket: CloseTicketActionReturnInfo;
809
- ai_prompt: AIPromptActionReturnInfo;
810
- };
811
-
812
- // Example workflow type ->
813
-
814
- // const demoWorkflow: WorkflowType = {
815
- // id: 'workflow-1',
816
- // name: 'Urgent Chat Auto-Responder',
817
- // trigger: Triggers.MESSAGE_CREATED,
818
- // trigger_metadata: {
819
- // org_phones: ['phone-1'],
820
- // allow_internal_messages: false,
821
- // first_action_id: 'action-validate',
822
- // },
823
- // actions: [
824
- // {
825
- // id: 'action-validate',
826
- // action_metadata: {
827
- // type: 'validate_action',
828
- // metadata: {
829
- // operator: 'AND',
830
- // conditions: [
831
- // {
832
- // id: 'cond-1',
833
- // variable_name: 'message.text',
834
- // variable_type: 'string',
835
- // condition: 'CONTAINS',
836
- // value: 'urgent',
837
- // },
838
- // {
839
- // id: 'cond-2',
840
- // variable_name: 'chat.assigned',
841
- // variable_type: 'boolean',
842
- // condition: 'IS',
843
- // value: false,
844
- // },
845
- // ],
846
- // },
847
- // },
848
- // next: 'action-add-label',
849
- // },
850
- // {
851
- // id: 'action-add-label',
852
- // action_metadata: {
853
- // type: 'add_chat_label',
854
- // metadata: {
855
- // labels: ['urgent'],
856
- // },
857
- // },
858
- // next: 'action-assign-chat',
859
- // },
860
- // {
861
- // id: 'action-assign-chat',
862
- // action_metadata: {
863
- // type: 'assign_chat',
864
- // metadata: {
865
- // assignee: {
866
- // round_robin: true,
867
- // emails: ['agent1@example.com', 'agent2@example.com'],
868
- // assignee_check_for: 'all',
869
- // },
870
- // },
871
- // },
872
- // next: 'action-delay',
873
- // },
874
- // {
875
- // id: 'action-delay',
876
- // action_metadata: {
877
- // type: 'delay',
878
- // metadata: {
879
- // delay: '5 minutes',
880
- // },
881
- // },
882
- // next: 'action-send-message',
883
- // },
884
- // {
885
- // id: 'action-send-message',
886
- // action_metadata: {
887
- // type: 'send_message_to_chat',
888
- // metadata: {
889
- // message: 'We’re on it!',
890
- // chat_id: 'trigger_chat',
891
- // },
892
- // },
893
- // next: 'action-split',
894
- // },
895
- // {
896
- // id: 'action-split',
897
- // action_metadata: {
898
- // type: 'split_path',
899
- // metadata: {
900
- // paths: [
901
- // {
902
- // id: 'path-flagged',
903
- // condition_action_id: 'action-condition-flagged',
904
- // },
905
- // {
906
- // id: 'path-not-flagged',
907
- // condition_action_id: 'action-condition-not-flagged',
908
- // },
909
- // ],
910
- // },
911
- // },
912
- // {
913
- // id: 'action-condition-flagged',
914
- // action_metadata: {
915
- // type: 'validate_action',
916
- // metadata: {
917
- // operator: 'AND',
918
- // conditions: [
919
- // {
920
- // id: 'cond-flagged',
921
- // variable_name: 'chat.has_flagged_messages',
922
- // variable_type: 'boolean',
923
- // condition: 'IS',
924
- // value: true,
925
- // },
926
- // ],
927
- // },
928
- // },
929
- // next: 'action-create-ticket',
930
- // },
931
- // {
932
- // id: 'action-condition-not-flagged',
933
- // action_metadata: {
934
- // type: 'validate_action',
935
- // metadata: {
936
- // operator: 'AND',
937
- // conditions: [
938
- // {
939
- // id: 'cond-unflagged',
940
- // variable_name: 'chat.has_flagged_messages',
941
- // variable_type: 'boolean',
942
- // condition: 'IS',
943
- // value: false,
944
- // },
945
- // ],
946
- // },
947
- // },
948
- // next: 'action-send-slack',
949
- // },
950
- // {
951
- // id: 'action-create-ticket',
952
- // action_metadata: {
953
- // type: 'create_ticket',
954
- // metadata: {
955
- // subject: 'Urgent Chat Follow-up',
956
- // assignee: {
957
- // email: 'manager@example.com',
958
- // },
959
- // priority: '4',
960
- // status: 'open',
961
- // labels: ['urgent', 'auto-created'],
962
- // due_date: '30 minutes',
963
- // },
964
- // },
965
- // next: '', // End
966
- // },
967
- // {
968
- // id: 'action-send-slack',
969
- // action_metadata: {
970
- // type: 'send_slack_notification',
971
- // metadata: {
972
- // slack_payload: JSON.stringify({
973
- // text: 'An urgent chat was received, no flagged messages.',
974
- // }),
975
- // url: 'https://hooks.slack.com/services/XXX/YYY/ZZZ',
976
- // },
977
- // },
978
- // next: '', // End
979
- // },
980
- // ],
981
- // };
982
-
983
- /***************************** WORKFLOW FE TYPES @harshgour *****************************/
1
+ import { Merge, OverrideProperties } from 'type-fest';
2
+ import { AppendTypes } from './rules.types';
3
+ import { Tables } from './supabase.types';
4
+ import { TaskType } from './types';
5
+
6
+ /***************************** WORKFLOWS *****************************/
7
+
8
+ export type NormalWorkflowActions = {
9
+ id: string;
10
+ action_metadata: NormalWorkflowActionTypes;
11
+ next: string | null;
12
+ };
13
+
14
+ export type SplitPathActions = {
15
+ id: string;
16
+ action_metadata: SplitPathWorkflowAction;
17
+ };
18
+
19
+ export type WorkflowAction = NormalWorkflowActions | SplitPathActions;
20
+
21
+ export type WorkflowType = OverrideProperties<
22
+ Tables<'tbl_org_workflows'>,
23
+ {
24
+ trigger_metadata: {
25
+ org_phones: string[];
26
+ allow_internal_messages?: boolean;
27
+ first_action_id: string | null;
28
+ };
29
+ trigger: Triggers;
30
+ actions: Array<NormalWorkflowActions | SplitPathActions>;
31
+ }
32
+ >;
33
+
34
+ export function isNormalWorkflowAction(
35
+ workflow_action:
36
+ | WorkflowType['actions'][number]
37
+ | {
38
+ trigger_metadata?: WorkflowType['trigger_metadata'];
39
+ trigger: WorkflowType['trigger'];
40
+ }
41
+ | {}
42
+ ): workflow_action is NormalWorkflowActions {
43
+ return (
44
+ 'action_metadata' in workflow_action &&
45
+ workflow_action?.action_metadata?.type !== 'split_path'
46
+ );
47
+ }
48
+
49
+ export function isSplitPathAction(
50
+ workflow_action: WorkflowType['actions'][number]
51
+ ): workflow_action is SplitPathActions {
52
+ return workflow_action.action_metadata.type === 'split_path';
53
+ }
54
+
55
+ /***************************** CONDITIONS TYPES *****************************/
56
+
57
+ // {
58
+ // "operator": "AND",
59
+ // "conditions": [
60
+ // {
61
+ // "id": "cond1",
62
+ // "variable_name": "message",
63
+ // "variable_type": "string",
64
+ // "condition": "CONTAINS",
65
+ // "value": "urgent"
66
+ // },
67
+ // {
68
+ // "operator": "OR",
69
+ // "conditions": [
70
+ // {
71
+ // "id": "cond2",
72
+ // "variable_name": "priority",
73
+ // "variable_type": "number",
74
+ // "condition": "GT",
75
+ // "value": 2
76
+ // },
77
+ // {
78
+ // "id": "cond3",
79
+ // "variable_name": "assigned",
80
+ // "variable_type": "boolean",
81
+ // "condition": "NKNOWN"
82
+ // }
83
+ // ]
84
+ // }
85
+ // ]
86
+ // }
87
+
88
+ enum Conditions {
89
+ // string
90
+ CONTAINS = 'contains',
91
+ NCONTAINS = 'not contains',
92
+ EQUALS = 'equals',
93
+ NEQUALS = 'not equals',
94
+ STARTS_WITH = 'starts with',
95
+ ENDS_WITH = 'ends with',
96
+
97
+ // number, date, time
98
+ GREATER_THAN = 'greater than',
99
+ GREATER_THAN_OR_EQUAL = 'greater than or equal',
100
+ LESS_THAN = 'less than',
101
+ LESS_THAN_OR_EQUAL = 'less than or equal',
102
+
103
+ // none
104
+ IS_KNOWN = 'is known',
105
+ IS_UNKNOWN = 'is unknown',
106
+
107
+ // boolean
108
+ IS = 'is',
109
+ IS_NOT = 'is not',
110
+
111
+ // array
112
+ IS_ANY_OF = 'is any of',
113
+ IS_NOT_ANY_OF = 'is not any of',
114
+
115
+ // day
116
+ ON = 'on',
117
+ }
118
+
119
+ type BaseCondition<T extends Triggers> = {
120
+ id: string;
121
+ variable_name: keyof WorkflowDataType<T>;
122
+ };
123
+
124
+ type StringCondition = BaseCondition<Triggers> & {
125
+ condition:
126
+ | 'CONTAINS'
127
+ | 'NCONTAINS'
128
+ | 'EQUALS'
129
+ | 'NEQUALS'
130
+ | 'STARTS_WITH'
131
+ | 'ENDS_WITH';
132
+ value: string;
133
+ variable_type: 'string';
134
+ };
135
+
136
+ type DateTimeNumberCondition = BaseCondition<Triggers> & {
137
+ condition:
138
+ | 'GREATER_THAN'
139
+ | 'GREATER_THAN_OR_EQUAL'
140
+ | 'LESS_THAN'
141
+ | 'LESS_THAN_OR_EQUAL';
142
+ } & (
143
+ | {
144
+ value: string;
145
+ variable_type: 'number';
146
+ }
147
+ | {
148
+ value: string;
149
+ timezone: string;
150
+ variable_type: 'date' | 'time';
151
+ }
152
+ );
153
+
154
+ type ExistsCondition = BaseCondition<Triggers> & {
155
+ condition: 'IS_KNOWN' | 'IS_UNKNOWN';
156
+ value: undefined | null;
157
+ variable_type: null;
158
+ };
159
+
160
+ type OnCondition = BaseCondition<Triggers> & {
161
+ condition: 'ON';
162
+ value: string | string[];
163
+ timezone: string;
164
+ variable_type: 'day';
165
+ };
166
+
167
+ type BooleanCondition = BaseCondition<Triggers> & {
168
+ condition: 'IS' | 'IS_NOT';
169
+ value: boolean | 'true' | 'false';
170
+ variable_type: 'boolean';
171
+ };
172
+
173
+ type ArrayCondition = BaseCondition<Triggers> & {
174
+ condition: 'IS_ANY_OF' | 'IS_NOT_ANY_OF';
175
+ value: string[];
176
+ variable_type: 'array';
177
+ };
178
+
179
+ export type ConditionLeaf =
180
+ | StringCondition
181
+ | DateTimeNumberCondition
182
+ | ExistsCondition
183
+ | OnCondition
184
+ | BooleanCondition
185
+ | ArrayCondition;
186
+
187
+ type ConditionOperator = 'AND' | 'OR';
188
+
189
+ export type WorkflowConditionGroup = {
190
+ operator: ConditionOperator;
191
+ conditions: Array<ConditionLeaf | WorkflowConditionGroup>;
192
+ };
193
+
194
+ export function isConditionLeaf(
195
+ condition: ConditionLeaf | WorkflowConditionGroup
196
+ ): condition is ConditionLeaf {
197
+ return 'id' in condition && !('operator' in condition);
198
+ }
199
+
200
+ /***************************** WORKFLOW DATA TYPES *****************************/
201
+
202
+ export type WorkflowRawDataTypes = {
203
+ message: Tables<'tbl_chat_messages'>;
204
+ reaction: Tables<'tbl_chat_reactions'>;
205
+ chat: Merge<
206
+ Merge<Tables<'tbl_chats'>, Tables<'tbl_chat_properties'>>,
207
+ {
208
+ has_flagged_messages: boolean;
209
+ last_message_self: boolean;
210
+ members: string[];
211
+ }
212
+ >;
213
+ chat_label: Tables<'tbl_chat_properties'>;
214
+ ticket: Tables<'tbl_chat_tickets'>;
215
+ task: TaskType;
216
+ sender: Tables<'tbl_contacts'> & Tables<'tbl_chat_participants'>;
217
+ };
218
+
219
+ export type GetMessageWorkflowDataTypes = {
220
+ message: WorkflowRawDataTypes['message'];
221
+ sender: WorkflowRawDataTypes['sender'];
222
+ chat: WorkflowRawDataTypes['chat'];
223
+ };
224
+
225
+ export type GetChatWorkflowDataTypes = {
226
+ chat: WorkflowRawDataTypes['chat'];
227
+ };
228
+
229
+ export type GetTicketWorkflowDataTypes = {
230
+ ticket: WorkflowRawDataTypes['ticket'];
231
+ message: WorkflowRawDataTypes['message'];
232
+ sender: WorkflowRawDataTypes['sender'];
233
+ chat: WorkflowRawDataTypes['chat'];
234
+ };
235
+
236
+ export type GetTaskWorkflowDataTypes = {
237
+ task: WorkflowRawDataTypes['task'];
238
+ associated_object: TaskType['associated_object_metadata'];
239
+ };
240
+
241
+ export type GetReactionWorkflowDataTypes = {
242
+ reaction: WorkflowRawDataTypes['reaction'];
243
+ sender: WorkflowRawDataTypes['sender'];
244
+ message: WorkflowRawDataTypes['message'];
245
+ chat: WorkflowRawDataTypes['chat'];
246
+ };
247
+
248
+ export type MessageWorkflowDataTypes = AppendTypes<
249
+ {
250
+ message: WorkflowRawDataTypes['message'];
251
+ sender: WorkflowRawDataTypes['sender'];
252
+ chat: WorkflowRawDataTypes['chat'];
253
+ },
254
+ '.'
255
+ >;
256
+
257
+ export type ReactionWorkflowDataTypes = AppendTypes<
258
+ {
259
+ reaction: WorkflowRawDataTypes['reaction'];
260
+ sender: WorkflowRawDataTypes['sender'];
261
+ message: WorkflowRawDataTypes['message'];
262
+ chat: WorkflowRawDataTypes['chat'];
263
+ },
264
+ '.'
265
+ >;
266
+
267
+ export type TicketWorkflowDataTypes = AppendTypes<
268
+ {
269
+ ticket: WorkflowRawDataTypes['ticket'];
270
+ message: WorkflowRawDataTypes['message'];
271
+ sender: WorkflowRawDataTypes['sender'];
272
+ chat: WorkflowRawDataTypes['chat'];
273
+ },
274
+ '.'
275
+ >;
276
+
277
+ export type TaskWorkflowDataTypes = AppendTypes<
278
+ {
279
+ task: WorkflowRawDataTypes['task'];
280
+ associated_object: TaskType['associated_object_metadata'];
281
+ },
282
+ '.'
283
+ >;
284
+
285
+ export type ChatWorkflowDataTypes = AppendTypes<
286
+ {
287
+ chat: WorkflowRawDataTypes['chat'];
288
+ },
289
+ '.'
290
+ >;
291
+
292
+ export enum Triggers {
293
+ MESSAGE_CREATED = 'message.created',
294
+ MESSAGE_UPDATED = 'message.updated',
295
+ MESSAGE_DELETED = 'message.deleted',
296
+ MESSAGE_FLAGGED = 'message.flagged',
297
+ MESSAGE_UNFLAGGED = 'message.unflagged',
298
+ REACTION_ADDED = 'reaction.added',
299
+ TICKET_CREATED = 'ticket.created',
300
+ TICKET_UPDATED = 'ticket.updated',
301
+ TICKET_DELETED = 'ticket.deleted',
302
+ TICKET_CLOSED = 'ticket.closed',
303
+ TICKET_DUE = 'ticket.due',
304
+ CHAT_CREATED = 'chat.created',
305
+ CHAT_LABEL_UPDATED = 'chat.label.updated',
306
+ CHAT_CLOSED = 'chat.closed',
307
+ TASK_CREATED = 'task.created',
308
+ TASK_DUE = 'task.due',
309
+ }
310
+
311
+ export type WorkflowDataType<T extends Triggers = Triggers> = T extends
312
+ | Triggers.MESSAGE_CREATED
313
+ | Triggers.MESSAGE_DELETED
314
+ | Triggers.MESSAGE_UPDATED
315
+ | Triggers.MESSAGE_FLAGGED
316
+ | Triggers.MESSAGE_UNFLAGGED
317
+ ? MessageWorkflowDataTypes
318
+ : T extends
319
+ | Triggers.CHAT_CREATED
320
+ | Triggers.CHAT_LABEL_UPDATED
321
+ | Triggers.CHAT_CLOSED
322
+ ? ChatWorkflowDataTypes
323
+ : T extends
324
+ | Triggers.TICKET_CREATED
325
+ | Triggers.TICKET_UPDATED
326
+ | Triggers.TICKET_DELETED
327
+ | Triggers.TICKET_CLOSED
328
+ | Triggers.TICKET_DUE
329
+ ? TicketWorkflowDataTypes
330
+ : T extends Triggers.REACTION_ADDED
331
+ ? ReactionWorkflowDataTypes
332
+ : T extends Triggers.TASK_CREATED | Triggers.TASK_DUE
333
+ ? TaskWorkflowDataTypes
334
+ : never;
335
+
336
+ /***************************** ACTION TYPES *****************************/
337
+
338
+ export type SendMessageToChatWorkflowAction = {
339
+ type: 'send_message_to_chat';
340
+ metadata: {
341
+ message: string;
342
+ media?: {
343
+ url: string;
344
+ type: 'image' | 'video' | 'audio' | 'document';
345
+ name: string;
346
+ } | null;
347
+ debounce?: `${number} ${'seconds' | 'minutes' | 'hours' | 'days'}` | null;
348
+ chat_id: `${string}${'@g.us' | '@c.us'}` | 'trigger_chat' | null;
349
+ unflag_chat?: boolean;
350
+ as_reply?: boolean;
351
+ };
352
+ };
353
+
354
+ export type CreateTicketWorkflowAction = {
355
+ type: 'create_ticket';
356
+ metadata: {
357
+ subject: string | null;
358
+ assignee:
359
+ | {
360
+ round_robin: true;
361
+ emails: string[];
362
+ assignee_check_for?: 'shift_times' | 'online_offline' | 'all';
363
+ }
364
+ | {
365
+ email: string | null;
366
+ round_robin: false;
367
+ };
368
+ priority?: '0' | '1' | '2' | '3' | '4';
369
+ status: 'open' | 'inprogress' | 'closed';
370
+ labels: string[];
371
+ due_in: `${number} ${'seconds' | 'minutes' | 'hours' | 'days'}` | null;
372
+ };
373
+ };
374
+
375
+ export type AttachToLatestTicket = {
376
+ type: 'attach_to_latest_ticket';
377
+ metadata: {
378
+ status: ('open' | 'inprogress' | 'closed')[];
379
+ };
380
+ };
381
+
382
+ export type NotifyHTTPWorkflowAction = {
383
+ type: 'notify_http';
384
+ metadata: {
385
+ url: string;
386
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE';
387
+ headers: Record<string, string>;
388
+ body: string;
389
+ };
390
+ };
391
+
392
+ export type FlagMessageWorkflowAction = {
393
+ type: 'flag_message';
394
+ metadata: {};
395
+ };
396
+
397
+ export type UnflagMessageWorkflowAction = {
398
+ type: 'unflag_message';
399
+ metadata: {};
400
+ };
401
+
402
+ export type AssignTicketWorkflowAction = {
403
+ type: 'assign_ticket';
404
+ metadata: {
405
+ assignee:
406
+ | {
407
+ round_robin: true;
408
+ emails: string[];
409
+ assignee_check_for?: 'shift_times' | 'online_offline' | 'all';
410
+ }
411
+ | {
412
+ email: string | null;
413
+ round_robin: false;
414
+ };
415
+ };
416
+ };
417
+
418
+ export type CloseTicketWorkflowAction = {
419
+ type: 'close_ticket';
420
+ metadata: {
421
+ bypass_mandatory_fields?: boolean;
422
+ closing_note: string;
423
+ };
424
+ };
425
+
426
+ export type AddChatLabelWorkflowAction = {
427
+ type: 'add_chat_label';
428
+ metadata: {
429
+ labels: string[];
430
+ };
431
+ };
432
+
433
+ export type RemoveChatLabelWorkflowAction = {
434
+ type: 'remove_chat_label';
435
+ metadata: {
436
+ labels: string[];
437
+ };
438
+ };
439
+
440
+ export type AddTicketLabelWorkflowAction = {
441
+ type: 'add_ticket_label';
442
+ metadata: {
443
+ labels: string[];
444
+ };
445
+ };
446
+
447
+ export type RemoveTicketLabelWorkflowAction = {
448
+ type: 'remove_ticket_label';
449
+ metadata: {
450
+ labels: string[];
451
+ };
452
+ };
453
+
454
+ export type AssignChatWorkflowAction = {
455
+ type: 'assign_chat';
456
+ metadata: {
457
+ assignee:
458
+ | {
459
+ round_robin: true;
460
+ emails: string[];
461
+ assignee_check_for?: 'shift_times' | 'online_offline' | 'all';
462
+ }
463
+ | {
464
+ email: string | null;
465
+ round_robin: false;
466
+ };
467
+ };
468
+ };
469
+
470
+ type ChatIdType = `${string}${'@g.us' | '@c.us'}`;
471
+
472
+ export type ForwardMessageWorkflowAction = {
473
+ type: 'forward_message';
474
+ metadata: {
475
+ chat_id: `${ChatIdType}${`;${ChatIdType}`}` | null;
476
+ };
477
+ };
478
+
479
+ export type SendEmailWorkflowAction = {
480
+ type: 'send_email';
481
+ metadata: {
482
+ email: string;
483
+ subject: string;
484
+ body: string;
485
+ };
486
+ };
487
+
488
+ export type DeleteMessageWorkflowAction = {
489
+ type: 'delete_message';
490
+ metadata: {};
491
+ };
492
+
493
+ export type CloseChatWorkflowAction = {
494
+ type: 'close_chat';
495
+ metadata: {};
496
+ };
497
+
498
+ export type ValidateWorkflowAction = {
499
+ type: 'validate_action';
500
+ metadata: WorkflowConditionGroup;
501
+ };
502
+
503
+ export type DelayWorkflowAction = {
504
+ type: 'delay';
505
+ metadata: {
506
+ delay: `${number} ${'seconds' | 'minutes' | 'hours' | 'days'}`;
507
+ };
508
+ };
509
+
510
+ export type SendSlackNotificationWorkflowAction = {
511
+ type: 'send_slack_notification';
512
+ metadata: {
513
+ slack_payload: string;
514
+ url: string;
515
+ };
516
+ };
517
+
518
+ export type SplitPathWorkflowAction = {
519
+ type: 'split_path';
520
+ metadata: {
521
+ paths: Array<{
522
+ id: string;
523
+ condition_action_id: string;
524
+ }>;
525
+ };
526
+ };
527
+
528
+ // experimental
529
+ export type AIPromptWorkflowAction = {
530
+ type: 'ai_prompt';
531
+ metadata: {
532
+ query: string;
533
+ body: string;
534
+ };
535
+ };
536
+
537
+ export type NormalWorkflowActionTypes =
538
+ | SendMessageToChatWorkflowAction
539
+ | CreateTicketWorkflowAction
540
+ | AttachToLatestTicket
541
+ | NotifyHTTPWorkflowAction
542
+ | FlagMessageWorkflowAction
543
+ | UnflagMessageWorkflowAction
544
+ | AssignTicketWorkflowAction
545
+ | CloseTicketWorkflowAction
546
+ | AddChatLabelWorkflowAction
547
+ | RemoveChatLabelWorkflowAction
548
+ | AddTicketLabelWorkflowAction
549
+ | RemoveTicketLabelWorkflowAction
550
+ | AssignChatWorkflowAction
551
+ | ForwardMessageWorkflowAction
552
+ | SendEmailWorkflowAction
553
+ | DeleteMessageWorkflowAction
554
+ | CloseChatWorkflowAction
555
+ | ValidateWorkflowAction
556
+ | DelayWorkflowAction
557
+ | SendSlackNotificationWorkflowAction
558
+ | AIPromptWorkflowAction;
559
+
560
+ export type WorkflowActionsTypeMap = {
561
+ send_message_to_chat: SendMessageToChatWorkflowAction;
562
+ create_ticket: CreateTicketWorkflowAction;
563
+ attach_to_latest_ticket: AttachToLatestTicket;
564
+ notify_http: NotifyHTTPWorkflowAction;
565
+ flag_message: FlagMessageWorkflowAction;
566
+ unflag_message: UnflagMessageWorkflowAction;
567
+ assign_ticket: AssignTicketWorkflowAction;
568
+ close_ticket: CloseTicketWorkflowAction;
569
+ add_chat_label: AddChatLabelWorkflowAction;
570
+ remove_chat_label: RemoveChatLabelWorkflowAction;
571
+ add_ticket_label: AddTicketLabelWorkflowAction;
572
+ remove_ticket_label: RemoveTicketLabelWorkflowAction;
573
+ assign_chat: AssignChatWorkflowAction;
574
+ forward_message: ForwardMessageWorkflowAction;
575
+ send_email: SendEmailWorkflowAction;
576
+ delete_message: DeleteMessageWorkflowAction;
577
+ close_chat: CloseChatWorkflowAction;
578
+ validate_action: ValidateWorkflowAction;
579
+ delay: DelayWorkflowAction;
580
+ send_slack_notification: SendSlackNotificationWorkflowAction;
581
+ ai_prompt: AIPromptWorkflowAction;
582
+ split_path: SplitPathWorkflowAction;
583
+ };
584
+
585
+ export type WorkflowActionTypes =
586
+ | NormalWorkflowActionTypes
587
+ | SplitPathWorkflowAction;
588
+
589
+ export type WorkflowActionCategory =
590
+ | 'message'
591
+ | 'ticket'
592
+ | 'chat'
593
+ | 'custom'
594
+ | 'flow'
595
+ | 'ai';
596
+
597
+ export const ActionCategoryMap: Record<
598
+ WorkflowActionTypes['type'],
599
+ WorkflowActionCategory
600
+ > = {
601
+ send_message_to_chat: 'message',
602
+ create_ticket: 'ticket',
603
+ attach_to_latest_ticket: 'ticket',
604
+ notify_http: 'custom',
605
+ flag_message: 'message',
606
+ unflag_message: 'message',
607
+ assign_ticket: 'ticket',
608
+ close_ticket: 'ticket',
609
+ add_chat_label: 'chat',
610
+ remove_chat_label: 'chat',
611
+ add_ticket_label: 'ticket',
612
+ remove_ticket_label: 'ticket',
613
+ assign_chat: 'chat',
614
+ forward_message: 'message',
615
+ send_email: 'custom',
616
+ delete_message: 'message',
617
+ close_chat: 'chat',
618
+ validate_action: 'flow',
619
+ delay: 'flow',
620
+ send_slack_notification: 'custom',
621
+ ai_prompt: 'ai',
622
+ split_path: 'flow',
623
+ };
624
+
625
+ export const CategoryNameMap: Record<WorkflowActionCategory, string> = {
626
+ message: 'Message',
627
+ ticket: 'Ticket',
628
+ chat: 'Chat',
629
+ custom: 'Custom',
630
+ flow: 'Flow',
631
+ ai: 'AI',
632
+ };
633
+
634
+ export const TriggerNameMap: Record<Triggers, string> = {
635
+ 'chat.closed': 'Chat Closed',
636
+ 'chat.created': 'Chat Created',
637
+ 'chat.label.updated': 'Chat Label Updated',
638
+ 'message.created': 'Message Created',
639
+ 'message.deleted': 'Message Deleted',
640
+ 'message.flagged': 'Message Flagged',
641
+ 'message.unflagged': 'Message Unflagged',
642
+ 'message.updated': 'Message Updated',
643
+ 'reaction.added': 'Reaction Added',
644
+ 'ticket.closed': 'Ticket Closed',
645
+ 'ticket.created': 'Ticket Created',
646
+ 'ticket.deleted': 'Ticket Deleted',
647
+ 'ticket.due': 'Ticket Due',
648
+ 'ticket.updated': 'Ticket Updated',
649
+ 'task.created': 'Task Created',
650
+ 'task.due': 'Task Due',
651
+ };
652
+
653
+ export const WorkflowActionNameMap: Record<
654
+ WorkflowType['actions'][number]['action_metadata']['type'],
655
+ {
656
+ title: string;
657
+ description: string;
658
+ }
659
+ > = {
660
+ add_chat_label: {
661
+ title: 'Add Chat Label',
662
+ description: 'Add a label to the trigger chat',
663
+ },
664
+ add_ticket_label: {
665
+ title: 'Add Ticket Label',
666
+ description: 'Add a label to the trigger ticket',
667
+ },
668
+ assign_chat: {
669
+ title: 'Assign Chat',
670
+ description: 'Assign a chat to org user',
671
+ },
672
+ attach_to_latest_ticket: {
673
+ title: 'Attach to Latest Ticket',
674
+ description: 'Attach to the latest ticket of trigger chat',
675
+ },
676
+ close_chat: {
677
+ title: 'Close Chat',
678
+ description: 'Close the chat',
679
+ },
680
+ close_ticket: {
681
+ title: 'Close Ticket',
682
+ description: 'Close the trigger ticket or ticket attached to the message',
683
+ },
684
+ create_ticket: {
685
+ title: 'Create Ticket',
686
+ description: 'Create a ticket attached to the trigger message',
687
+ },
688
+ delay: {
689
+ title: 'Delay',
690
+ description: 'Add a delay to next sequential actions',
691
+ },
692
+ ai_prompt: {
693
+ title: 'AI Prompt',
694
+ description: 'Analyse, filter, categorise, and generate text using AI',
695
+ },
696
+ flag_message: {
697
+ title: 'Flag Message',
698
+ description: 'Flag the trigger message or message attached to the ticket',
699
+ },
700
+ remove_chat_label: {
701
+ title: 'Remove Chat Label',
702
+ description: 'Remove a label from the trigger chat',
703
+ },
704
+ remove_ticket_label: {
705
+ title: 'Remove Ticket Label',
706
+ description:
707
+ 'Remove a label from the trigger ticket or ticket attached to the message',
708
+ },
709
+ send_email: {
710
+ title: 'Send Email',
711
+ description: 'Send custom text to an email',
712
+ },
713
+ send_message_to_chat: {
714
+ title: 'Send Message to Chat',
715
+ description: 'Send a message to the chat attached to the trigger',
716
+ },
717
+ send_slack_notification: {
718
+ title: 'Send Slack Notification',
719
+ description: 'Send a slack notification',
720
+ },
721
+ split_path: {
722
+ title: 'Split Path',
723
+ description: 'Split the workflow path based on the condition',
724
+ },
725
+ unflag_message: {
726
+ title: 'Unflag Message',
727
+ description: 'Unflag the trigger message or message attached to the ticket',
728
+ },
729
+ validate_action: {
730
+ title: 'Validate Action',
731
+ description: 'Validate the action based on multiple criterias',
732
+ },
733
+ notify_http: {
734
+ title: 'Notify HTTP',
735
+ description: 'Send a custom HTTP request to an endpoint',
736
+ },
737
+ assign_ticket: {
738
+ title: 'Assign Ticket',
739
+ description: 'Assign a ticket to an org user',
740
+ },
741
+ forward_message: {
742
+ title: 'Forward Message',
743
+ description: 'Forward a message to a chat',
744
+ },
745
+ delete_message: {
746
+ title: 'Delete Message',
747
+ description: 'Delete the trigger message or message attached to the ticket',
748
+ },
749
+ };
750
+
751
+ export type SendMessageToChatActionReturnInfo = {
752
+ message_details: {
753
+ queue_id: string;
754
+ queue_position: number;
755
+ };
756
+ };
757
+
758
+ export type CreateTicketActionReturnInfo = {
759
+ ticket_details: Tables<'tbl_chat_tickets'>;
760
+ };
761
+
762
+ export type AssignChatActionReturnInfo = {
763
+ chat_details: {
764
+ chat_id: string;
765
+ assigned_to: string;
766
+ org_id: string;
767
+ };
768
+ };
769
+
770
+ export type AddChatLabelActionReturnInfo = {
771
+ chat_details: {
772
+ chat_id: string;
773
+ org_id: string;
774
+ labels: string[];
775
+ };
776
+ };
777
+
778
+ export type NotifyHTTPActionReturnInfo = {
779
+ status: number | 'Unknown';
780
+ data: Record<string, unknown>;
781
+ error: any;
782
+ };
783
+
784
+ export type ForwardMessageActionReturnInfo = {
785
+ [key: string]: boolean;
786
+ };
787
+
788
+ export type DeleteMessageActionReturnInfo = {};
789
+
790
+ export type AssignTicketActionReturnInfo = Tables<'tbl_chat_tickets'>;
791
+ export type CloseTicketActionReturnInfo = Tables<'tbl_chat_tickets'>;
792
+
793
+ export type AIPromptActionReturnInfo = {
794
+ query: string;
795
+ input: string;
796
+ output: string | Record<string, unknown> | boolean | null;
797
+ };
798
+
799
+ export type ActionInfo = {
800
+ send_message_to_chat: SendMessageToChatActionReturnInfo;
801
+ create_ticket: CreateTicketActionReturnInfo;
802
+ assign_chat: AssignChatActionReturnInfo;
803
+ add_chat_label: AddChatLabelActionReturnInfo;
804
+ notify_http: NotifyHTTPActionReturnInfo;
805
+ forward_message: ForwardMessageActionReturnInfo;
806
+ delete_message: DeleteMessageActionReturnInfo;
807
+ assign_ticket: AssignTicketActionReturnInfo;
808
+ close_ticket: CloseTicketActionReturnInfo;
809
+ ai_prompt: AIPromptActionReturnInfo;
810
+ };
811
+
812
+ // Example workflow type ->
813
+
814
+ // const demoWorkflow: WorkflowType = {
815
+ // id: 'workflow-1',
816
+ // name: 'Urgent Chat Auto-Responder',
817
+ // trigger: Triggers.MESSAGE_CREATED,
818
+ // trigger_metadata: {
819
+ // org_phones: ['phone-1'],
820
+ // allow_internal_messages: false,
821
+ // first_action_id: 'action-validate',
822
+ // },
823
+ // actions: [
824
+ // {
825
+ // id: 'action-validate',
826
+ // action_metadata: {
827
+ // type: 'validate_action',
828
+ // metadata: {
829
+ // operator: 'AND',
830
+ // conditions: [
831
+ // {
832
+ // id: 'cond-1',
833
+ // variable_name: 'message.text',
834
+ // variable_type: 'string',
835
+ // condition: 'CONTAINS',
836
+ // value: 'urgent',
837
+ // },
838
+ // {
839
+ // id: 'cond-2',
840
+ // variable_name: 'chat.assigned',
841
+ // variable_type: 'boolean',
842
+ // condition: 'IS',
843
+ // value: false,
844
+ // },
845
+ // ],
846
+ // },
847
+ // },
848
+ // next: 'action-add-label',
849
+ // },
850
+ // {
851
+ // id: 'action-add-label',
852
+ // action_metadata: {
853
+ // type: 'add_chat_label',
854
+ // metadata: {
855
+ // labels: ['urgent'],
856
+ // },
857
+ // },
858
+ // next: 'action-assign-chat',
859
+ // },
860
+ // {
861
+ // id: 'action-assign-chat',
862
+ // action_metadata: {
863
+ // type: 'assign_chat',
864
+ // metadata: {
865
+ // assignee: {
866
+ // round_robin: true,
867
+ // emails: ['agent1@example.com', 'agent2@example.com'],
868
+ // assignee_check_for: 'all',
869
+ // },
870
+ // },
871
+ // },
872
+ // next: 'action-delay',
873
+ // },
874
+ // {
875
+ // id: 'action-delay',
876
+ // action_metadata: {
877
+ // type: 'delay',
878
+ // metadata: {
879
+ // delay: '5 minutes',
880
+ // },
881
+ // },
882
+ // next: 'action-send-message',
883
+ // },
884
+ // {
885
+ // id: 'action-send-message',
886
+ // action_metadata: {
887
+ // type: 'send_message_to_chat',
888
+ // metadata: {
889
+ // message: 'We’re on it!',
890
+ // chat_id: 'trigger_chat',
891
+ // },
892
+ // },
893
+ // next: 'action-split',
894
+ // },
895
+ // {
896
+ // id: 'action-split',
897
+ // action_metadata: {
898
+ // type: 'split_path',
899
+ // metadata: {
900
+ // paths: [
901
+ // {
902
+ // id: 'path-flagged',
903
+ // condition_action_id: 'action-condition-flagged',
904
+ // },
905
+ // {
906
+ // id: 'path-not-flagged',
907
+ // condition_action_id: 'action-condition-not-flagged',
908
+ // },
909
+ // ],
910
+ // },
911
+ // },
912
+ // {
913
+ // id: 'action-condition-flagged',
914
+ // action_metadata: {
915
+ // type: 'validate_action',
916
+ // metadata: {
917
+ // operator: 'AND',
918
+ // conditions: [
919
+ // {
920
+ // id: 'cond-flagged',
921
+ // variable_name: 'chat.has_flagged_messages',
922
+ // variable_type: 'boolean',
923
+ // condition: 'IS',
924
+ // value: true,
925
+ // },
926
+ // ],
927
+ // },
928
+ // },
929
+ // next: 'action-create-ticket',
930
+ // },
931
+ // {
932
+ // id: 'action-condition-not-flagged',
933
+ // action_metadata: {
934
+ // type: 'validate_action',
935
+ // metadata: {
936
+ // operator: 'AND',
937
+ // conditions: [
938
+ // {
939
+ // id: 'cond-unflagged',
940
+ // variable_name: 'chat.has_flagged_messages',
941
+ // variable_type: 'boolean',
942
+ // condition: 'IS',
943
+ // value: false,
944
+ // },
945
+ // ],
946
+ // },
947
+ // },
948
+ // next: 'action-send-slack',
949
+ // },
950
+ // {
951
+ // id: 'action-create-ticket',
952
+ // action_metadata: {
953
+ // type: 'create_ticket',
954
+ // metadata: {
955
+ // subject: 'Urgent Chat Follow-up',
956
+ // assignee: {
957
+ // email: 'manager@example.com',
958
+ // },
959
+ // priority: '4',
960
+ // status: 'open',
961
+ // labels: ['urgent', 'auto-created'],
962
+ // due_date: '30 minutes',
963
+ // },
964
+ // },
965
+ // next: '', // End
966
+ // },
967
+ // {
968
+ // id: 'action-send-slack',
969
+ // action_metadata: {
970
+ // type: 'send_slack_notification',
971
+ // metadata: {
972
+ // slack_payload: JSON.stringify({
973
+ // text: 'An urgent chat was received, no flagged messages.',
974
+ // }),
975
+ // url: 'https://hooks.slack.com/services/XXX/YYY/ZZZ',
976
+ // },
977
+ // },
978
+ // next: '', // End
979
+ // },
980
+ // ],
981
+ // };
982
+
983
+ /***************************** WORKFLOW FE TYPES @harshgour *****************************/