salesforce/canvas/views/main.ejs (204 lines of code) (raw):

<html> <head> <link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link href="https://fonts.googleapis.com/css2?family=Open+Sans&display=swap" rel="stylesheet" /> <link href="https://fonts.googleapis.com/css?family=Product+Sans" rel="stylesheet" /> <% if (debug === 'true') { %> <script> window._uiModuleFlags = { debug: true }; </script> <% } %> <script src="../../../third_party/salesforce/canvas/javascripts/canvas-all.js"></script> <!-- WebComponents polyfill. Needed for rendering web components in older browsers. --> <script src="https://www.gstatic.com/external_hosted/document_register_element/document-register-element.js"></script> <script src="https://www.gstatic.com/agent-assist-ui-modules/container.js"></script> <script src="https://www.gstatic.com/agent-assist-ui-modules/transcript.js"></script> <style> html, body { margin: 0; padding: 0; } body { background-color: #fff; font-family: 'Open Sans', sans-serif; } .header-bar > h2 { color: #5f6368; display: flex; align-items: center; font-family: 'Product Sans', Arial, sans-serif; font-size: 22px; font-weight: 300; line-height: 24px; margin-top: 16px; padding-left: 8px; position: relative; top: -1.5px; vertical-align: middle; } .header-bar > h2 > img { margin-top: 2px; margin-right: 8px; } .app-container { display: flex; gap: 60px; justify-content: space-between; } .messages-container, .ui-modules-container { flex: 1; height: 80vh; } .proxy-number { color: #222; } .header-bar { display: flex; align-items: center; justify-content: space-between; } </style> </head> <body> <div class="header-bar"> <h2> <img src="https://www.gstatic.com/images/branding/googlelogo/svg/googlelogo_clr_74x24px.svg" /> Contact Center AI </h2> <div class="status-container"></div> </div> <div class="app-container"> <div class="messages-container"> <!-- The UI module that renders the conversation transcript. --> <agent-assist-transcript></agent-assist-transcript> </div> <div class="ui-modules-container"></div> </div> <script> var UI_MODULES_EL_SELECTOR = 'agent-assist-ui-modules'; var proxyServerEndpoint = '<%= proxyServer %>'; var conversationName = '<%= conversationName %>'; var conversationProfile = '<%= conversationProfile %>'; var features = '<%= features %>'; var salesforceContext = JSON.parse( '<%- JSON.stringify(salesforceContext) %>' ); // Dialogflow-specific authentication token. var authToken; window.addEventListener('load', function () { // Exchanges the agent's Salesforce OAuth token for one that can be used to call the // Dialogflow API. registerAuthToken('<%= salesforceToken %>').then(function ( dialogflowToken ) { authToken = dialogflowToken; // Set the active conversation once the API connection is established. addAgentAssistEventListener('api-connector-initialized', function () { dispatchAgentAssistEvent('active-conversation-selected', { detail: { conversationName: conversationName }, }); }); // Logs the customer and agent participant details to the console for testing purposes. addAgentAssistEventListener( 'conversation-initialized', function (event) { if (event.detail.participants) { console.log(`Customer participant: ${event.detail.participants.END_USER}`); console.log(`Agent participant: ${event.detail.participants.HUMAN_AGENT}`); } } ); // Initializes the core UI modules. initializeSuggestionModules(); // After an hour, refresh to avoid token expiration. // Note: Default token expiration is 2 hours, but can be changed by the // Salesforce Canvas application management settings setTimeout(refreshAuthToken, 3600 * 1000); }); }); /** * Exchanges the agent's Salesforce OAuth token for one that can be used to call the * Dialogflow API. **/ function registerAuthToken(salesforceToken) { return fetch(proxyServerEndpoint + '/register', { method: 'POST', headers: [['Authorization', salesforceToken]], }) .then(function (res) { return res.json(); }) .then(function (body) { return body.token; }); } /** * Refreshes the agent's Salesforce auth token, and exchanges it for a new Dialogflow-specific * auth token. **/ function refreshAuthToken() { Sfdc.canvas.client.refreshSignedRequest(function (data) { if (data.status === 200) { var signedRequest = data.payload.response; var part = signedRequest.split('.')[1]; var obj = JSON.parse(Sfdc.canvas.decode(part)); var salesforceToken = obj.client && obj.client.oauthToken; if (!salesforceToken) { console.error('No token present when refreshing signed request.'); return; } registerAuthToken(salesforceToken) .then(function (dialogflowToken) { authToken = dialogflowToken; var uiModulesEl = document.querySelector( UI_MODULES_EL_SELECTOR ); if (uiModulesEl) { uiModulesEl.setAttribute('auth-token', authToken); } }) .catch(function (err) { console.error('Could not register OAuth token.', err); }); } else { console.error('Could not refresh OAuth token.'); } }); } /** * Initializes the core UI modules that surface suggestions to the agent. */ function initializeSuggestionModules() { var uiModulesEl = document.createElement(UI_MODULES_EL_SELECTOR); var attributes = [ ['custom-api-endpoint', proxyServerEndpoint], ['notifier-server-endpoint', proxyServerEndpoint], ['event-based-library', 'SocketIo'], ['channel', 'voice'], ['agent-desktop', 'Custom'], ['features', features], ['conversation-profile', conversationProfile], ['auth-token', authToken], ['use-custom-conversation-id', 'true'], ]; for (var attribute of attributes) { uiModulesEl.setAttribute(attribute[0], attribute[1]); } document .querySelector('.ui-modules-container') .appendChild(uiModulesEl); } </script> </body> </html>