@peacom/core 0.0.85 → 0.0.87

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.
Files changed (178) hide show
  1. package/.eslintrc.json +18 -0
  2. package/data/Chuyen-de-1.pdf +63386 -304
  3. package/data/report_bulk_campaign_Kplus_1665394311017.xlsx +0 -0
  4. package/jest.config.ts +16 -0
  5. package/package.json +9 -10
  6. package/project.json +41 -0
  7. package/src/index.ts +5 -0
  8. package/src/lib/api/api.constant.ts +82 -0
  9. package/src/lib/api/core.api.ts +86 -0
  10. package/src/lib/api/index.ts +4 -0
  11. package/src/lib/api/micro-service.api.ts +35 -0
  12. package/src/lib/api/micro-service.spec.ts +29 -0
  13. package/src/lib/api/queue/queue.api.ts +39 -0
  14. package/src/lib/core.spec.ts +7 -0
  15. package/src/lib/core.ts +3 -0
  16. package/src/lib/error/FormError.ts +64 -0
  17. package/src/lib/error/HttpError.ts +9 -0
  18. package/src/lib/model/Application.ts +63 -0
  19. package/src/lib/model/BackgroundTask.ts +5 -0
  20. package/src/lib/model/Billing.ts +11 -0
  21. package/src/lib/model/Currency.ts +5 -0
  22. package/src/lib/model/FileInfo.ts +9 -0
  23. package/src/lib/model/conversation/constant.ts +34 -0
  24. package/src/lib/model/conversation/index.ts +1 -0
  25. package/src/lib/model/index.ts +11 -0
  26. package/src/lib/model/message/Message.ts +159 -0
  27. package/src/lib/model/message/TemplateMessage.ts +4 -0
  28. package/src/lib/model/message/index.ts +4 -0
  29. package/src/lib/model/message/sinch/SinchWhatsappTemplate.ts +27 -0
  30. package/src/lib/model/message/zalo/ZaloZNSTemplate.ts +26 -0
  31. package/src/lib/model/partner/PartnerEvent.ts +24 -0
  32. package/src/lib/model/partner/index.ts +6 -0
  33. package/src/lib/model/queue/QueueMessage.ts +31 -0
  34. package/src/lib/model/queue/index.ts +2 -0
  35. package/src/lib/model/queue/queue.constant.ts +6 -0
  36. package/src/lib/model/template/Template.ts +86 -0
  37. package/src/lib/model/template/index.ts +1 -0
  38. package/src/lib/model/viber-business/constant.ts +4 -0
  39. package/src/lib/model/viber-business/index.ts +1 -0
  40. package/src/lib/service/index.ts +1 -0
  41. package/src/lib/service/storage/aws/constants.ts +22 -0
  42. package/src/lib/service/storage/aws/index.ts +2 -0
  43. package/src/lib/service/storage/aws/s3.service.ts +128 -0
  44. package/src/lib/service/storage/aws/s3.spec.ts +12 -0
  45. package/src/lib/service/storage/index.ts +1 -0
  46. package/src/lib/util/date/constant.ts +3 -0
  47. package/src/lib/util/date/date.spec.ts +22 -0
  48. package/src/lib/util/date/date.util.ts +64 -0
  49. package/src/lib/util/date/index.ts +2 -0
  50. package/src/lib/util/file/file.spec.ts +40 -0
  51. package/src/lib/util/file/file.util.ts +60 -0
  52. package/src/lib/util/general.util.ts +3 -0
  53. package/src/lib/util/index.ts +6 -0
  54. package/src/lib/util/message/message.util.ts +118 -0
  55. package/src/lib/util/phone.spec.ts +48 -0
  56. package/src/lib/util/phone.util.ts +51 -0
  57. package/src/lib/util/string.spec.ts +15 -0
  58. package/src/lib/util/string.util.ts +118 -0
  59. package/tsconfig.json +22 -0
  60. package/tsconfig.lib.json +10 -0
  61. package/tsconfig.spec.json +14 -0
  62. package/src/index.d.ts +0 -4
  63. package/src/index.js +0 -8
  64. package/src/index.js.map +0 -1
  65. package/src/lib/api/api.constant.d.ts +0 -58
  66. package/src/lib/api/api.constant.js +0 -20
  67. package/src/lib/api/api.constant.js.map +0 -1
  68. package/src/lib/api/core.api.d.ts +0 -9
  69. package/src/lib/api/core.api.js +0 -78
  70. package/src/lib/api/core.api.js.map +0 -1
  71. package/src/lib/api/index.d.ts +0 -4
  72. package/src/lib/api/index.js +0 -8
  73. package/src/lib/api/index.js.map +0 -1
  74. package/src/lib/api/micro-service.api.d.ts +0 -2
  75. package/src/lib/api/micro-service.api.js +0 -38
  76. package/src/lib/api/micro-service.api.js.map +0 -1
  77. package/src/lib/api/queue/queue.api.d.ts +0 -7
  78. package/src/lib/api/queue/queue.api.js +0 -37
  79. package/src/lib/api/queue/queue.api.js.map +0 -1
  80. package/src/lib/core.d.ts +0 -1
  81. package/src/lib/core.js +0 -8
  82. package/src/lib/core.js.map +0 -1
  83. package/src/lib/error/FormError.d.ts +0 -53
  84. package/src/lib/error/FormError.js +0 -58
  85. package/src/lib/error/FormError.js.map +0 -1
  86. package/src/lib/error/HttpError.d.ts +0 -4
  87. package/src/lib/error/HttpError.js +0 -12
  88. package/src/lib/error/HttpError.js.map +0 -1
  89. package/src/lib/model/Application.d.ts +0 -52
  90. package/src/lib/model/Application.js +0 -59
  91. package/src/lib/model/Application.js.map +0 -1
  92. package/src/lib/model/Billing.d.ts +0 -10
  93. package/src/lib/model/Billing.js +0 -16
  94. package/src/lib/model/Billing.js.map +0 -1
  95. package/src/lib/model/Currency.d.ts +0 -4
  96. package/src/lib/model/Currency.js +0 -9
  97. package/src/lib/model/Currency.js.map +0 -1
  98. package/src/lib/model/FileInfo.d.ts +0 -9
  99. package/src/lib/model/FileInfo.js +0 -3
  100. package/src/lib/model/FileInfo.js.map +0 -1
  101. package/src/lib/model/conversation/constant.d.ts +0 -25
  102. package/src/lib/model/conversation/constant.js +0 -25
  103. package/src/lib/model/conversation/constant.js.map +0 -1
  104. package/src/lib/model/conversation/index.d.ts +0 -1
  105. package/src/lib/model/conversation/index.js +0 -5
  106. package/src/lib/model/conversation/index.js.map +0 -1
  107. package/src/lib/model/index.d.ts +0 -10
  108. package/src/lib/model/index.js +0 -14
  109. package/src/lib/model/index.js.map +0 -1
  110. package/src/lib/model/message/Message.d.ts +0 -129
  111. package/src/lib/model/message/Message.js +0 -88
  112. package/src/lib/model/message/Message.js.map +0 -1
  113. package/src/lib/model/message/TemplateMessage.d.ts +0 -4
  114. package/src/lib/model/message/TemplateMessage.js +0 -9
  115. package/src/lib/model/message/TemplateMessage.js.map +0 -1
  116. package/src/lib/model/message/index.d.ts +0 -4
  117. package/src/lib/model/message/index.js +0 -8
  118. package/src/lib/model/message/index.js.map +0 -1
  119. package/src/lib/model/message/sinch/SinchWhatsappTemplate.d.ts +0 -22
  120. package/src/lib/model/message/sinch/SinchWhatsappTemplate.js +0 -14
  121. package/src/lib/model/message/sinch/SinchWhatsappTemplate.js.map +0 -1
  122. package/src/lib/model/message/zalo/ZaloZNSTemplate.d.ts +0 -23
  123. package/src/lib/model/message/zalo/ZaloZNSTemplate.js +0 -3
  124. package/src/lib/model/message/zalo/ZaloZNSTemplate.js.map +0 -1
  125. package/src/lib/model/partner/PartnerEvent.d.ts +0 -22
  126. package/src/lib/model/partner/PartnerEvent.js +0 -3
  127. package/src/lib/model/partner/PartnerEvent.js.map +0 -1
  128. package/src/lib/model/partner/index.d.ts +0 -5
  129. package/src/lib/model/partner/index.js +0 -11
  130. package/src/lib/model/partner/index.js.map +0 -1
  131. package/src/lib/model/queue/QueueMessage.d.ts +0 -28
  132. package/src/lib/model/queue/QueueMessage.js +0 -9
  133. package/src/lib/model/queue/QueueMessage.js.map +0 -1
  134. package/src/lib/model/queue/index.d.ts +0 -2
  135. package/src/lib/model/queue/index.js +0 -6
  136. package/src/lib/model/queue/index.js.map +0 -1
  137. package/src/lib/model/queue/queue.constant.d.ts +0 -6
  138. package/src/lib/model/queue/queue.constant.js +0 -11
  139. package/src/lib/model/queue/queue.constant.js.map +0 -1
  140. package/src/lib/model/template/Template.d.ts +0 -43
  141. package/src/lib/model/template/Template.js +0 -89
  142. package/src/lib/model/template/Template.js.map +0 -1
  143. package/src/lib/model/template/index.d.ts +0 -1
  144. package/src/lib/model/template/index.js +0 -5
  145. package/src/lib/model/template/index.js.map +0 -1
  146. package/src/lib/model/viber-business/constant.d.ts +0 -4
  147. package/src/lib/model/viber-business/constant.js +0 -9
  148. package/src/lib/model/viber-business/constant.js.map +0 -1
  149. package/src/lib/model/viber-business/index.d.ts +0 -1
  150. package/src/lib/model/viber-business/index.js +0 -5
  151. package/src/lib/model/viber-business/index.js.map +0 -1
  152. package/src/lib/util/date/constant.d.ts +0 -3
  153. package/src/lib/util/date/constant.js +0 -7
  154. package/src/lib/util/date/constant.js.map +0 -1
  155. package/src/lib/util/date/date.util.d.ts +0 -19
  156. package/src/lib/util/date/date.util.js +0 -59
  157. package/src/lib/util/date/date.util.js.map +0 -1
  158. package/src/lib/util/date/index.d.ts +0 -2
  159. package/src/lib/util/date/index.js +0 -6
  160. package/src/lib/util/date/index.js.map +0 -1
  161. package/src/lib/util/file/file.util.d.ts +0 -5
  162. package/src/lib/util/file/file.util.js +0 -35
  163. package/src/lib/util/file/file.util.js.map +0 -1
  164. package/src/lib/util/general.util.d.ts +0 -1
  165. package/src/lib/util/general.util.js +0 -8
  166. package/src/lib/util/general.util.js.map +0 -1
  167. package/src/lib/util/index.d.ts +0 -6
  168. package/src/lib/util/index.js +0 -10
  169. package/src/lib/util/index.js.map +0 -1
  170. package/src/lib/util/message/message.util.d.ts +0 -90
  171. package/src/lib/util/message/message.util.js +0 -72
  172. package/src/lib/util/message/message.util.js.map +0 -1
  173. package/src/lib/util/phone.util.d.ts +0 -24
  174. package/src/lib/util/phone.util.js +0 -51
  175. package/src/lib/util/phone.util.js.map +0 -1
  176. package/src/lib/util/string.util.d.ts +0 -14
  177. package/src/lib/util/string.util.js +0 -118
  178. package/src/lib/util/string.util.js.map +0 -1
