@phonghq/go-chat 1.0.35 → 1.0.38

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 (31) hide show
  1. package/dist/assets/icons/IconSms.vue.d.ts +2 -0
  2. package/dist/chat/page/home/ChatList.vue.d.ts +29 -0
  3. package/dist/composable/useError.d.ts +4 -0
  4. package/dist/composable/usePlivo.d.ts +4 -1
  5. package/dist/constant/mqtt.d.ts +2 -2
  6. package/dist/go-chat.es.js +23215 -23193
  7. package/dist/go-chat.umd.js +14 -13
  8. package/dist/style.css +1 -1
  9. package/dist/test/assets/icons/IconSms.vue.js +22 -0
  10. package/dist/test/chat/App.vue.js +111 -60
  11. package/dist/test/chat/page/home/ChatList.vue.js +34 -49
  12. package/dist/test/chat/page/home/ChatMessageItem.vue.js +5 -5
  13. package/dist/test/chat/page/home/Home.vue.js +5 -4
  14. package/dist/test/chat/page/home/HomeHeader.vue.js +81 -4
  15. package/dist/test/chat/page/home/InputChat.vue.js +22 -66
  16. package/dist/test/chat/page/home/NewCustomer.vue.js +3 -2
  17. package/dist/test/components/chat/ScrollEvent/ScrollEvent.vue.js +2 -0
  18. package/dist/test/components/chat/call/Calling.vue.js +46 -6
  19. package/dist/test/composable/useError.js +10 -0
  20. package/dist/test/composable/useListConversations.js +4 -1
  21. package/dist/test/composable/usePlivo.js +30 -23
  22. package/dist/test/constant/mqtt.js +4 -3
  23. package/dist/test/utils/chat/auth.js +11 -0
  24. package/dist/test/utils/chat/call.js +16 -0
  25. package/dist/test/utils/chat/conversation.js +3 -3
  26. package/dist/test/utils/string-helper.js +1 -1
  27. package/dist/types/chat/auth.d.ts +1 -0
  28. package/dist/types/message.d.ts +1 -0
  29. package/dist/utils/chat/auth.d.ts +5 -0
  30. package/dist/utils/chat/call.d.ts +4 -0
  31. package/package.json +1 -1
@@ -12,6 +12,8 @@ import IconClose from '../../../assets/icons/call/IconClose.vue';
12
12
  import { usePlivo } from '../../../composable/usePlivo';
13
13
  import { PLIVO_CALL_STATUS } from '../../../types/chat/call';
14
14
  import IconMic from '../../../assets/icons/call/IconMic.vue';
15
+ import { useError } from '../../../composable/useError';
16
+ import { useDebounce } from '../../../utils/debounce';
15
17
  const props = withDefaults(defineProps(), {});
16
18
  const emit = defineEmits();
17
19
  // const {
@@ -49,6 +51,7 @@ const handlePlivoCallBack = (status, data) => {
49
51
  }
50
52
  };
51
53
  const { plivoLogin, plivoCallAnswer, plivoCall, plivoEndCall, plivoCallSwishMute } = usePlivo(handlePlivoCallBack);
