UNPKG

@tencentcloud/ai-desk-customer-uniapp

Version:

uni-app Vue2/Vue3 UIKit for AI Desk

321 lines (290 loc) 10.3 kB
import { isCustomerServiceMessage, isThinkingMessage, isMessageInvisible, clearChatStorage, } from './utils/index'; import TUIChatEngine, { TUIChatService, TUIConversationService, IMessageModel, TUITranslateService, SendMessageParams, SendMessageOptions, TUIUserService, TUIStore, StoreName, func, } from './@aidesk/uikit-engine'; import Log from './utils/logger'; import { version } from './package.json' import { Toast, TOAST_TYPE } from "./components/common/Toast/index-uniapp"; import { vueVersion } from "./adapter-vue-uniapp"; import { switchReadStatus, transferToTaskFlow, transferToHuman, validateUserID, updateCustomStore } from "./utils/utils"; import state from "./utils/state"; import { USER_DEFAULT_AVATAR } from "./constant"; import { ITransferToTaskFlowModel, ITransferToHumanModel } from "./interface"; interface IInitWithProfile { SDKAppID: number, userID: string, userSig: string, nickName?: string, avatar?: string, customerServiceID?: string, scene?: string; } interface IProfile { nick?: string, avatar?: string, } export default class TUICustomerServer { private isLoggedIn: boolean; static instance: TUICustomerServer; private customerServiceIDList: any[]; private currentCustomerServiceID: string; private loggedInUserID: string; private myProfile: IProfile; private bindOnActionConversation: func; private paramsForActiveAgain: any; private _scene: string; constructor() { this.customerServiceIDList = ['@customer_service_account']; this.currentCustomerServiceID = this.customerServiceIDList[0]; this.isLoggedIn = false; this.loggedInUserID = ''; this.myProfile = { avatar: USER_DEFAULT_AVATAR }; this.bindOnActionConversation = this.onActiveConversation.bind(this); this._scene = ''; } static getInstance(): TUICustomerServer { if (!TUICustomerServer.instance) { TUICustomerServer.instance = new TUICustomerServer(); } return TUICustomerServer.instance; } private async loginCustomerUIKit(SDKAppID:number, userID:string, userSig:string) { clearChatStorage(SDKAppID, userID); return TUIChatEngine.login({ SDKAppID, userID, userSig, useUploadPlugin: true, scene: this._scene, }).then(() => { Log.i(`login success. userID:${userID}`); this.isLoggedIn = true; this.loggedInUserID = userID; TUIStore.watch(StoreName.CUSTOM, { 'activeConversation': this.bindOnActionConversation, }); this.switchConversation(`C2C${this.currentCustomerServiceID}`); switchReadStatus(state.get('showReadStatus')); TUIChatEngine.chat.callExperimentalAPI('isFeatureEnabledForStat', Math.pow(2, 42)); }) .catch((error) => { Toast({ message: TUITranslateService.t('TUIChat.登录失败'), type: TOAST_TYPE.ERROR, duration: 30000, }); Log.l(error); }) } public async init(SDKAppID:number, userID:string, userSig:string) { Log.l(`TUICustomerServer.init vue:${vueVersion} version:${version} SDKAppID:${SDKAppID} userID:${userID}` + ` isLoggedIn:${this.isLoggedIn} loggedInUserID:${this.loggedInUserID} currentCustomerServiceID:${this.currentCustomerServiceID}`); if (userID) { const ret = validateUserID(userID); if (ret > 0) { // Ensure i18n is configured first. setTimeout(() => { let reason = ''; if (ret === 1) { reason = TUITranslateService.t("AIDesk.userID 只能包含可打印 ASCII 字符"); } else if (ret === 2) { reason = TUITranslateService.t("AIDesk.userID 不能包含'administrator'"); } else if (ret === 3) { reason = TUITranslateService.t("AIDesk.userID 长度不能超过45字节"); } Toast({ message: reason, type: TOAST_TYPE.ERROR, duration: 30000, }); }, 500); return; } } if (this.isLoggedIn) { if (this.loggedInUserID === userID) { await this.switchConversation(`C2C${this.currentCustomerServiceID}`); return; } return this.unInit().finally(() => { this.isLoggedIn = false; this.loginCustomerUIKit(SDKAppID, userID, userSig); }); } else { return this.loginCustomerUIKit(SDKAppID, userID, userSig); } } public async initWithProfile(options: IInitWithProfile) { const { SDKAppID, userID, userSig, nickName, avatar, customerServiceID, scene } = options; Log.l(`TUICustomerServer.initWithProfile version:${version}`); if (nickName) { // chat 个人资料的昵称是 nick this.myProfile.nick = nickName; } else { this.myProfile.nick = ''; } if (avatar) { this.myProfile.avatar = avatar; } else { this.myProfile.avatar = USER_DEFAULT_AVATAR; } if (customerServiceID) { this.currentCustomerServiceID = customerServiceID; if (!this.customerServiceIDList.includes(this.currentCustomerServiceID)) { this.customerServiceIDList.push(this.currentCustomerServiceID); } } if (scene) { this._scene = scene; } else { if (vueVersion === 2) { this._scene = 'aidesk-customer-uni-vue2'; } else if (vueVersion === 3) { this._scene = 'aidesk-customer-uni-vue3'; } } return this.init(SDKAppID, userID, userSig); } public async unInit() { Log.l(`TUICustomerServer.unInit`); TUIStore.unwatch(StoreName.CUSTOM, { 'activeConversation': this.bindOnActionConversation, }); this.isLoggedIn = false; // 清理预加载缓存 let preloadedEmojiMap = state.get('preloadedEmojiMap'); if (preloadedEmojiMap) { preloadedEmojiMap.clear(); } return TUIChatEngine.logout(); } public sendTextMessage(options: SendMessageParams, sendMessageOptions?: SendMessageOptions) { return TUIChatService.sendTextMessage(options, sendMessageOptions); } public sendCustomMessage(options: SendMessageParams, sendMessageOptions?: SendMessageOptions) { return TUIChatService.sendCustomMessage(options, sendMessageOptions); }; public changeLanguage(language: string) { return TUITranslateService.changeLanguage(language).then(() => { Log.i(`language changed to ${language}`); }); } public getLoggedInUserID() { return this.loggedInUserID; } // Determine if the current session is a customer service session public isCustomerConversation(conversationID: string) { const userID = (conversationID && conversationID.slice(3)) || ''; return this.customerServiceIDList.indexOf(userID) > -1; } // Determine if the current message is a customer service message public isCustomerServicePluginMessage(message: IMessageModel) { if (!message || !this.isCustomerConversation(message.conversationID)) { return false; } if (isThinkingMessage(message)) { return false; } return isCustomerServiceMessage(message) || isMessageInvisible(message); } public onGetExtension(extensionID: string) { if (extensionID === TUIConstants.TUIContact.EXTENSION.CONTACT_LIST.EXT_ID) { return [ { weight: 0, icon: '', text: '智能客服', data: { name: 'customer', accountList: this.customerServiceIDList, }, }, ]; } } /** * Set up multiple customer service ID * @param list */ public setCustomerServiceIDList(list: Array<string>) { if (!Array.isArray(list) || list.length === 0) { return; } this.customerServiceIDList = list; this.currentCustomerServiceID = list[0]; Log.i(`TUICustomerServer.setCustomerServiceIDList`, this.customerServiceIDList); } public transferToTaskFlow(options: ITransferToTaskFlowModel) { transferToTaskFlow(this.currentCustomerServiceID, options.taskFlowID, options.description); } public transferToHuman(options: ITransferToHumanModel) { transferToHuman(this.currentCustomerServiceID, options.groupID, options.specificMemberList, options.description); } /** * Clear conversation unread count * @param conversationID */ public clearConversationUnreadCount(conversationID?: string) { Log.l(`TUICustomerServer.clearConversationUnreadCount conversationID:${conversationID}`); if (conversationID) { TUIConversationService.setMessageRead(conversationID); } else { TUIConversationService.setMessageRead('C2C@customer_service_account'); } } private onActiveConversation(params: any) { if (!params) { return; } Log.l(`TUICustomerServer.onActiveConversation options:`, params); if (this.isCustomerConversation(params.conversationID)) { // 如果有资料,确保资料更新完成(或失败)后再激活会话服务流 if (Object.keys(this.myProfile).length > 0) { Log.l(`TUICustomerServer.onActiveConversation updateMyProfile:${JSON.stringify(this.myProfile)}`); TUIUserService.updateMyProfile({...this.myProfile}).finally(() => { this.activeServiceFlow(params); }); } else { this.activeServiceFlow(params); } } } private async switchConversation(conversationID: string) { const ret = await TUIConversationService.switchConversation(conversationID); // -100002 即要切换的会话 ID 跟当前已打开的会话 ID 相同,这个时候我们重发 src 7,确保服务流状态正确 if (ret.code === -100002) { this.activeServiceFlow(this.paramsForActiveAgain); } } // 激活会话服务流 private activeServiceFlow(params: any) { Log.l(`TUICustomerServer.activeServiceFlow params:`, params); this.paramsForActiveAgain = { ...params }; TUIChatService.sendCustomMessage({ to: params.conversationID.slice(3), conversationType: TUIChatEngine.TYPES.CONV_C2C, payload: { data: JSON.stringify({ src: '7', customerServicePlugin: 0, triggeredContent: typeof params.robotLang === 'undefined' ? undefined : { language: params.robotLang } }), }, }, { onlineUserOnly: true }); Log.w(`TUICustomerServer.activeServiceFlow src 7 sent`); } }