@@ -0,0 +1,159 @@
1
+ import {Application} from "../Application";
2
+ import {BILLING_STATUS} from "../Billing";
3
+ import {FileInfo} from "../FileInfo";
4
+ import {ZaloZnsTemmplateParam} from "./zalo/ZaloZNSTemplate";
5
+
6
+ export enum MESSAGE_CONTENT_TYPE {
7
+ EVENT = 1, // DELIVERY STATUS
8
+ MESSAGE,
9
+ LIVE_AGENT_REQUEST,
10
+ TYPING_INDICATOR,
11
+ CONVERSATION_CLOSE
12
+ }
13
+
14
+ export enum SEND_TYPE {
15
+ VIA_BROADCAST = 1,
16
+ VIA_BOT = 2,
17
+ VIA_TEMPLATE_TEST = 3,
18
+ VIA_CONVERSATION = 4,
19
+ VIA_PARTNER = 5
20
+ }
21
+
22
+ export enum MESSAGE_STATUS {
23
+ PENDING = 1,
24
+ SUCCESS = 2,
25
+ FAIL = 3,
26
+ DELIVERED = 4,
27
+ READ = 5,
28
+ }
29
+
30
+ export enum DIRECTION_TYPE {
31
+ SEND = 1,
32
+ RECEIVE
33
+ }
34
+
35
+ export enum MESSAGE_TYPE {
36
+ NONE = 'NONE',
37
+ TEXT = "text",
38
+ TEXT_WITH_ATTACHMENT = "text_with_attachment",
39
+ RICH_CARD = "rich_card",
40
+ VIDEO = "video",
41
+ PICTURE = "picture",
42
+ FILE = "file",
43
+ RICH_LINK = "richLink",
44
+ LIST_PICKER = "listPicker",
45
+ QUICK_REPLY = "quickReply",
46
+ LOCATION = "location",
47
+ ZALO_LIST_PICKER = "zalo_list_picker",
48
+ TYPING_INDICATOR_START = "TYPING_INDICATOR_START",
49
+ TYPING_INDICATOR_STOP = "TYPING_INDICATOR_STOP",
50
+ ZALO_ZNS_TEMPLATE = 'zalo_zns_template',
51
+ SHARE_INFO = "share_info",
52
+ REACTION = "reaction"
53
+ }
54
+
55
+ export const GENERAL_MESSAGE = [MESSAGE_TYPE.TEXT, MESSAGE_TYPE.RICH_CARD, MESSAGE_TYPE.VIDEO, MESSAGE_TYPE.PICTURE, MESSAGE_TYPE.FILE]
56
+
57
+ export const APPLICATION_MESSAGE: Record<Application, Array<MESSAGE_TYPE>> = {
58
+ [Application.APPLE]: [MESSAGE_TYPE.TEXT, MESSAGE_TYPE.TEXT_WITH_ATTACHMENT, MESSAGE_TYPE.RICH_LINK, MESSAGE_TYPE.LIST_PICKER, MESSAGE_TYPE.QUICK_REPLY, MESSAGE_TYPE.LOCATION, MESSAGE_TYPE.TYPING_INDICATOR_START, MESSAGE_TYPE.TYPING_INDICATOR_STOP],
59
+ [Application.SMS]: [MESSAGE_TYPE.TEXT],
60
+ [Application.VIBER]: GENERAL_MESSAGE,
61
+ [Application.RCS]: [...GENERAL_MESSAGE, MESSAGE_TYPE.TYPING_INDICATOR_START, MESSAGE_TYPE.TYPING_INDICATOR_STOP],
62
+ [Application.TELEGRAM]: GENERAL_MESSAGE,
63
+ [Application.VIBER_BUSINESS]: GENERAL_MESSAGE,
64
+ [Application.FACEBOOK]: GENERAL_MESSAGE,
65
+ [Application.ZALO]: [...GENERAL_MESSAGE, MESSAGE_TYPE.ZALO_LIST_PICKER],
66
+ [Application.ZALO_ZNS]: [MESSAGE_TYPE.TEXT],
67
+ [Application.VIBER_BOT]: GENERAL_MESSAGE,
68
+ [Application.WHATSAPP]: GENERAL_MESSAGE,
69
+ [Application.GOOGLE_BUSINESS]: [MESSAGE_TYPE.TEXT, MESSAGE_TYPE.RICH_CARD, MESSAGE_TYPE.PICTURE],
70
+ }
71
+
72
+ export enum SEND_MESSAGE_VIA {
73
+ QUEUE = 1,
74
+ DIRECTLY = 2
75
+ }
76
+
77
+ export enum MESSAGE_REACTION {
78
+ REPLY = 1,
79
+ LIKE = 2,
80
+ SUGGESTION_CLICK = 3
81
+ }
82
+
83
+ export enum SuggestionActionType {
84
+ OPEN_URL = "open-url",
85
+ REPLY = "reply",
86
+ DIAL = "dial",
87
+ LIVE_AGENT_REQUEST = "liveAgent",
88
+ CALENDAR = "CalendarEventAction"
89
+ }
90
+
91
+ export interface RawMessageSuggestion {
92
+ action: SuggestionActionType
93
+ text: string
94
+ postbackData: string
95
+ }
96
+
97
+ export interface RichCard {
98
+ title?: string
99
+ titleRow?: number
100
+ description?: string
101
+ descriptionRow?: number
102
+ image?: string
103
+ imageRow?: number
104
+ suggestions: RawMessageSuggestion[]
105
+ }
106
+
107
+ export interface PickListItem {
108
+ title: string
109
+ value: string
110
+ subtitle?: string
111
+ image?: string
112
+ }
113
+
114
+ type ReceivedMessage = PickListItem
115
+ type ReplyMessage = PickListItem
116
+
117
+ export interface ContactMessage {
118
+ name: string
119
+ phone: string
120
+ address: string
121
+
122
+ [key: string]: any
123
+ }
124
+
125
+ export interface RawMessage {
126
+ type: MESSAGE_TYPE
127
+ message?: string
128
+ file?: FileInfo
129
+ fileUrl?: string
130
+ fileName?: string
131
+ fileSize?: string | number
132
+ trackingData?: ""
133
+ richCards?: RichCard[]
134
+ viberRichCardRow?: number
135
+ viberRichCardCol?: number
136
+ fileResolution?: string
137
+ thumbnailUrl?: string
138
+ thumbnailFile?: FileInfo
139
+ suggestions?: Array<RawMessageSuggestion>
140
+ allowMultiple?: boolean
141
+ attachments?: Array<FileInfo>
142
+ listPicker?: Array<PickListItem>
143
+ receivedMessage?: ReceivedMessage
144
+ replyMessage?: ReplyMessage
145
+ richLinkUrl?: string
146
+ zaloZnsTemplateParam?: ZaloZnsTemmplateParam
147
+ contacts?: Array<ContactMessage>
148
+ extra?: any
149
+ }
150
+
151
+ export interface Message {
152
+ id?: number;
153
+ publicId?: string;
154
+ rawMessage: RawMessage;
155
+ extraData?: RawMessage;
156
+ createdDate?: string;
157
+ cost?: number;
158
+ billingStatus?: BILLING_STATUS
159
+ }
@@ -0,0 +1,4 @@
1
+ export enum TemplateMessageSource {
2
+ LOCAL = 1,
3
+ PARTNER
4
+ }
@@ -0,0 +1,4 @@
1
+ export * from './TemplateMessage'
2
+ export * from './sinch/SinchWhatsappTemplate'
3
+ export * from './Message'
4
+ export * from './zalo/ZaloZNSTemplate'
@@ -0,0 +1,27 @@
1
+ import {FileInfo} from "../../FileInfo";
2
+
3
+
4
+ export enum WhatsappTemplateType {
5
+ TEXT = 1,
6
+ MEDIA = 2
7
+ }
8
+
9
+ export enum WhatsappTemplateButtonType {
10
+ quick_reply = "quick_reply",
11
+ url = "url"
12
+ }
13
+
14
+ export interface WhatsappTemplateButton {
15
+ type: WhatsappTemplateButtonType
16
+ data: string
17
+ }
18
+
19
+ export interface WhatsappTemplateParam {
20
+ templateId: string,
21
+ language?: string
22
+ header?: Array<string>
23
+ body?: Array<string>
24
+ type: WhatsappTemplateType
25
+ media?: FileInfo
26
+ buttons?: Array<WhatsappTemplateButton>
27
+ }
@@ -0,0 +1,26 @@
1
+
2
+ export interface ZaloZnsTemplateInfo {
3
+ templateId: string | number
4
+ templateName: string
5
+ listParams: Array<ZaloZnsParam>,
6
+ previewUrl: string
7
+ }
8
+
9
+ export interface ZaloZnsParam {
10
+ name: string
11
+ require: boolean
12
+ type: 'STRING' | 'DATE' | 'NUMBER'
13
+ maxLength: number
14
+ minLength: number
15
+ acceptNull: boolean
16
+ }
17
+
18
+ export interface ZaloZnsTemmplateParam {
19
+ template: ZaloZnsTemplateInfo;
20
+ templateInfo: ZaloZnsTemplateInfo;
21
+ templateData: Array<{
22
+ name: string,
23
+ value?: string | number,
24
+ param: ZaloZnsParam
25
+ }>
26
+ }
@@ -0,0 +1,24 @@
1
+ import {PARTNER_MESSAGE_TYPE} from "./index";
2
+ import {MESSAGE_STATUS, RawMessage} from "../message";
3
+ import {JobsOptions} from "bullmq";
4
+ import {Application} from "../Application";
5
+
6
+ export interface PartnerEvent {
7
+ messageId: string
8
+ type: PARTNER_MESSAGE_TYPE
9
+ timestamp: number
10
+ cause: string
11
+ status: MESSAGE_STATUS
12
+ message?: RawMessage
13
+ publicId?: string // channel publicId
14
+ applicationId: Application
15
+ from?: string
16
+ clientMessageId?: string
17
+ }
18
+
19
+ export interface QueuePartnerEventParam {
20
+ webHookUrl: string
21
+ event: PartnerEvent
22
+ companyId: number
23
+ jobOpt?: JobsOptions,
24
+ }
@@ -0,0 +1,6 @@
1
+ export enum PARTNER_MESSAGE_TYPE {
2
+ EVENT = 1,
3
+ MESSAGE = 2
4
+ }
5
+
6
+ export * from './PartnerEvent'
@@ -0,0 +1,31 @@
1
+ import {ApplicationInfo, Message, RawMessage} from "../";
2
+ import {MESSAGE_STATUS} from "../";
3
+ import {JobsOptions} from "bullmq";
4
+ import {Conversation} from "../conversation";
5
+
6
+ export enum QueueMessageStatusSource {
7
+ LOCAL = 1,
8
+ PARTNER = 2
9
+ }
10
+
11
+ export interface QueueMessageStatus {
12
+ messageId?: string;
13
+ applicationMessageId?: string;
14
+ applicationInfo: ApplicationInfo;
15
+ status: MESSAGE_STATUS;
16
+ sentTime: number;
17
+ extraData?: Record<string, unknown>;
18
+ deliveryStatus?: string,
19
+ jobOpt?: JobsOptions,
20
+ source: QueueMessageStatusSource
21
+ }
22
+
23
+ export interface QueueOutgoingMessage {
24
+ receiverId: string
25
+ messages: Array<Message>
26
+ applicationInfo: ApplicationInfo
27
+ contact: unknown
28
+ jobOpt?: JobsOptions,
29
+ name?: string
30
+ conversation?: Conversation
31
+ }
@@ -0,0 +1,2 @@
1
+ export * from './queue.constant'
2
+ export * from './QueueMessage'
@@ -0,0 +1,6 @@
1
+ export enum PEACOM_CORE_QUEUE {
2
+ BILLING = "PEACOM_CORE_BILLING",
3
+ STATUS = "PEACOM_CORE_MESSAGE_STATUS",
4
+ FALLBACK = "PEACOM_CORE_FALLBACK",
5
+ PARTNER = "PEACOM_CORE_PARTNER"
6
+ }
@@ -0,0 +1,86 @@
1
+ export enum TemplateMessageStatus {
2
+ NORMAL = 0,
3
+ START = 1,
4
+ COMPLETE = 2,
5
+ ERROR,
6
+ }
7
+
8
+ export enum TemplateMessageScriptOP {
9
+ GREATER = 1,
10
+ GREATER_EQ = 2,
11
+ SMALLER = 3,
12
+ SMALLER_EQ = 4,
13
+ EQUAL = 5,
14
+ UNEQUAL = 6,
15
+ HAS_TEXT = 7,
16
+ EMPTY = 8,
17
+ IS_NUMBER = 9,
18
+ IS_PHONE = 10,
19
+ IS_NOT_NUMBER = 11,
20
+ IS_NOT_PHONE,
21
+ LENGTH,
22
+ IS_ARRAY_INDEX,
23
+ IS_NOT_ARRAY_INDEX,
24
+ CUSTOM = 100,
25
+ }
26
+
27
+ export enum TEMPLATE_MESSAGE_SCRIPT_DATA_TYPE {
28
+ TEXT = 1,
29
+ NUMBER
30
+ }
31
+
32
+ export enum TemplateApiEventPosition {
33
+ BEFORE = 1,
34
+ AFTER
35
+ }
36
+
37
+ export enum TemplateApiFailActionType {
38
+ ShowErrorMessage = 1,
39
+ NextQuestion
40
+ }
41
+
42
+ export enum OperatorType {
43
+ FUNCTION = 1,
44
+ COMPARISON = 2,
45
+ FUNCTION_MULTIPLE_ARGS
46
+ }
47
+
48
+ export const MAPPING_OPERATOR_TYPE: Record<TemplateMessageScriptOP, OperatorType> = {
49
+ [TemplateMessageScriptOP.EQUAL]: OperatorType.COMPARISON,
50
+ [TemplateMessageScriptOP.UNEQUAL]: OperatorType.COMPARISON,
51
+ [TemplateMessageScriptOP.GREATER]: OperatorType.COMPARISON,
52
+ [TemplateMessageScriptOP.GREATER_EQ]: OperatorType.COMPARISON,
53
+ [TemplateMessageScriptOP.SMALLER]: OperatorType.COMPARISON,
54
+ [TemplateMessageScriptOP.SMALLER_EQ]: OperatorType.COMPARISON,
55
+ [TemplateMessageScriptOP.HAS_TEXT]: OperatorType.FUNCTION,
56
+ [TemplateMessageScriptOP.EMPTY]: OperatorType.FUNCTION,
57
+ [TemplateMessageScriptOP.IS_NUMBER]: OperatorType.FUNCTION,
58
+ [TemplateMessageScriptOP.IS_NOT_NUMBER]: OperatorType.FUNCTION,
59
+ [TemplateMessageScriptOP.IS_PHONE]: OperatorType.FUNCTION,
60
+ [TemplateMessageScriptOP.IS_NOT_PHONE]: OperatorType.FUNCTION,
61
+ [TemplateMessageScriptOP.CUSTOM]: OperatorType.FUNCTION,
62
+ [TemplateMessageScriptOP.LENGTH]: OperatorType.FUNCTION_MULTIPLE_ARGS,
63
+ [TemplateMessageScriptOP.IS_ARRAY_INDEX]: OperatorType.FUNCTION_MULTIPLE_ARGS,
64
+ [TemplateMessageScriptOP.IS_NOT_ARRAY_INDEX]: OperatorType.FUNCTION_MULTIPLE_ARGS
65
+ }
66
+
67
+ export const MAPPING_OPERATOR: Record<TemplateMessageScriptOP, string> = {
68
+ [TemplateMessageScriptOP.EQUAL]: "===",
69
+ [TemplateMessageScriptOP.UNEQUAL]: "!==",
70
+ [TemplateMessageScriptOP.GREATER]: ">",
71
+ [TemplateMessageScriptOP.GREATER_EQ]: ">=",
72
+ [TemplateMessageScriptOP.SMALLER]: "<",
73
+ [TemplateMessageScriptOP.SMALLER_EQ]: "<=",
74
+ [TemplateMessageScriptOP.HAS_TEXT]: "hasText",
75
+ [TemplateMessageScriptOP.EMPTY]: "isEmpty",
76
+ [TemplateMessageScriptOP.IS_NUMBER]: "isNumber",
77
+ [TemplateMessageScriptOP.IS_PHONE]: "isPhone",
78
+ [TemplateMessageScriptOP.IS_NUMBER]: "isNumber",
79
+ [TemplateMessageScriptOP.IS_PHONE]: "isPhone",
80
+ [TemplateMessageScriptOP.CUSTOM]: "script",
81
+ [TemplateMessageScriptOP.IS_NOT_NUMBER]: "isNotNumber",
82
+ [TemplateMessageScriptOP.IS_NOT_PHONE]: "isNotPhone",
83
+ [TemplateMessageScriptOP.LENGTH]: "length",
84
+ [TemplateMessageScriptOP.IS_ARRAY_INDEX]: "isArrayItem",
85
+ [TemplateMessageScriptOP.IS_NOT_ARRAY_INDEX]: "isNotArrayItem"
86
+ }
@@ -0,0 +1 @@
1
+ export * from './Template'
@@ -0,0 +1,4 @@
1
+ export enum VIBER_SEND_MESSAGE_TYPE {
2
+ PROMOTION = 1,
3
+ SESSION = 2
4
+ }
@@ -0,0 +1 @@
1
+ export * from './constant'
@@ -0,0 +1 @@
1
+ export * from './storage'
@@ -0,0 +1,22 @@
1
+ import { S3 } from "@aws-sdk/client-s3"
2
+
3
+ export const S3_OPTION = {
4
+ accessKeyId: process.env['S3_ACCESS_KEY'] || 'AKIATVLTGO26C3NWH2HR',
5
+ secretAccessKey: process.env['S3_SECRET_KEY'] || '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',
6
+ endpoint: process.env['S3_ENDPOINT'] || 'https://s3.ap-southeast-1.amazonaws.com',
7
+ region: process.env['S3_REGION'] || 'ap-southeast-1'
8
+ };
9
+
10
+ export const S3_INFO = {
11
+ BUCKET: process.env['S3_BUCKET'] || 'ap-southeast-1-dev-peacom'
12
+ }
13
+
14
+ export const S3_FOLDERS = {
15
+ DEFAULT: "files",
16
+ TICKET: "files"
17
+ };
18
+
19
+ export const s3 = new S3({
20
+ credentials: {accessKeyId: S3_OPTION.accessKeyId, secretAccessKey: S3_OPTION.secretAccessKey},
21
+ region: S3_OPTION.region, endpoint: S3_OPTION.endpoint
22
+ });
@@ -0,0 +1,2 @@
1
+ export * from './constants'
2
+ export * from './s3.service'
@@ -0,0 +1,128 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import {GetObjectCommand, PutObjectCommand, PutObjectCommandInput} from "@aws-sdk/client-s3";
4
+ import {getSignedUrl} from "@aws-sdk/s3-request-presigner";
5
+ import {v4 as uuidv4} from "uuid";
6
+ import {s3, S3_INFO, S3_OPTION, S3_FOLDERS} from "./constants";
7
+ import {hasText, getFileInfoFromUrl, rightString, getFileInfoFromLocalFile} from "../../../util";
8
+ import {FileInfo} from "../../../model";
9
+ import {PutObjectRequest} from "@aws-sdk/client-s3/dist-types/models/models_0";
10
+ import fetch from "node-fetch";
11
+
12
+ export const getS3Url = (key: string | null | undefined) => `https://${S3_INFO.BUCKET}.s3.${S3_OPTION.region}.amazonaws.com/${key}`
13
+
14
+ export const uploadLocalFileToS3 = async (
15
+ {filePath = ""},
16
+ folder = S3_FOLDERS.DEFAULT
17
+ ): Promise<FileInfo> => {
18
+ const rs = getFileInfoFromLocalFile(filePath)
19
+ const fileStream = fs.createReadStream(filePath);
20
+
21
+ // Setting up S3 upload parameters
22
+ const params: PutObjectCommandInput = {
23
+ Bucket: S3_INFO.BUCKET,
24
+ Key: `${folder}/${path.basename(filePath)}`,
25
+ Body: fileStream,
26
+ ContentType: rs.type,
27
+ ContentLength: rs.size
28
+ };
29
+
30
+ const command = new PutObjectCommand(params);
31
+ /*
32
+ const multipartUpload = new Upload({
33
+ client: s3,
34
+ params
35
+ })
36
+ return multipartUpload.done()
37
+ */
38
+ await s3.send(command);
39
+
40
+ return {
41
+ ...rs,
42
+ url: getS3Url(params.Key),
43
+ }
44
+ };
45
+
46
+
47
+ interface FileProp {
48
+ fileName: string
49
+ contentType: string
50
+ }
51
+
52
+ export const createPreSignedUrl = ({fileName, contentType}: FileProp) => {
53
+ const type = fileName.split(".").pop();
54
+ const location = `${S3_FOLDERS.DEFAULT}/${fileName.replace(
55
+ /[^a-zA-Z]/g,
56
+ ""
57
+ )}_${uuidv4()}.${type}`;
58
+ const command = new PutObjectCommand({
59
+ Bucket: S3_INFO.BUCKET,
60
+ Key: location,
61
+ ContentType: contentType
62
+ });
63
+ return getSignedUrl(s3, command, {expiresIn: 3600});
64
+ };
65
+
66
+ export const getUrlInfo = async (str: string): Promise<FileInfo> => {
67
+ const fileInfo = getFileInfoFromUrl(str);
68
+ const key = rightString(
69
+ str,
70
+ str.length -
71
+ `https://${S3_INFO.BUCKET}.s3.${S3_OPTION.region}.amazonaws.com/`.length
72
+ );
73
+ const input = {
74
+ // GetObjectRequest
75
+ Bucket: S3_INFO.BUCKET,
76
+ Key: key
77
+ };
78
+ const command = new GetObjectCommand(input);
79
+ const resp = await s3.send(command);
80
+ return {
81
+ ...fileInfo,
82
+ size: resp.ContentLength,
83
+ type: resp.ContentType || fileInfo.type
84
+ };
85
+ };
86
+
87
+ interface UploadS3BufferProp extends FileProp {
88
+ data: PutObjectRequest["Body"] | string | Uint8Array | Buffer;
89
+ }
90
+
91
+ const uploadS3Buffer = async (
92
+ {fileName = "", contentType = "application/octet-stream", data}: UploadS3BufferProp,
93
+ folder = S3_FOLDERS.TICKET
94
+ ): Promise<string> => {
95
+ // Setting up S3 upload parameters
96
+ const params: PutObjectCommandInput = {
97
+ Bucket: S3_INFO.BUCKET,
98
+ Key: `${folder}/${fileName}`,
99
+ Body: data
100
+ };
101
+ if (hasText(contentType)) {
102
+ params.ContentType = contentType;
103
+ }
104
+
105
+ const command = new PutObjectCommand(params);
106
+ await s3.send(command);
107
+ return getS3Url(params.Key);
108
+ };
109
+
110
+ export const uploadS3FromUrl = async (
111
+ {url = "", mimeType = "", name = ""},
112
+ folder = S3_FOLDERS.DEFAULT
113
+ ): Promise<FileInfo> => {
114
+ const data = await fetch(url).then(t => t.arrayBuffer())
115
+ const fileInfo = getFileInfoFromUrl(url);
116
+ const uploadUrl = await uploadS3Buffer(
117
+ {
118
+ fileName: name || fileInfo.name,
119
+ contentType: mimeType || fileInfo.type,
120
+ data: data as Uint8Array
121
+ },
122
+ folder
123
+ );
124
+ return {
125
+ ...fileInfo,
126
+ url: uploadUrl
127
+ }
128
+ };
@@ -0,0 +1,12 @@
1
+ import {uploadS3FromUrl} from "./s3.service";
2
+ import fetch from 'node-fetch';
3
+
4
+ describe('s3.service.specs.ts', () => {
5
+ it('uploadS3FromUrl', async () => {
6
+ const rs = await uploadS3FromUrl({url: 'https://pngimg.com/uploads/birds/birds_PNG9.png'})
7
+ console.log(rs);
8
+ expect(rs).toEqual({
9
+ name: 'birds_PNG9.png', type: 'image/png', extension: 'png'
10
+ });
11
+ });
12
+ })
@@ -0,0 +1 @@
1
+ export * from './aws'
@@ -0,0 +1,3 @@
1
+ export const DEFAULT_TIME_ZONE = 'Asia/Ho_Chi_Minh'
2
+ export const DATE_FORMAT = "YYYY-MM-DD";
3
+ export const DATE_TIME_FORMAT = "YYYY-MM-DD HH:mm:ss";
@@ -0,0 +1,22 @@
1
+ import {addHours, endOfDate, endOfWeek, formatDateTimeTZ, startOfWeeks} from "./date.util";
2
+ import {DEFAULT_TIME_ZONE} from "./constant";
3
+
4
+ describe('date.util', () => {
5
+ it('should work', () => {
6
+ const dateStr = '2022-12-20T10:23:55Z'
7
+ const VN_DateStr = '2022-12-20 17:23:55'
8
+ expect(formatDateTimeTZ(new Date(dateStr))).toEqual(VN_DateStr);
9
+ expect(formatDateTimeTZ(dateStr)).toEqual(VN_DateStr);
10
+ });
11
+ it('endOfDate', () => {
12
+ console.log(endOfDate(new Date(), DEFAULT_TIME_ZONE))
13
+ });
14
+ it('addHour', () => {
15
+ console.log(addHours(new Date(), -0.25))
16
+ });
17
+ it('startOfWeek', () => {
18
+ const dateStr = '2022-12-20T10:23:55Z'
19
+ console.log(startOfWeeks(new Date(dateStr), DEFAULT_TIME_ZONE))
20
+ console.log(endOfWeek(new Date(dateStr), DEFAULT_TIME_ZONE))
21
+ });
22
+ });
@@ -0,0 +1,64 @@
1
+ import {DATE_TIME_FORMAT, DEFAULT_TIME_ZONE} from "./constant";
2
+ import * as moment from "moment-timezone";
3
+
4
+ type DateType = Date | string
5
+
6
+ export function formatDateTimeTZ(
7
+ date: DateType,
8
+ timezone = DEFAULT_TIME_ZONE,
9
+ format = DATE_TIME_FORMAT
10
+ ) {
11
+ return moment(date).tz(timezone).format(format);
12
+ }
13
+
14
+ export const getDate = (date: DateType, tz = "") => {
15
+ if (!tz) return moment(date)
16
+ return moment(date).tz(tz)
17
+ }
18
+
19
+ export function endOfDate(date: DateType, tz = "") {
20
+ return getDate(date, tz).endOf("date").toDate()
21
+ }
22
+
23
+ export function startOfDate(date: DateType, tz = "") {
24
+ return getDate(date, tz).startOf("date").toDate();
25
+ }
26
+
27
+ export function addHours(date: DateType, hours: number, tz = "") {
28
+ return getDate(date, tz).add(hours, "hours").toDate();
29
+ }
30
+
31
+ /**
32
+ * Week start from sunday
33
+ * @param date
34
+ * @param tz
35
+ */
36
+ export function startOfWeeks(date: DateType, tz = "") {
37
+ return getDate(date, tz).startOf("week").toDate()
38
+ }
39
+
40
+ export function endOfWeek(date: DateType, tz = "") {
41
+ return getDate(date, tz).endOf("week").toDate()
42
+ }
43
+
44
+ export function lastWeek(date: DateType, tz = "") {
45
+ return getDate(date, tz).subtract(1, "week").startOf("week").toDate()
46
+ }
47
+
48
+ export function differentMinute(date: DateType, date1: DateType) {
49
+ return Math.ceil(moment(date).diff(moment(date1), "minutes", true));
50
+ }
51
+
52
+ export function formatTimeTZ(date: DateType, timezone = DEFAULT_TIME_ZONE, format = "LT") {
53
+ return moment(date).tz(timezone).format(format);
54
+ }
55
+
56
+ export const parseDateTimeByFormat = (
57
+ dateStr: string,
58
+ format = DATE_TIME_FORMAT,
59
+ timezone = DEFAULT_TIME_ZONE
60
+ ) => {
61
+ return moment
62
+ .tz(`${dateStr}`, DATE_TIME_FORMAT, timezone)
63
+ .toDate();
64
+ };
@@ -0,0 +1,2 @@
1
+ export * from './constant'
2
+ export * from './date.util'