/** * Copyright (c) Cisco Systems, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ import { LitElement, html, property, PropertyValues, internalProperty } from "lit-element"; import { bindMeetingEvents, joinMeeting } from "./meeting"; import { nothing } from "lit-html"; import { customElementWithCheck } from "@/mixins"; import "../timer/Timer"; import styles from "./scss/module.scss"; const AGENT_STOCK = "https://cjaas.cisco.com/assets/img/agent-stock.jpg"; export namespace WebexWalkin { @customElementWithCheck("cjaas-webex-walkin") export class ELEMENT extends LitElement { @property({ attribute: "welcome-message" }) welcomeMessage = `Hey there! Maybe I can help you today, let's meet over video!`; @property({ attribute: "access-token" }) accessToken: string | null = null; @property({ attribute: "brand-name" }) brandName: string | null = null; @property({ attribute: "agent-id" }) agentId: string | null = null; @internalProperty() fullScreen = false; @internalProperty() webex: any; @internalProperty() isWebexMeetingConnected = false; @internalProperty() isAuthDenied = false; @internalProperty() showMeetingControls = false; @internalProperty() profile: any | null = null; @internalProperty() isAudioOnly = false; connectedCallback() { super.connectedCallback(); } disconnectedCallback() { super.disconnectedCallback(); } updated(changedProperties: PropertyValues) { super.updated(changedProperties); if (changedProperties.has("accessToken")) { const intervalForInit = setInterval(() => { if (window.Webex) { clearInterval(intervalForInit); this.initiateMeeting(); } }, 500); } } getSpinner() { return html`
${this.isAuthDenied ? html` Unable to connect to server ` : html` `}
`; } getWelcomeScreen() { return html`
${this.welcomeMessage}
${this.getControls()}
`; } setProfile() { return new Promise((resolve, reject) => { if (!this.agentId) { console.error("No Agent Id found"); reject(); return; } this.getProfileFromEmail(this.agentId).then( (x: { items: Array }) => { if (x?.items?.length > 0) { const profile = x.items[0]; this.profile = profile; resolve(true); } else { this.profile = { nickName: "Agent", // SIP morphed as email emails: [this.agentId] }; resolve(false); } }, (err: unknown) => reject(err) ); }); } getProfileFromEmail(email: string) { return this.webex.people.list({ email }); } resizeModal() { this.fullScreen = !this.fullScreen; const event = new CustomEvent("resize-popup", { detail: { fullScreen: this.fullScreen } }); this.requestUpdate(); this.dispatchEvent(event); } getMeetingInterface() { return html`
Calling ${this.profile?.nickName}
${this.isAudioOnly ? nothing : html` `}
{ this.resizeModal(); }} >
`; } getControls() { return html` this.callAgent()} size="44" > this.callAgent(true)} > this.dispatchCloseEvent()} > `; } callAgent(isAudioOnly = false) { this.showMeetingControls = true; this.isAudioOnly = isAudioOnly; this.requestUpdate(); this.webex.meetings.create(this.profile?.emails[0]).then((meeting: any) => { bindMeetingEvents( meeting, this.shadowRoot, () => this.requestUpdate(), () => this.dispatchCloseEvent(), this.isAudioOnly ); joinMeeting(meeting, this.isAudioOnly); this.dispatchEvent( new CustomEvent("Calling Agent", { bubbles: true }) ); // error handling // video mute buttons enabled }); } async initiateMeeting() { if (!this.accessToken || !window.Webex) { return; } this.webex = window.Webex.init(); this.webex.once("ready", () => { this.webex.authorization.requestAccessTokenFromJwt({ jwt: this.accessToken }).then( () => { Promise.all([this.setProfile(), this.webex.meetings.register()]) // error handling .then( (result: [unknown, {}]) => { this.isWebexMeetingConnected = true; this.requestUpdate(); if (result && result[0]) { const customEvent = new CustomEvent("Connected To Webex"); this.shadowRoot?.host.dispatchEvent(customEvent); } }, (err: Error) => { console.log(err); } ); }, () => { // error handling // bubble error event this.isAuthDenied = true; this.requestUpdate(); } ); }); } dispatchCloseEvent() { const event = new CustomEvent("Meeting Closed"); this.shadowRoot?.host.dispatchEvent(event); } static get styles() { return styles; } render() { return html`
Webex Walk In
${this.isWebexMeetingConnected ? this.showMeetingControls ? this.getMeetingInterface() : this.getWelcomeScreen() : this.getSpinner()}
`; } } } declare global { interface HTMLElementTagNameMap { "cjaas-webex-walkin": WebexWalkin.ELEMENT; } }