@periskope/types 0.6.308 → 0.6.310

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