diff --git a/demos/demo-react-ts/package-lock.json b/demos/demo-react-ts/package-lock.json index 720ddee..ad828be 100644 --- a/demos/demo-react-ts/package-lock.json +++ b/demos/demo-react-ts/package-lock.json @@ -9,11 +9,12 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "@hubspot/calling-extensions-sdk": "^0.6.4-alpha.4", + "@hubspot/calling-extensions-sdk": "^0.6.4-alpha.9", "react": "^18.2.0", "react-aria": "^3.22.0", "react-dom": "^18.2.0", - "styled-components": "^5.3.6" + "styled-components": "^5.3.6", + "uuid": "^10.0.0" }, "devDependencies": { "@babel/core": "^7.20.12", @@ -1859,9 +1860,9 @@ } }, "node_modules/@hubspot/calling-extensions-sdk": { - "version": "0.6.4-alpha.4", - "resolved": "https://registry.npmjs.org/@hubspot/calling-extensions-sdk/-/calling-extensions-sdk-0.6.4-alpha.4.tgz", - "integrity": "sha512-kxSdmKPoKEh+JNEiWA4FHaef+4aoGeuI38ahSH/aetE8jUDsNX/eacEwFJrliihFoL+PNaoE70iHOgbJbmx+8Q==", + "version": "0.6.4-alpha.9", + "resolved": "https://registry.npmjs.org/@hubspot/calling-extensions-sdk/-/calling-extensions-sdk-0.6.4-alpha.9.tgz", + "integrity": "sha512-7ijBQn/CWOCS6LChTdVhpfPBnBJ8bu3Pz7KDU/kllGulszSST0Of1Darw3EnQaAuTE7GvvfjliEZm4xD+mNpTA==", "engines": { "node": ">=14" } @@ -3838,9 +3839,10 @@ } }, "node_modules/@types/ws": { - "version": "8.5.4", + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", + "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } @@ -6414,9 +6416,10 @@ } }, "node_modules/jasmine-browser-runner": { - "version": "1.3.0", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jasmine-browser-runner/-/jasmine-browser-runner-1.4.0.tgz", + "integrity": "sha512-UOwxL7/tL5K3Ww9LUw4EFWyZCQyTflzTgRFr80Bm/22EEUqlOiDhdqhYblu3LEZ+ZZ8qfwrlBShtcc+MAwNetg==", "dev": true, - "license": "MIT", "dependencies": { "ejs": "^3.1.6", "express": "^4.16.4", @@ -6527,6 +6530,16 @@ "node": ">=0.10.0" } }, + "node_modules/launch-editor": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", + "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, "node_modules/lie": { "version": "3.3.0", "dev": true, @@ -7804,6 +7817,15 @@ "node": ">=8" } }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/side-channel": { "version": "1.0.4", "dev": true, @@ -7832,6 +7854,15 @@ "websocket-driver": "^0.7.4" } }, + "node_modules/sockjs/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/source-map": { "version": "0.6.1", "dev": true, @@ -8307,9 +8338,13 @@ } }, "node_modules/uuid": { - "version": "8.3.2", - "dev": true, - "license": "MIT", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { "uuid": "dist/bin/uuid" } @@ -8465,9 +8500,10 @@ } }, "node_modules/webpack-dev-server": { - "version": "4.11.1", + "version": "4.15.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", + "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", "dev": true, - "license": "MIT", "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -8475,7 +8511,7 @@ "@types/serve-index": "^1.9.1", "@types/serve-static": "^1.13.10", "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.1", + "@types/ws": "^8.5.5", "ansi-html-community": "^0.0.8", "bonjour-service": "^1.0.11", "chokidar": "^3.5.3", @@ -8488,6 +8524,7 @@ "html-entities": "^2.3.2", "http-proxy-middleware": "^2.0.3", "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", "open": "^8.0.9", "p-retry": "^4.5.0", "rimraf": "^3.0.2", @@ -8496,8 +8533,8 @@ "serve-index": "^1.9.1", "sockjs": "^0.3.24", "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.4.2" + "webpack-dev-middleware": "^5.3.4", + "ws": "^8.13.0" }, "bin": { "webpack-dev-server": "bin/webpack-dev-server.js" @@ -8513,6 +8550,9 @@ "webpack": "^4.37.0 || ^5.0.0" }, "peerDependenciesMeta": { + "webpack": { + "optional": true + }, "webpack-cli": { "optional": true } @@ -9839,9 +9879,9 @@ } }, "@hubspot/calling-extensions-sdk": { - "version": "0.6.4-alpha.4", - "resolved": "https://registry.npmjs.org/@hubspot/calling-extensions-sdk/-/calling-extensions-sdk-0.6.4-alpha.4.tgz", - "integrity": "sha512-kxSdmKPoKEh+JNEiWA4FHaef+4aoGeuI38ahSH/aetE8jUDsNX/eacEwFJrliihFoL+PNaoE70iHOgbJbmx+8Q==" + "version": "0.6.4-alpha.9", + "resolved": "https://registry.npmjs.org/@hubspot/calling-extensions-sdk/-/calling-extensions-sdk-0.6.4-alpha.9.tgz", + "integrity": "sha512-7ijBQn/CWOCS6LChTdVhpfPBnBJ8bu3Pz7KDU/kllGulszSST0Of1Darw3EnQaAuTE7GvvfjliEZm4xD+mNpTA==" }, "@internationalized/date": { "version": "3.1.0", @@ -11208,7 +11248,9 @@ } }, "@types/ws": { - "version": "8.5.4", + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", + "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", "dev": true, "requires": { "@types/node": "*" @@ -12902,7 +12944,9 @@ } }, "jasmine-browser-runner": { - "version": "1.3.0", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jasmine-browser-runner/-/jasmine-browser-runner-1.4.0.tgz", + "integrity": "sha512-UOwxL7/tL5K3Ww9LUw4EFWyZCQyTflzTgRFr80Bm/22EEUqlOiDhdqhYblu3LEZ+ZZ8qfwrlBShtcc+MAwNetg==", "dev": true, "requires": { "ejs": "^3.1.6", @@ -12975,6 +13019,16 @@ "version": "6.0.3", "dev": true }, + "launch-editor": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", + "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", + "dev": true, + "requires": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, "lie": { "version": "3.3.0", "dev": true, @@ -13835,6 +13889,12 @@ "version": "3.0.0", "dev": true }, + "shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true + }, "side-channel": { "version": "1.0.4", "dev": true, @@ -13855,6 +13915,14 @@ "faye-websocket": "^0.11.3", "uuid": "^8.3.2", "websocket-driver": "^0.7.4" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + } } }, "source-map": { @@ -14159,8 +14227,9 @@ "dev": true }, "uuid": { - "version": "8.3.2", - "dev": true + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==" }, "vary": { "version": "1.1.2", @@ -14291,7 +14360,9 @@ } }, "webpack-dev-server": { - "version": "4.11.1", + "version": "4.15.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", + "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", "dev": true, "requires": { "@types/bonjour": "^3.5.9", @@ -14300,7 +14371,7 @@ "@types/serve-index": "^1.9.1", "@types/serve-static": "^1.13.10", "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.1", + "@types/ws": "^8.5.5", "ansi-html-community": "^0.0.8", "bonjour-service": "^1.0.11", "chokidar": "^3.5.3", @@ -14313,6 +14384,7 @@ "html-entities": "^2.3.2", "http-proxy-middleware": "^2.0.3", "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", "open": "^8.0.9", "p-retry": "^4.5.0", "rimraf": "^3.0.2", @@ -14321,8 +14393,8 @@ "serve-index": "^1.9.1", "sockjs": "^0.3.24", "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.4.2" + "webpack-dev-middleware": "^5.3.4", + "ws": "^8.13.0" }, "dependencies": { "ipaddr.js": { diff --git a/demos/demo-react-ts/package.json b/demos/demo-react-ts/package.json index 31515e2..f6bf98a 100644 --- a/demos/demo-react-ts/package.json +++ b/demos/demo-react-ts/package.json @@ -18,11 +18,12 @@ "node": ">=14" }, "dependencies": { - "@hubspot/calling-extensions-sdk": "^0.6.4-alpha.4", + "@hubspot/calling-extensions-sdk": "^0.6.4-alpha.9", "react": "^18.2.0", "react-aria": "^3.22.0", "react-dom": "^18.2.0", - "styled-components": "^5.3.6" + "styled-components": "^5.3.6", + "uuid": "^10.0.0" }, "devDependencies": { "@babel/core": "^7.20.12", diff --git a/demos/demo-react-ts/src/hooks/useCti.ts b/demos/demo-react-ts/src/hooks/useCti.ts index 5bf6b22..9ba2b98 100644 --- a/demos/demo-react-ts/src/hooks/useCti.ts +++ b/demos/demo-react-ts/src/hooks/useCti.ts @@ -1,31 +1,22 @@ /* eslint-disable import/no-relative-packages */ import { useMemo, useState } from "react"; -// import CallingExtensions from "@hubspot/calling-extensions-sdk/src/CallingExtensions"; -// import { callStatus } from "@hubspot/calling-extensions-sdk/src/Constants"; - -// @ts-expect-error module not typed -import CallingExtensions from "../../../../src/CallingExtensions"; - -// @TODO Move it to CallingExtensions and export it once migrated to typescript -type ObjectCoordinates = { - portalId: number; - objectTypeId: string; - objectId: number; -}; - -export type ContactIdMatch = { - callerIdType: "CONTACT"; - objectCoordinates: ObjectCoordinates; - firstName: string; - lastName: string; - email: string; -}; - -export type CompanyIdMatch = { - callerIdType: "COMPANY"; - objectCoordinates: ObjectCoordinates; - name: string; -}; +import { v4 as uuidv4 } from "uuid"; +import CallingExtensions, { + CompanyIdMatch, + ContactIdMatch, + OnCallAnswered, + OnCallCompleted, + OnCallEnded, + OnError, + OnIncomingCall, + OnInitialized, + OnMessage, + OnNavigateToRecord, + OnOutgoingCall, + OnPublishToChannel, + OnResize, + Options, +} from "@hubspot/calling-extensions-sdk"; const INCOMING_NUMBER_KEY = "LocalSettings:Calling:DemoReact:incomingNumber"; const INCOMING_CONTACT_NAME_KEY = @@ -33,27 +24,22 @@ const INCOMING_CONTACT_NAME_KEY = // @TODO Move it to CallingExtensions and export it once migrated to typescript interface CallingExtensionsContract { - initialized: (userData: unknown) => void; + initialized: (userData: OnInitialized) => void; userAvailable: () => void; userUnavailable: () => void; userLoggedIn: () => void; userLoggedOut: () => void; - incomingCall: (callDetails: { fromNumber: string }) => void; - outgoingCall: (callDetails: unknown) => void; - callAnswered: () => void; + incomingCall: (callDetails: OnIncomingCall) => void; + outgoingCall: (callDetails: OnOutgoingCall) => void; + callAnswered: (payload: OnCallAnswered) => void; callData: (data: unknown) => void; - callEnded: (engagementData: unknown) => void; - callCompleted: (callCompletedData: unknown) => void; - sendError: (errorData: unknown) => void; - resizeWidget: (sizeInfo: unknown) => void; - sendMessage: (message: unknown) => void; + callEnded: (engagementData: OnCallEnded) => void; + callCompleted: (callCompletedData: OnCallCompleted) => void; + sendError: (errorData: OnError) => void; + resizeWidget: (sizeInfo: OnResize) => void; + sendMessage: (message: OnMessage) => void; logDebugMessage: (messageData: unknown) => void; -} - -// @TODO Move it to CallingExtensions and export it once migrated to typescript -interface CallingExtensionsOptions { - debugMode: boolean; - eventHandlers: unknown; + publishToChannel: (data: OnPublishToChannel) => void; } // @TODO Move it to CallingExtensions and export it once migrated to typescript @@ -62,10 +48,20 @@ class CallingExtensionsWrapper implements CallingExtensionsContract { private _incomingNumber = ""; - constructor(options: CallingExtensionsOptions) { + private _externalCallId = ""; + + constructor(options: Options) { this._cti = new CallingExtensions(options); } + get externalCallId() { + return this._externalCallId; + } + + set externalCallId(id: string) { + this._externalCallId = id; + } + get incomingNumber() { return this._incomingNumber; } @@ -74,7 +70,7 @@ class CallingExtensionsWrapper implements CallingExtensionsContract { this._incomingNumber = number; } - initialized(userData: unknown) { + initialized(userData: OnInitialized) { return this._cti.initialized(userData); } @@ -94,48 +90,70 @@ class CallingExtensionsWrapper implements CallingExtensionsContract { return this._cti.userLoggedOut(); } - incomingCall(callDetails: { fromNumber: string }) { - this._incomingNumber = callDetails.fromNumber; - return this._cti.incomingCall(callDetails); + incomingCall(callDetails: OnIncomingCall) { + this.incomingNumber = callDetails.fromNumber; + this.externalCallId = uuidv4(); + return this._cti.incomingCall({ + ...callDetails, + externalCallId: this.externalCallId, + }); } - outgoingCall(callDetails: unknown) { - return this._cti.outgoingCall(callDetails); + outgoingCall(callDetails: OnOutgoingCall) { + this.externalCallId = uuidv4(); + return this._cti.outgoingCall({ + ...callDetails, + externalCallId: this.externalCallId, + }); } - navigateToRecord(data: { objectCoordinates: ObjectCoordinates }) { + navigateToRecord(data: OnNavigateToRecord) { return this._cti.navigateToRecord(data); } - callAnswered() { - return this._cti.callAnswered(); + callAnswered(data: OnCallAnswered) { + return this._cti.callAnswered({ + ...data, + externalCallId: this.externalCallId, + }); } callData(data: unknown) { return this._cti.callData(data); } - callEnded(engagementData: unknown) { - return this._cti.callEnded(engagementData); + callEnded(engagementData: OnCallEnded) { + return this._cti.callEnded({ + ...engagementData, + externalCallId: this.externalCallId, + }); + } + + callCompleted(callCompletedData: OnCallCompleted) { + this._cti.callCompleted({ + ...callCompletedData, + externalCallId: this.externalCallId, + }); + this.externalCallId = ""; } - callCompleted(callCompletedData: unknown) { - return this._cti.callCompleted(callCompletedData); + publishToChannel(data: OnPublishToChannel) { + return this._cti.publishToChannel(data); } - sendError(errorData: unknown) { + sendError(errorData: OnError) { return this._cti.sendError(errorData); } - resizeWidget(sizeInfo: unknown) { + resizeWidget(sizeInfo: OnResize) { return this._cti.resizeWidget(sizeInfo); } - sendMessage(message: unknown) { + sendMessage(message: OnMessage) { return this._cti.sendMessage(message); } - logDebugMessage(messageData: unknown) { + logDebugMessage(messageData: any) { return this._cti.logDebugMessage(messageData); } } @@ -147,7 +165,6 @@ export const useCti = ( const [engagementId, setEngagementId] = useState(null); const [incomingContactName, setIncomingContactName] = useState(""); const cti = useMemo(() => { - const defaultSize = { width: 400, height: 600 }; return new CallingExtensionsWrapper({ debugMode: true, eventHandlers: { @@ -161,7 +178,6 @@ export const useCti = ( cti.initialized({ isLoggedIn: true, - sizeInfo: defaultSize, engagementId, }); const incomingNumber = @@ -227,9 +243,9 @@ export const useCti = ( cti.incomingNumber ); window.localStorage.setItem(INCOMING_CONTACT_NAME_KEY, name); - cti.navigateToRecord({ - objectCoordinates: firstCallerIdMatch.objectCoordinates, - }); + // cti.navigateToRecord({ + // objectCoordinates: firstCallerIdMatch.objectCoordinates, + // }); return; } cti.logDebugMessage({ @@ -252,6 +268,18 @@ export const useCti = ( onPublishToChannelSucceeded: (data: any, _rawEvent: any) => { /** HubSpot successfully published the call to the connected channel. */ }, + onSetCallState: (data: any, _rawEvent: any) => { + /** HubSpot successfully published the call to the connected channel. */ + }, + onEndCall: (data: any, _rawEvent: any) => { + /** HubSpot successfully ended the call. */ + }, + onInitiateCallIdSucceeded: (data: any, _rawEvent: any) => { + /** HubSpot successfully initiated the call. */ + }, + onInitiateCallIdFailed: (data: any, _rawEvent: any) => { + /** HubSpot was unable to initiate call. */ + }, }, }); }, []);