This article walks through how to configure SendSafely Halo to work with the Salesforce Agentforce Chat Widget. This example prompts the user to upload files for certain workflows and launches the upload dialog as needed. The example uses the Agentforce Widget client-side functionality to update the conversation after the user submits files. No Dropzone Connector is needed for this example.
Defining the Trigger in Agentforce
Before configuring Halo, you'll need to train your agent to know when to request files using Halo and how to acknowledge that files have been uploaded.
Requesting Files
First, you will train the agent to use a specific phrase when an file is requested. Responses that contain only this phrase will cause the Halo upload button to render on the page running the Agentforce widget. To do this, you can create a new topic within the Agentforce Builder. An example topic is shown on the screenshot below.
The example above instructs the agent to ask the user if they would like to upload screenshots when they report a problem or issue (before handing off to a human). When the user confirms they have screenshots, the agent responds with the phrase "Please use the paperclip icon below to upload your files". In the next step, we will add Javascript to the page that runs the Agentforce chat widget so that it activates Halo when the agent responds with this phrase.
Acknowledging File Uploads
Next, you'll need to train the agent how to recognize that the user has uploaded files using SendSafely. Uploads will be recognized any time the end-user posts a hyperlink that contains a SendSafely package link. Halo will do this automatically on behalf of the user after files are submitted. For this you can create another topic in the Agentforce Builder and provide instructions to the bot for how to respond.
The above example, once the user submits files the bot acknowledges the upload and escalates the conversation to a human. The exact behavior you choose to implement can vary, but we always recommend at least acknowledging the upload with a confirmation message from the agent.
Once the user is transferred to a live agent or you decide to create a Salesforce Case based on the chat transcript, the human agents will be able to view the files that the end user uploaded using the SendSafely Agent App for Salesforce (or by clicking the secure link and accessing the files from the SendSafely portal).
Installing and Initializing the Halo Javascript
The Halo Javascript should be included on every page that runs the Agentforce widget where you expect uploads to be requested from.
<script src="https://files.sendsafely.com/js/SendSafelyDropzoneModal.js" type="module"></script>Once the Javascript is included on the page, you'll need to define a function that initializes the Halo modal (SendSafelyDropzoneModal). This function includes onUploadComplete callback logic to post the SendSafely Secure Link to the chat window after the user submits their files. We also include logic in the onCancel callback to handle cases where the user presses "Cancel" or closes the modal without submitting files, along with utility functions to show/hide the upload button as needed.
//Initialize upload widget
let myUploadWidget = null;
function createBasicUploadWidget() {
return new SendSafelyDropzoneModal({
dropzoneId: 'put-your-dropzone-id-here',
url: 'https://app.sendsafely.com',
uploadButtonText: " ", // no text
uploadButtonIcon: "data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='20'%20height='20'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M21.44%2011.05l-9.19%209.19a6%206%200%200%201-8.49-8.49l9.19-9.19a4%204%200%200%201%205.66%205.66l-9.2%209.19a2%202%200%200%201-2.83-2.83l8.49-8.48'/%3E%3C/svg%3E",
uploadButtonStyle: {
position: "fixed",
bottom: "20px",
right: "42px",
width: "39px",
height: "39px",
padding: "0",
maxWidth: "48px",
background: "#000000",
border: "none",
display: "flex",
justifyContent: "center",
alignItems: "center",
gap: "0px !important",
cursor: "pointer",
boxShadow: "rgba(0, 0, 0, 0.25) 0px 8px 24px",
zIndex: "2147483647"
},
cancelButtonStyle: { display: 'none' },
submitButtonStyle: {
backgroundColor: "#000000",
color: "#fff",
padding: "10px 18px",
borderRadius: "3px"
},
onCancel: () => console.log('SendSafely Modal closed'),
onUploadComplete: (secureUrl) => {
postToChat(secureUrl);
hideUploadButton();
},
onUploadError: (type, message) => {
alert("[SendSafely] Upload error:", type, message);
}
});
}
function showUploadButton() {
if (!myUploadWidget) myUploadWidget = createBasicUploadWidget();
myUploadWidget.showUploadButton();
}
function hideUploadButton() {
myUploadWidget.hideUploadButton();
}Next, you define a function on the page that uses Salesforce Enhanced Web Chat to post the "Secure Link" to the chat as shown below:
function postToChat(text) {
try {
const sendFn = window.embeddedservice_bootstrap?.utilAPI?.sendTextMessage;
if (typeof sendFn === "function") {
sendFn(`<a href='${text}'> Upload Succeeded </a>`);
} else {
console.warn("[Salesforce] utilAPI.sendTextMessage not available yet.");
}
} catch (e) {
console.error("[Salesforce] Failed to send chat message:", e);
}
}Finally, you will define an event listener that looks for the phrase from your agent indicating that an upload is being requested. When this happens, an upload button will be rendered in the Salesforce chat widget. Our example used the phrase "Please use the paperclip icon below to upload your files". If you trained the agent to respond with something else you will need to change the "message" string in the code example below.
When invoked, our example renders a black paperclip button that gets pinned to the right side of the chat input box. You can change the appearance and position of this button by changing the uploadButtonText, uploadButtonIcon and uploadButtonStyle properties when initializing the Halo modal.
window.addEventListener("onEmbeddedMessageSent", (e) => {
//when received a specific message from the bot show the upload button
var jsonMessagePayload = JSON.parse(e.detail.conversationEntry.entryPayload);
var message = jsonMessagePayload.abstractMessage.staticContent.text;
if (message === "Please use the paperclip icon below to upload your files.") {
showUploadButton();
}
})Using the Halo modal
Now that the appropriate code has been added to the page, you are ready to invoke and test the Halo modal. As shown below, the topic we defined in step one prompts the user if they want to attach files.
When the user responds with "yes" the bot responds with "Please use the paperclip icon below to upload your files" which triggers the paperclip button to render.
When you press the paperclip button, the SendSafely Halo modal will appear and allow you to attach one or more files.
Once the files are attached and you press the submit button, the SendSafely Secure Link is automatically posted to the chat session and the bot should acknowledge the upload.
Complete Example Code
The full HTML from the example above is included below for reference. You will need to update the example to use a valid SendSafely Dropzone ID and your own Salesforce Agentforce Config.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
.sendsafely-modal-overlay {
z-index: 1000001 !important;
}
.sendsafely-upload-btn {
gap: 0px !important;
border-radius: 0 6px 6px 0 !important;
}
</style>
<script src="https://files.sendsafely.com/js/SendSafelyDropzoneModal.js" type="module"></script>
</head>
<body>
<script>
function postToChat(text) {
try {
const sendFn = window.embeddedservice_bootstrap?.utilAPI?.sendTextMessage;
if (typeof sendFn === "function") {
sendFn(`<a href='${text}'> Upload Succeeded </a>`);
} else {
console.warn("[Salesforce] utilAPI.sendTextMessage not available yet.");
}
} catch (e) {
console.error("[Salesforce] Failed to send chat message:", e);
}
}
let myUploadWidget = null;
function createBasicUploadWidget() {
return new SendSafelyDropzoneModal({
dropzoneId: 'put-your-dropzone-id-here',
url: 'https://app.sendsafely.com',
showSubmissionConfirmation: false,
showSubmissionId: false,
invokeDropzoneConnectors: true,
packageLabel: 'salesforce-messaging',
submitterEmail: "",
uploadButtonText: " ", // no text
uploadButtonIcon: "data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='20'%20height='20'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='white'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M21.44%2011.05l-9.19%209.19a6%206%200%200%201-8.49-8.49l9.19-9.19a4%204%200%200%201%205.66%205.66l-9.2%209.19a2%202%200%200%201-2.83-2.83l8.49-8.48'/%3E%3C/svg%3E",
uploadButtonStyle: {
position: "fixed",
bottom: "20px",
right: "42px",
width: "39px",
height: "39px",
padding: "0",
maxWidth: "48px",
background: "#000000",
border: "none",
display: "flex",
justifyContent: "center",
alignItems: "center",
gap: "0px !important",
cursor: "pointer",
boxShadow: "rgba(0, 0, 0, 0.25) 0px 8px 24px",
zIndex: "2147483647"
},
cancelButtonStyle: { display: 'none' },
submitButtonStyle: {
backgroundColor: "#000000",
color: "#fff",
padding: "10px 18px",
borderRadius: "3px"
},
onCancel: () => console.log('[SendSafely] Modal closed'),
onUploadComplete: (secureUrl) => {
//post the link to the chat
postToChat(secureUrl);
hideUploadButton();
},
onUploadError: (type, message) => {
alert("[SendSafely] Upload error:", type, message);
}
});
}
function showUploadButton() {
if (!myUploadWidget) myUploadWidget = createBasicUploadWidget();
myUploadWidget.showUploadButton();
}
function hideUploadButton() {
myUploadWidget.hideUploadButton();
}
function initEmbeddedMessaging() {
try {
embeddedservice_bootstrap.settings.language = 'en_US';
embeddedservice_bootstrap.init(
//salesforce chatbot config
);
} catch (err) {
console.error('Error loading Embedded Messaging: ', err);
}
}
window.addEventListener("onEmbeddedMessageSent", (e) => {
var jsonMessagePayload = JSON.parse(e.detail.conversationEntry.entryPayload);
var message = jsonMessagePayload.abstractMessage.staticContent.text;
if (message === "Please use the paperclip icon below to upload your files.") {
showUploadButton();
}
})
</script>
<script type='text/javascript'
src="salesforce-chatbot-script-url"
onload="initEmbeddedMessaging()">
</script>
</body>
</html>
Comments
0 comments
Please sign in to leave a comment.