@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.
- package/.eslintrc.json +18 -0
- package/data/Chuyen-de-1.pdf +63386 -304
- package/data/report_bulk_campaign_Kplus_1665394311017.xlsx +0 -0
- package/jest.config.ts +16 -0
- package/package.json +9 -10
- package/project.json +41 -0
- package/src/index.ts +5 -0
- package/src/lib/api/api.constant.ts +82 -0
- package/src/lib/api/core.api.ts +86 -0
- package/src/lib/api/index.ts +4 -0
- package/src/lib/api/micro-service.api.ts +35 -0
- package/src/lib/api/micro-service.spec.ts +29 -0
- package/src/lib/api/queue/queue.api.ts +39 -0
- package/src/lib/core.spec.ts +7 -0
- package/src/lib/core.ts +3 -0
- package/src/lib/error/FormError.ts +64 -0
- package/src/lib/error/HttpError.ts +9 -0
- package/src/lib/model/Application.ts +63 -0
- package/src/lib/model/BackgroundTask.ts +5 -0
- package/src/lib/model/Billing.ts +11 -0
- package/src/lib/model/Currency.ts +5 -0
- package/src/lib/model/FileInfo.ts +9 -0
- package/src/lib/model/conversation/constant.ts +34 -0
- package/src/lib/model/conversation/index.ts +1 -0
- package/src/lib/model/index.ts +11 -0
- package/src/lib/model/message/Message.ts +159 -0
- package/src/lib/model/message/TemplateMessage.ts +4 -0
- package/src/lib/model/message/index.ts +4 -0
- package/src/lib/model/message/sinch/SinchWhatsappTemplate.ts +27 -0
- package/src/lib/model/message/zalo/ZaloZNSTemplate.ts +26 -0
- package/src/lib/model/partner/PartnerEvent.ts +24 -0
- package/src/lib/model/partner/index.ts +6 -0
- package/src/lib/model/queue/QueueMessage.ts +31 -0
- package/src/lib/model/queue/index.ts +2 -0
- package/src/lib/model/queue/queue.constant.ts +6 -0
- package/src/lib/model/template/Template.ts +86 -0
- package/src/lib/model/template/index.ts +1 -0
- package/src/lib/model/viber-business/constant.ts +4 -0
- package/src/lib/model/viber-business/index.ts +1 -0
- package/src/lib/service/index.ts +1 -0
- package/src/lib/service/storage/aws/constants.ts +22 -0
- package/src/lib/service/storage/aws/index.ts +2 -0
- package/src/lib/service/storage/aws/s3.service.ts +128 -0
- package/src/lib/service/storage/aws/s3.spec.ts +12 -0
- package/src/lib/service/storage/index.ts +1 -0
- package/src/lib/util/date/constant.ts +3 -0
- package/src/lib/util/date/date.spec.ts +22 -0
- package/src/lib/util/date/date.util.ts +64 -0
- package/src/lib/util/date/index.ts +2 -0
- package/src/lib/util/file/file.spec.ts +40 -0
- package/src/lib/util/file/file.util.ts +60 -0
- package/src/lib/util/general.util.ts +3 -0
- package/src/lib/util/index.ts +6 -0
- package/src/lib/util/message/message.util.ts +118 -0
- package/src/lib/util/phone.spec.ts +48 -0
- package/src/lib/util/phone.util.ts +51 -0
- package/src/lib/util/string.spec.ts +15 -0
- package/src/lib/util/string.util.ts +118 -0
- package/tsconfig.json +22 -0
- package/tsconfig.lib.json +10 -0
- package/tsconfig.spec.json +14 -0
- package/src/index.d.ts +0 -4
- package/src/index.js +0 -8
- package/src/index.js.map +0 -1
- package/src/lib/api/api.constant.d.ts +0 -58
- package/src/lib/api/api.constant.js +0 -20
- package/src/lib/api/api.constant.js.map +0 -1
- package/src/lib/api/core.api.d.ts +0 -9
- package/src/lib/api/core.api.js +0 -78
- package/src/lib/api/core.api.js.map +0 -1
- package/src/lib/api/index.d.ts +0 -4
- package/src/lib/api/index.js +0 -8
- package/src/lib/api/index.js.map +0 -1
- package/src/lib/api/micro-service.api.d.ts +0 -2
- package/src/lib/api/micro-service.api.js +0 -38
- package/src/lib/api/micro-service.api.js.map +0 -1
- package/src/lib/api/queue/queue.api.d.ts +0 -7
- package/src/lib/api/queue/queue.api.js +0 -37
- package/src/lib/api/queue/queue.api.js.map +0 -1
- package/src/lib/core.d.ts +0 -1
- package/src/lib/core.js +0 -8
- package/src/lib/core.js.map +0 -1
- package/src/lib/error/FormError.d.ts +0 -53
- package/src/lib/error/FormError.js +0 -58
- package/src/lib/error/FormError.js.map +0 -1
- package/src/lib/error/HttpError.d.ts +0 -4
- package/src/lib/error/HttpError.js +0 -12
- package/src/lib/error/HttpError.js.map +0 -1
- package/src/lib/model/Application.d.ts +0 -52
- package/src/lib/model/Application.js +0 -59
- package/src/lib/model/Application.js.map +0 -1
- package/src/lib/model/Billing.d.ts +0 -10
- package/src/lib/model/Billing.js +0 -16
- package/src/lib/model/Billing.js.map +0 -1
- package/src/lib/model/Currency.d.ts +0 -4
- package/src/lib/model/Currency.js +0 -9
- package/src/lib/model/Currency.js.map +0 -1
- package/src/lib/model/FileInfo.d.ts +0 -9
- package/src/lib/model/FileInfo.js +0 -3
- package/src/lib/model/FileInfo.js.map +0 -1
- package/src/lib/model/conversation/constant.d.ts +0 -25
- package/src/lib/model/conversation/constant.js +0 -25
- package/src/lib/model/conversation/constant.js.map +0 -1
- package/src/lib/model/conversation/index.d.ts +0 -1
- package/src/lib/model/conversation/index.js +0 -5
- package/src/lib/model/conversation/index.js.map +0 -1
- package/src/lib/model/index.d.ts +0 -10
- package/src/lib/model/index.js +0 -14
- package/src/lib/model/index.js.map +0 -1
- package/src/lib/model/message/Message.d.ts +0 -129
- package/src/lib/model/message/Message.js +0 -88
- package/src/lib/model/message/Message.js.map +0 -1
- package/src/lib/model/message/TemplateMessage.d.ts +0 -4
- package/src/lib/model/message/TemplateMessage.js +0 -9
- package/src/lib/model/message/TemplateMessage.js.map +0 -1
- package/src/lib/model/message/index.d.ts +0 -4
- package/src/lib/model/message/index.js +0 -8
- package/src/lib/model/message/index.js.map +0 -1
- package/src/lib/model/message/sinch/SinchWhatsappTemplate.d.ts +0 -22
- package/src/lib/model/message/sinch/SinchWhatsappTemplate.js +0 -14
- package/src/lib/model/message/sinch/SinchWhatsappTemplate.js.map +0 -1
- package/src/lib/model/message/zalo/ZaloZNSTemplate.d.ts +0 -23
- package/src/lib/model/message/zalo/ZaloZNSTemplate.js +0 -3
- package/src/lib/model/message/zalo/ZaloZNSTemplate.js.map +0 -1
- package/src/lib/model/partner/PartnerEvent.d.ts +0 -22
- package/src/lib/model/partner/PartnerEvent.js +0 -3
- package/src/lib/model/partner/PartnerEvent.js.map +0 -1
- package/src/lib/model/partner/index.d.ts +0 -5
- package/src/lib/model/partner/index.js +0 -11
- package/src/lib/model/partner/index.js.map +0 -1
- package/src/lib/model/queue/QueueMessage.d.ts +0 -28
- package/src/lib/model/queue/QueueMessage.js +0 -9
- package/src/lib/model/queue/QueueMessage.js.map +0 -1
- package/src/lib/model/queue/index.d.ts +0 -2
- package/src/lib/model/queue/index.js +0 -6
- package/src/lib/model/queue/index.js.map +0 -1
- package/src/lib/model/queue/queue.constant.d.ts +0 -6
- package/src/lib/model/queue/queue.constant.js +0 -11
- package/src/lib/model/queue/queue.constant.js.map +0 -1
- package/src/lib/model/template/Template.d.ts +0 -43
- package/src/lib/model/template/Template.js +0 -89
- package/src/lib/model/template/Template.js.map +0 -1
- package/src/lib/model/template/index.d.ts +0 -1
- package/src/lib/model/template/index.js +0 -5
- package/src/lib/model/template/index.js.map +0 -1
- package/src/lib/model/viber-business/constant.d.ts +0 -4
- package/src/lib/model/viber-business/constant.js +0 -9
- package/src/lib/model/viber-business/constant.js.map +0 -1
- package/src/lib/model/viber-business/index.d.ts +0 -1
- package/src/lib/model/viber-business/index.js +0 -5
- package/src/lib/model/viber-business/index.js.map +0 -1
- package/src/lib/util/date/constant.d.ts +0 -3
- package/src/lib/util/date/constant.js +0 -7
- package/src/lib/util/date/constant.js.map +0 -1
- package/src/lib/util/date/date.util.d.ts +0 -19
- package/src/lib/util/date/date.util.js +0 -59
- package/src/lib/util/date/date.util.js.map +0 -1
- package/src/lib/util/date/index.d.ts +0 -2
- package/src/lib/util/date/index.js +0 -6
- package/src/lib/util/date/index.js.map +0 -1
- package/src/lib/util/file/file.util.d.ts +0 -5
- package/src/lib/util/file/file.util.js +0 -35
- package/src/lib/util/file/file.util.js.map +0 -1
- package/src/lib/util/general.util.d.ts +0 -1
- package/src/lib/util/general.util.js +0 -8
- package/src/lib/util/general.util.js.map +0 -1
- package/src/lib/util/index.d.ts +0 -6
- package/src/lib/util/index.js +0 -10
- package/src/lib/util/index.js.map +0 -1
- package/src/lib/util/message/message.util.d.ts +0 -90
- package/src/lib/util/message/message.util.js +0 -72
- package/src/lib/util/message/message.util.js.map +0 -1
- package/src/lib/util/phone.util.d.ts +0 -24
- package/src/lib/util/phone.util.js +0 -51
- package/src/lib/util/phone.util.js.map +0 -1
- package/src/lib/util/string.util.d.ts +0 -14
- package/src/lib/util/string.util.js +0 -118
- 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,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,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,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 @@
|
|
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'] || 'qDIfB+fTlxWVvHf7VtY4TiWYyqcreSAPYXwclLIq',
|
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,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,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
|
+
};
|