Embedded UCP¶
In this document you can find the step-by-step explanation of how you can load a embedded version of UCP from your website.
The powerful iframe HTML tag!¶
The most easily way to load UCP from your site is by using an iframe HTML tag. Lets go to the explanation of how to use this powerful HTML tag in your site to load the application.
Lets use the following vocabulary to talk about your website and UCP - webParent: The URL of the website that you want to load UCP from - webUCP: The URL of UCP website (Ex: https://qvoice.ca/ucp/login) The URL of UCP FULLSCREEN website (Ex: https://qvoice.ca/ucp/login?fullscreen=true)
Insert the iframe HTML tag in your website (webParent)¶
In the HTML document of your website (webParent) or inside your component if you are working with React you should insert the following:
<iframe title='ucp' src='{webUCP}' allow='notifications; microphone'
/>
Lets talk about the attributes of the iframe
- title: This is the title of your iframe, we suggest to use ucp to easily recognize it
- src: This is the source of the content of the iframe, in other terms it is the URL of the website that you want to load, in this case we are talking about webUCP (URL of UCP website)
Important: Always use the URL of UCP with the /login path at the end, otherwise the content of UCP will not be loaded successfully
Incorrect usage: https://qvoice.ca/ucp
Correct usage: https://qvoice.ca/ucp/login
- allow: This is a list of permissions splited by ; that you grant to the embedded website. UCP uses two of them, notifications in order to have the ability to push notifications and microphone in order to access the audio input that will be used during your calls
Important: If you do not want to grant these two permissions to UCP you should take into account that incoming and outgoing calls are not going to work
Finally you should see UCP embedded inside your website, for sure you can customise the styles of the iframe.
Important: We strongly suggest to use a minimum size of 300 pixels x 300 pixels in order to give the UI enough space to normally display the elements
Enjoy Embedded UCP in your website!
Receiving messages in parent window from Embedded UCP¶
Embedded UCP sends call events to the parent window so you can subscribe to these events by opening a listener in the parent window.
Below you can find the examples of the events:
On Set Disposition:
{
"type": "UCP_DISPOSITION",
"payload": {
"call_id": "8a9e7f1e-af22-4257-84d2-043e56dc0d1e",
"disposition": "interested in product"
}
}
On Set Agent State:
{
"type": "UCP_AGENT_STATE",
"payload": {
"state": "2dc22f830e444cf885e5724a804f51e9" // agent state id
}
}
{
"type": "UCP_INCOMING_CALL",
"payload": {
"call_id": "8a9e7f1e-af22-4257-84d2-043e56dc0d1e",
"caller_id_name": "John Doe",
"caller_id_number": "1234567890",
"queue_id": "1234567890",
"queue_name": "Test Queue",
"campaign_name": "Test Campaign",
"lead_id": "1234567890",
"user_id": "1234567890",
"user_ext": "1000"
}
},
{
"type": "UCP_ANSWERED_CALL",
"payload": {
"call_id": "8a9e7f1e-af22-4257-84d2-043e56dc0d1e",
"caller_id_name": "John Doe",
"caller_id_number": "1234567890",
"queue_id": "1234567890",
"queue_name": "Test Queue",
"campaign_name": "Test Campaign",
"lead_id": "1234567890",
"user_id": "1234567890",
"user_ext": "1000"
}
},
{
"type": "UCP_HANGUP_CALL",
"payload": {
"call_id": "8a9e7f1e-af22-4257-84d2-043e56dc0d1e",
"user_id": "1234567890",
"user_ext": "1000",
"initiated_by": "agent",
"interaction_id": "63947898542-5ee8b08f",
"customer_call_id": "1-25426@142.93.151.168"
}
},
{
"type": "UCP_OUTGOING_CALL",
"payload": {
"call_id": "8a9e7f1e-af22-4257-84d2-043e56dc0d1e",
"callee_id_number": "1237",
"user_id": "1234567890",
"user_ext": "1000"
}
}
The UCP_HANGUP_CALL event in detail¶
The UCP_HANGUP_CALL event is emitted when a call ends. It now fires whichever party ends the call — when the agent hangs up and when the customer / remote party hangs up. Earlier versions only emitted it on agent hang-up.
Important:
UCP_HANGUP_CALLfires for calls that reach the agent's softphone. Calls that abandon in the IVR or queue before reaching an agent do not produce a UCP event — use your CDR data to account for those.
The payload includes the following fields:
| Field | Always present | Description |
|---|---|---|
call_id |
yes | Call-ID of the agent leg (the same call_id you received on UCP_INCOMING_CALL / UCP_ANSWERED_CALL). |
user_id |
yes | Id of the agent. |
user_ext |
yes | Extension of the agent. |
initiated_by |
yes | Which party ended the call: "agent" (the agent pressed hang-up / cancelled) or "customer" (the remote party ended the call, i.e. the agent did not). |
interaction_id |
yes (may be empty) | Stable identifier of the logical call, useful to correlate this event with the CDR and other data sources. Returned as an empty string "" when it is not available (see note below). |
customer_call_id |
yes (may be empty) | Call-ID of the external / customer leg. Returned as an empty string "" for calls that are not queue calls (where there is no separate customer leg in scope). |
Note:
initiated_byis always populated ("agent"or"customer") because it is determined by UCP itself.interaction_idis provided by the telephony platform; on older platform versions, or before the identifier has propagated to the call, it is returned as an empty string. Wheninteraction_idis empty you can still correlate the call usingcustomer_call_id/call_id.Edge case — transferred / merged calls: in a 3-way / merged conference the agent leg only ends when the agent themselves hangs up, so that case is reported as
initiated_by: "agent".
- Receiving messages in parent window
window.addEventListener('message', function(event) { if (event.data.type === "UCP_INCOMING_CALL") { console.log('INCOMING CALL FROM UCP: ', event.data) } else if (event.data.type === "UCP_ANSWERED_CALL") { console.log('ANSWERED CALL FROM UCP: ', event.data) } else if (event.data.type === "UCP_HANGUP_CALL") { // event.data.payload.initiated_by is "agent" or "customer" console.log('HUNGUP CALL FROM UCP: ', event.data) } else if (event.data.type === "UCP_OUTGOING_CALL") { console.log('OUTGOING CALL FROM UCP: ', event.data) } }, false)
Sending messages from Parent window to Embedded UCP¶
The parent window can also send messages to the embedded UCP to trigger specific actions. This allows you to control UCP functionality directly from your website.
Making calls from Parent window¶
You can initiate calls from the parent window by sending a message to the embedded UCP iframe. Here's how to do it:
document.getElementById('ucp-iframe').contentWindow.postMessage({
type: 'MAKE_CALL',
payload: {
destination: '1234'
}
}, '*')
Important considerations:
-
iframe ID: Make sure your iframe has an
idattribute so you can reference it. For example:<iframe id="ucp-iframe" title='ucp' src='{webUCP}' allow='notifications; microphone' /> -
Message structure: The message must follow the specific format with
typeandpayloadproperties. -
Destination: The
destinationfield should contain the phone number you want to call. -
Origin parameter: The
'*'parameter allows the message to be sent to any origin. For security reasons, you might want to specify the exact UCP domain instead.
Available message types¶
Currently, the following message types are supported:
- MAKE_CALL: Initiates an outgoing call to the specified destination
Note: More message types will be added in future versions to support additional UCP functionality.
Example implementation¶
Here's a complete example showing how to add a button that makes a call from the parent window:
<iframe id="ucp-iframe" title='ucp' src='https://qvoice.ca/ucp/login' allow='notifications; microphone' />
<button onclick="makeCall('1234567890')">Call 123-456-7890</button>
<script>
function makeCall(destination) {
const iframe = document.getElementById('ucp-iframe');
iframe.contentWindow.postMessage({
type: 'MAKE_CALL',
payload: {
destination: destination
}
}, '*');
}
</script>
Now you can control UCP functionality directly from your parent website!