54
+ const { showError } = useError();
52
55
  const STATUS_LABEL = computed(() => {
53
56
  return {
54
57
  [PLIVO_CALL_STATUS.CONNECTING]: 'Connecting...',
@@ -76,13 +79,20 @@ const userRemoter = ref(null);
76
79
  const isMute = ref(false);
77
80
  let timer = null;
78
81
  let timeOut = null;
82
+ let refreshTokenTimeOut = null;
83
+ let refreshTokenCount = null;
79
84
  let callType = 'call';
80
85
  let uuidEnd = '';
81
86
  onMounted(async () => {
82
- if (dataProfile.value?.tenant_phone) {
83
- const token = await getPlivoAccessToken();
84
- // const token = ''
85
- await plivoLogin(token);
87
+ try {
88
+ if (dataProfile.value?.tenant_phone) {
89
+ const token = await getPlivoAccessToken();
90
+ await plivoLogin({ token });
91
+ setTimeout(refreshToken, 1000);
92
+ }
93
+ }
94
+ catch {
95
+ showError('We’re having trouble connecting the call. Please try again in a moment');
86
96
  }
87
97
  });
88
98
  onUnmounted(() => {
@@ -108,6 +118,9 @@ function endCall(option) {
108
118
  drawerVisible.value = false;
109
119
  drawerVisibleRef.value?.close();
110
120
  }
121
+ else {
122
+ handleEmitEndCall(userRemoter.value, callType);
123
+ }
111
124
  plivoEndCall(callStatus.value);
112
125
  callStatus.value = PLIVO_CALL_STATUS.CALL_END;
113
126
  clearInterval(timer);
@@ -118,9 +131,36 @@ function endCall(option) {
118
131
  clearInterval(timer);
119
132
  if (timeOut)
120
133
  clearTimeout(timeOut);
121
- emit('endCall', userRemoter.value, callType);
122
134
  callType = '';
123
135
  }
136
+ const handleEmitEndCall = useDebounce((data, type) => {
137
+ emit('endCall', data, type);
138
+ }, 500);
139
+ const refreshToken = async () => {
140
+ try {
141
+ console.log('refreshToken: ');
142
+ if (refreshTokenTimeOut) {
143
+ clearTimeout(refreshTokenTimeOut);
144
+ refreshTokenTimeOut = null;
145
+ }
146
+ const token = await getPlivoAccessToken();
147
+ await plivoLogin({ token, isRefresh: true });
148
+ setTimeout(() => refreshToken(), 15 * 60 * 1000);
149
+ refreshTokenCount = 0;
150
+ }
151
+ catch (e) {
152
+ console.log(e);
153
+ refreshTokenCount = refreshTokenCount + 1;
154
+ console.log(refreshTokenCount);
155
+ if (refreshTokenCount < 3) {
156
+ setTimeout(() => refreshToken(), 60 * 1000);
157
+ }
158
+ else {
159
+ showError('We’re having trouble connecting the call. Please try again in a moment');
160
+ }
161
+ console.log(e);
162
+ }
163
+ };
124
164
  const open = () => {
125
165
  drawerVisible.value = true;
126
166
  disable.value = true;
@@ -159,7 +199,7 @@ const answer = async () => {
159
199
  const getUserOffer = async (phone) => {
160
200
  let res = null;
161
201
  try {
162
- userRemoter.value = null;
202
+ userRemoter.value = { phone, username: '' };
163
203
  let data = {
164
204
  phone: formatPhone10number(phone, '1'),
165
205
  client_id: dataProfile.value?.tenant_id ?? ''
@@ -0,0 +1,10 @@
1
+ import { ref } from 'vue';
2
+ export const goChatError = ref('');
3
+ export function useError() {
4
+ const showError = (error) => {
5
+ goChatError.value = error;
6
+ };
7
+ return {
8
+ showError
9
+ };
10
+ }
@@ -36,6 +36,7 @@ export const useListConversations = (is_unknown) => {
36
36
  if (dataProfile.value) {
37
37
  await connectMqtt();
38
38
  TOPIC_HOME.forEach((item) => {
39
+ console.log(item + dataProfile.value?.id);
39
40
  subscribeToTopic(item + dataProfile.value?.id);
40
41
  addHandleMqttMessage('chat-list-' + item + '-' + is_unknown, item + dataProfile.value?.id, mqttMessageHandler);
41
42
  });
@@ -51,7 +52,8 @@ export const useListConversations = (is_unknown) => {
51
52
  if ((data.is_unknown ?? 0) != is_unknown)
52
53
  return;
53
54
  getDataMqtt();
54
- if (topic === TOPIC_HOME[0] + dataProfile.value?.id) {
55
+ if ((topic === TOPIC_HOME[0] + dataProfile.value?.id) || topic === (TOPIC_HOME[3] + dataProfile.value?.id)) {
56
+ console.log(data);
55
57
  const index = listConversations.value.findIndex((item) => item.id === data.id);
56
58
  const hasChatBox = listConversations.value.findIndex((item) => item.id === digibotId);
57
59
  if (index != -1) {
@@ -79,6 +81,7 @@ export const useListConversations = (is_unknown) => {
79
81
  listConversations.value[index].status = data.is_online ? 1 : 0;
80
82
  }
81
83
  }
84
+ console.log(listConversations.value, is_unknown);
82
85
  };
83
86
  const getDataMqtt = useDebounce(() => {
84
87
  getData(undefined, { hideLoading: true, reset: true });
@@ -1,4 +1,6 @@
1
1
  import { PLIVO_CALL_STATUS } from '../types/chat/call';
2
+ import { createSipAccount } from '../utils/chat/call';
3
+ import { dataProfile } from '../utils/chat/auth';
2
4
  export function usePlivo(callback) {
3
5
  var options = {
4
6
  debug: 'ALL',
@@ -12,36 +14,41 @@ export function usePlivo(callback) {
12
14
  let CallUuid = '';
13
15
  let custom_resolve = null;
14
16
  let custom_reject = null;
15
- const plivoLogin = async (token) => {
17
+ const plivoLogin = async (data) => {
16
18
  // token =
17
19
  // 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImN0eSI6InBsaXZvO3Y9MSJ9.eyJqdGkiOiJ0ZXN0MSIsImlzcyI6IlNBTjJZMFpERTRNSkFUTVpZNU5DIiwic3ViIjoid2ViY2FsbDAwMzA3OTY3MzQ1NDg5MTgyNyIsIm5iZiI6MTc2MzY5MzUyNSwiZXhwIjoxNzYzNzc5OTI1LCJncmFudHMiOnsidm9pY2UiOnsiaW5jb21pbmdfYWxsb3ciOnRydWUsIm91dGdvaW5nX2FsbG93Ijp0cnVlfX19.9p4O_xTb4kNhKyDVfK3EemSKBQiHtbKNUZ5iwnSdX1I'
18
20
  try {
19
- if (!plivoBrowserSdk)
21
+ if (!plivoBrowserSdk) {
20
22
  plivoBrowserSdk = new window.Plivo(options);
21
- plivoBrowserSdk?.client?.on?.('onCallAnswered', (callInfo) => {
22
- handleCallAnswered(callInfo);
23
- });
24
- plivoBrowserSdk?.client?.on?.('onCallTerminated', (hangupInfo, callInfo) => handleCallTerminated(hangupInfo, callInfo));
25
- plivoBrowserSdk.client.on('onCallFailed', (data, callInfo) => {
26
- handleCallFailed(data, callInfo);
27
- });
28
- plivoBrowserSdk.client.on('onIncomingCallCanceled', (callInfo) => {
29
- handleIncomingCallCanceled(callInfo);
30
- });
31
- // plivoBrowserSdk.client.on('onCalling', (data: any) => console.log('onCallFailed', data))
32
- plivoBrowserSdk?.client?.on?.('onIncomingCall', (callerID, extraHeaders, callInfo) => {
33
- handleIncomingCall(callInfo);
34
- });
35
- plivoBrowserSdk.client.on('onCallRemoteRinging', (data) => handleCallRemoteRinging(data));
36
- plivoBrowserSdk.client.on('onMediaPermission', (e) => handleMediaPermission(e));
37
- plivoBrowserSdk?.client?.on?.('onLoginFailed', (e) => handleLoginFailed(e));
38
- // plivoBrowserSdk?.client?.on?.('remoteAudioStatus', () => console.log('remoteAudioStatus'))
39
- const payload = JSON.parse(atob(token.split('.')[1]));
40
- // console.log(payload)
23
+ plivoBrowserSdk?.client?.on?.('onCallAnswered', (callInfo) => {
24
+ handleCallAnswered(callInfo);
25
+ });
26
+ plivoBrowserSdk?.client?.on?.('onCallTerminated', (hangupInfo, callInfo) => handleCallTerminated(hangupInfo, callInfo));
27
+ plivoBrowserSdk.client.on('onCallFailed', (data, callInfo) => {
28
+ handleCallFailed(data, callInfo);
29
+ });
30
+ plivoBrowserSdk.client.on('onIncomingCallCanceled', (callInfo) => {
31
+ handleIncomingCallCanceled(callInfo);
32
+ });
33
+ // plivoBrowserSdk.client.on('onCalling', (data: any) => console.log('onCallFailed', data))
34
+ plivoBrowserSdk?.client?.on?.('onIncomingCall', (callerID, extraHeaders, callInfo) => {
35
+ handleIncomingCall(callInfo);
36
+ });
37
+ plivoBrowserSdk.client.on('onCallRemoteRinging', (data) => handleCallRemoteRinging(data));
38
+ plivoBrowserSdk.client.on('onMediaPermission', (e) => handleMediaPermission(e));
39
+ plivoBrowserSdk?.client?.on?.('onLoginFailed', (e) => handleLoginFailed(e));
40
+ }
41
+ if (!data.isRefresh) {
42
+ const payload = JSON.parse(atob(data.token.split('.')[1]));
43
+ await createSipAccount({
44
+ sip_username: `${payload.sub}_${payload.iss}`,
45
+ did_number: dataProfile.value?.tenant_phone ?? ''
46
+ });
47
+ }
41
48
  // await plivoBrowserSdk?.client?.tokenLogin(payload.sub ?? '', token)
42
49
  // await plivoBrowserSdk?.client?.login('webcall003079673454891827', '123456abcA!')
43
50
  // await plivoBrowserSdk?.client?.login(payload.sub , null, token)
44
- await plivoBrowserSdk?.client?.loginWithAccessToken(token);
51
+ await plivoBrowserSdk?.client?.loginWithAccessToken(data.token);
45
52
  // await plivoBrowserSdk?.client?.on?.(payload)
46
53
  // console.log('Registered with token')
47
54
  }
@@ -1,12 +1,13 @@
1
1
  export const TOPIC_DETAIL_CHAT = 'chat/message/';
2
2
  export const TOPIC_DETAIL_CALL = 'call/message/';
3
+ export const TOPIC_PLIVO_SMS = 'sms-inbound/';
4
+ export const TOPIC_STATUS_USER = 'user/status/';
3
5
  export const TOPIC_HOME = [
4
6
  'chat/conversation/update/',
5
7
  'chat/conversation/read_message/',
6
- 'chat/conversation/update_list/'
8
+ 'chat/conversation/update_list/',
9
+ 'chat/conversation/update/sms-inbound/'
7
10
  ];
8
- export const TOPIC_PLIVO_SMS = 'sms-outbound/';
9
- export const TOPIC_STATUS_USER = 'user/status/';
10
11
  // export CALL_STATE = {
11
12
  // Offer: 'offer',
12
13
  // }
@@ -41,6 +41,7 @@ export const getProfile = async () => {
41
41
  export const checkTenantPhone = async () => {
42
42
  const id = localStorage.getItem('chat_id');
43
43
  const res = await axios.get(`/api/v1/message/tenant/get-info?tenant_name=${id}`);
44
+ console.log(res, '5555555555555555');
44
45
  if (res.error || !res?.data)
45
46
  throw new Error(res.error);
46
47
  if (dataProfile.value)
@@ -48,6 +49,10 @@ export const checkTenantPhone = async () => {
48
49
  // if(dataProfile.value) dataProfile.value.tenant_phone = ''
49
50
  if (dataProfile.value)
50
51
  dataProfile.value.tenant_phone_limit = Number(res?.data?.go_chat_phone_limit ?? 0);
52
+ if (dataProfile.value?.phone != dataProfile.value?.tenant_phone &&
53
+ dataProfile.value?.tenant_phone) {
54
+ updateProfile({ phone: dataProfile.value?.tenant_phone });
55
+ }
51
56
  return res;
52
57
  };
53
58
  export const submitTenantPhone = async (body) => {
@@ -55,6 +60,12 @@ export const submitTenantPhone = async (body) => {
55
60
  dataLoginLink.value = res;
56
61
  return res;
57
62
  };
63
+ export const updateProfile = async (body) => {
64
+ const res = await axios.post('/api/v1/message/tenant/update', { ...body, id: dataProfile.value?.id });
65
+ console.log(res);
66
+ dataProfile.value = res;
67
+ return res;
68
+ };
58
69
  export const logout = async () => {
59
70
  dataLogin = { id: '', token: '', domain: '' };
60
71
  dataProfile.value = null;
@@ -137,3 +137,19 @@ export const getPlivoAccessToken = async () => {
137
137
  const result = await response.json();
138
138
  return result?.accessToken;
139
139
  };
140
+ export const createSipAccount = async (data) => {
141
+ const url = BARE_WEBSOCKET_URL + '/ws/create-sip-account';
142
+ const response = await fetch(url, {
143
+ method: 'POST',
144
+ body: JSON.stringify(data),
145
+ headers: {
146
+ ['Content-Type']: 'application/json'
147
+ }
148
+ });
149
+ if (!response.ok) {
150
+ throw new Error(`Response status: ${response.status}`);
151
+ }
152
+ const result = await response.json();
153
+ console.log(result);
154
+ return result;
155
+ };
@@ -30,7 +30,7 @@ export const publicTopicConversationUpdate = async (data) => {
30
30
  const current = dayjs().tz(TIME_ZONE_UTC).format(DATE_FORMATS['DATE_FORMAT_FULL']);
31
31
  const dataMessageForReceiver = {
32
32
  id: data.infoUser?.conversation_id ?? 0,
33
- receiver_id: Number(dataProfile.value?.id ?? 0),
33
+ receiver_id: Number(data.infoUser?.id ?? 0),
34
34
  username: dataProfile.value?.username ?? '',
35
35
  phone: dataProfile.value?.phone ?? '',
36
36
  avatar: dataProfile.value?.avatar ?? '',
@@ -42,12 +42,12 @@ export const publicTopicConversationUpdate = async (data) => {
42
42
  status: 1,
43
43
  color: dataProfile.value?.color ?? '',
44
44
  is_call: dataProfile.value?.color ?? '',
45
- is_unknown: 0
45
+ is_unknown: data.infoUser?.is_unknown ?? 0,
46
46
  };
47
47
  publishMessage(`${TOPIC_HOME[0] + Number(data.infoUser?.id)}`, JSON.stringify(dataMessageForReceiver));
48
48
  const dataMessageMyself = {
49
49
  id: data.infoUser?.conversation_id ?? 0,
50
- receiver_id: Number(dataProfile.value?.id ?? 0),
50
+ receiver_id: Number(data.infoUser?.id ?? 0),
51
51
  username: data.infoUser?.username ?? '',
52
52
  phone: data.infoUser?.phone ?? '',
53
53
  avatar: data.infoUser?.avatar ?? '',
@@ -4,7 +4,7 @@ export const phoneNumberFormat = (phone, halfShowType = 1) => {
4
4
  number = number.substring(number.length - 10);
5
5
  }
6
6
  if (number.length == 10) {
7
- if (true) {
7
+ if (false) {
8
8
  if (halfShowType == 4) {
9
9
  number = (number || '').replace(/(\d{3})(\d{3})(\d{4})/, "*** $3");
10
10
  }
@@ -26,6 +26,7 @@ interface IResProfile {
26
26
  user_type: 'customer' | 'tenant';
27
27
  has_business_tenant_phone?: boolean;
28
28
  color: string;
29
+ is_sms_active: number;
29
30
  }
30
31
  interface IPramsLoginLink {
31
32
  tenant_id: string;
@@ -20,6 +20,7 @@ export type IResMessage = {
20
20
  message_uuid?: string | null;
21
21
  is_call?: number | null;
22
22
  duration?: number | null;
23
+ is_sms: number;
23
24
  record_url?: string | null;
24
25
  call_status?: string | null;
25
26
  created_at: string;
@@ -20,6 +20,7 @@ export declare const dataProfile: import("vue").Ref<{
20
20
  user_type: "customer" | "tenant";
21
21
  has_business_tenant_phone?: boolean | undefined;
22
22
  color: string;
23
+ is_sms_active: number;
23
24
  } | null, IResProfile | {
24
25
  id: number;
25
26
  username: string;
@@ -31,6 +32,7 @@ export declare const dataProfile: import("vue").Ref<{
31
32
  user_type: "customer" | "tenant";
32
33
  has_business_tenant_phone?: boolean | undefined;
33
34
  color: string;
35
+ is_sms_active: number;
34
36
  } | null>;
35
37
  export declare const dataLoginLink: import("vue").Ref<{
36
38
  token: string;
@@ -52,5 +54,8 @@ export declare const submitTenantPhone: (body: {
52
54
  phone: string;
53
55
  tenant_id: string;
54
56
  }) => Promise<any>;
57
+ export declare const updateProfile: (body: {
58
+ phone: string;
59
+ }) => Promise<any>;
55
60
  export declare const logout: () => Promise<void>;
56
61
  export {};
@@ -9,3 +9,7 @@ export declare const plivoCall: (user: IResUser) => Promise<any>;
9
9
  export declare const plivoEndCall: (uuid: string) => Promise<void>;
10
10
  export declare const downloadRecord: (url_pub: string) => Promise<void>;
11
11
  export declare const getPlivoAccessToken: () => Promise<any>;
12
+ export declare const createSipAccount: (data: {
13
+ did_number: string;
14
+ sip_username: string;
15
+ }) => Promise<any>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phonghq/go-chat",
3
- "version": "1.0.35",
3
+ "version": "1.0.38",
4
4
  "private": false,
5
5
  "files": [
6
6
  "dist"