Embedded Softphone
Here's an interactive introduction on how Wazo Embedded works. Want to learn from a technical approch, please refer to the E-UC Plugins SDK documentation to see how the SDK works.
Assign the softphone to your stackβ
Please enter you stack domain! Otherwise the interactive demo will be limited to the login form
First of all, we need to define a server associated to the softphone, it's required to fully enable the full interactive demo.
Showβ
softphone.show();
Hideβ
softphone.hide();
Minimize / restore the embedded softphoneβ
You can minimize and restore the embedded softphone the way you would any regular window by adding your buttons to the wrapper element, which will allow you to position your buttons relative to the iframe.
const minimizeButton = document.createElement('button');
minimizeButton.addEventListener('click', softphone.hide.bind(softphone));
softphone.wrapper.appendChild(minimizeButton);
const maximizeButton = document.createElement('button');
minimizeButton.addEventListener('click', softphone.show.bind(softphone));
softphone.wrapper.appendChild(minimizeButton);
Move it rightβ
softphone.init({
server: 'my-server',
width: 400,
iframeCss: {
position: 'fixed',
right: 0,
top: '80px',
},
});
softphone.show();
Login directly from a tokenβ
const login = document.querySelector('#login').value;
const password = document.querySelector('#password').value;
const server = document.querySelector('#server').value;
Wazo.Auth.init('softphone-example');
Wazo.Auth.setHost(server);
const session = await Wazo.Auth.logIn(login, password);
softphone.loginWithToken(session.token, session.refreshToken);
Making a callβ
softphone.makeCall('*10');
Parsing link on the pageβ
We can parse links contains tel://
and callto://
on the current page.
Link are already parsed when we authenticate, so we have to call removeParsedLinksEvent
to be able to parse them again.
softphone.onLinkEnabled = (link => {
link.style.color = 'red';
});
// We have to remove the previous parsing of the links
softphone.removeParsedLinksEvent();
softphone.parseLinks();
Injecting CSS in the Embedded Softphoneβ
softphone.injectCss(`
a button {
background-color: green !important;
}
`);
Changing the appearance of the Embedded Softphoneβ
softphone.customizeAppearance({
colors: {
primary: '#d06c2b',
button: '#4b2bd7',
secondary: '#29877c',
},
}, {
// Translation
// Set `debug: true` to know where to change translations, like below:
en: {
call: {
searchInWazo: 'Type a number here !',
},
user: {
login: 'My login button', // will be displayed as `user:login` in the button when settings `debug: true` in the init() method
},
},
}, {
// Assets
logo: 'my-logo.png',
});
Adding a card formβ
We can add form so the user can fill some information during a call, it uses the React Json schema form :
softphone.setFormSchema({
type: 'object',
required: ['title', 'phone'],
properties: {
subject: ["Support", "Greetings", "Whant to talk to Bob"],
title: { type: 'string', title: 'Title' },
note: { type: 'string', title: 'Note' },
},
}, {
note: { 'ui:widget': 'textarea' },
});
Changing the value in the formβ
softphone.setCardValue('title', 'My new title !');
Advanced card formβ
We can add a new field to select the client and allow creating new one.
softphone.setFormSchema({
type: 'object',
required: ['title', 'clientId'],
properties: {
clientId: {
type: 'object',
title: 'Client id',
// triggers the `onDisplayLinkedOption` event when changing the value
triggerDisplay: true,
// createForm is another JSON schema the description the add option form.
createForm: {
optionLabel: '%firstname% %lastname%',
schema: {
type: 'object',
required: ['phone'],
properties: {
firstname: { type: 'string', title: 'Firstname' },
lastname: { type: 'string', title: 'Lastname' },
phone: { type: 'string', title: 'Phone' },
}
},
uiSchema: {}
},
},
title: { type: 'string', title: 'Title' },
note: { type: 'string', title: 'Note' },
},
}, {
note: { 'ui:widget': 'textarea' },
clientId :{ 'ui:field': 'autocomplete'},
});
// Add select values
softphone.onOptionsResults('clientId', [{ label: 'Alice', id: 1 }, { label: 'Bob', id: 2 }, { label: 'Charlies', id: 3 }]);
softphone.onSearchOptions = (fieldId, query) => {
// Call you API here with `query`
// const results = await fetchClient();
const results = [{ label: 'Charles', id: 4}, { label: 'David', id: 5 }, { label: 'Henry', id: 6 }];
softphone.onOptionsResults(fieldId, results);
};
Eventsβ
Iframe loadedβ
softphone.onIFrameLoaded = () => {
document.getElementById('iframe-loaded-event').innerText = 'Embedded Softphone iframe is loaded';
}
β° Will react when the iframe is loaded
User authenticatedβ
softphone.onAuthenticated = session => {
document.getElementById('authenticated-event').innerText = `User authenticated, token: ${session.token}`;
}
β° Will react when the user logs in
User logged outβ
softphone.onLoggedOut = () => {
document.getElementById('logout-event').innerText = 'Current user logged out';
}
β° Will react when the user logs out
Call Incomingβ
softphone.onCallIncoming = call => {
document.getElementById('call-incoming-event').innerText = `Incoming call from ${call.displayName}, number: ${call.number}`
};
β° Will react on incoming calls
Call answered locallyβ
softphone.onCallLocallyAnswered = call => {
document.getElementById('call-locally-answered-event').innerText = `Call answered here, number: ${call.number}`
};
β° Will react on call answered by the user
Call establishedβ
softphone.onCallEstablished = call => {
document.getElementById('call-established-event').innerText = `Call answered, number: ${call.number}`
};
β° Will react on call answered
Call created locallyβ
softphone.onOutgoingCallMade = call => {
document.getElementById('call-outgoing-event').innerText = `Call created here, number: ${call.number}`
};
β° Will react on call created locally
Call rejected locallyβ
softphone.onCallRejected = call => {
document.getElementById('call-rejected-event').innerText = `Call rejected here, number: ${call.number}`
};
β° Will react on call rejected locally
Call endedβ
softphone.onCallEnded = call => {
document.getElementById('call-ended-event').innerText = `Call ended, duration: ${(call.endTime - call.answerTime) / 1000}s`;
};
β° Will react on call ended
User saved the call formβ
softphone.onCardSaved = card => {
document.getElementById('card-saved-event').innerHTML = `Client: ${card.clientId.label}<br /> title: ${card.title}<br /> note: ${card.note}`;
};
β° Will react when the form is saved by the user
User cancels the call formβ
softphone.onCardCanceled = () => {
document.getElementById('card-canceled-event').innerHTML = 'Card canceled π';
};
β° Will react when the form is canceled by the user
User select a value in the select field of the call formβ
softphone.onDisplayLinkedOption = optionId => {
document.getElementById('display-linked-option-event').innerHTML = `Selected identified: ${optionId}`;
};
β° Will react when the user choose a value in a select field of the call form
User select search for a contactβ
softphone.onWazoContactSearch = query => {
document.getElementById('wazo-search-contact-event').innerHTML = `Searching for: ${query}`;
};
β° Will react when the user searches for a contact
User logs in as an agentβ
softphone.onAgentLoggedIn = () => {
document.getElementById('agent-logged-in-event').innerHTML = 'Agent logged in !';
};
β° Will react when the user logs as an agent
User logs out as an agentβ
softphone.onAgentLoggedOut = () => {
document.getElementById('agent-logged-out-event').innerHTML = 'Agent logged out !';
};
β° Will react when the user logs out as an agent
User pauses the agentβ
softphone.onAgentPaused = () => {
document.getElementById('agent-paused-event').innerHTML = 'Agent paused !';
};
β° Will react when the user pauses the agent
User resumes the agentβ
softphone.onAgentResumed = () => {
document.getElementById('agent-resumed-event').innerHTML = 'Agent resumed !';
};
β° Will react when the user pauses the agent
User changes the languageβ
softphone.onLanguageChanged = language => {
document.getElementById('language-changed-event').innerHTML = `Language changed: ${language}!`;
};
β° Will react when the user changes the language
Current call is heldβ
softphone.onCallHeld = () => {
document.getElementById('call-held-event').innerHTML = 'Current call is held βΈοΈ';
};
β° Will react when the current call is held
Current call is resumedβ
softphone.onCallResumed = () => {
document.getElementById('call-resumed-event').innerHTML = 'Current call is resumed βΆοΈοΈ';
};
β° Will react when the current call is resumed
Current call is mutedβ
softphone.onCallMuted = () => {
document.getElementById('call-muted-event').innerHTML = 'Current call is muted π€';
};
β° Will react when the current is muted
Current call is un-mutedβ
softphone.onCallUnMuted = () => {
document.getElementById('call-unmuted-event').innerHTML = 'Current call is un-muted π';
};
β° Will react when the current is un-muted
When the user send a DTMF in the current callβ
softphone.onDtmfSent = tone => {
document.getElementById('call-dtmf-event').innerHTML = `DTMF sent: ${tone}`;
};
β° Will react when a DTMF is sent in the current call
When the user transfers directly the current callβ
softphone.onDirectTransfer = number => {
document.getElementById('call-direct-transfer-event').innerHTML = `Call directly transfered to: ${number}`;
};
β° Will react when the current call is transferred
When the user creates an indirect transferβ
softphone.onCreateIndirectTransfer = number => {
document.getElementById('call-indirect-transfer-event').innerHTML = `Indirect transfer created to: ${number}`;
};
β° Will react when the user creates an indirect transfer
When the indirect transfer call is createdβ
softphone.onIndirectCallMade = call => {
document.getElementById('call-indirect-transfer-made-event').innerHTML = `Indirect transfer answered from: ${call.number}`;
};
β° Will react when the user creates an indirect transfer
When the user cancels an indirect transferβ
softphone.onCancelIndirectTransfer = () => {
document.getElementById('call-indirect-transfer-cancel-event').innerHTML = 'Indirect transfer canceled';
};
β° Will react when the user cancels an indirect transfer
When the user confirms an indirect transferβ
softphone.onConfirmIndirectTransfer = () => {
document.getElementById('call-indirect-transfer-confirm-event').innerHTML = 'Indirect transfer confirmed';
};
β° Will react when the user confirms an indirect transfer
When the user records the current callβ
softphone.onStartRecording = () => {
document.getElementById('call-start-record-event').innerHTML = 'Current call recorded';
};
β° Will react when the user records the current call
When the user stops the record of the current callβ
softphone.onStopRecording = () => {
document.getElementById('call-stop-record-event').innerHTML = 'Current record stopped';
};
β° Will react when the user stops the record of the current call
When the user receives a call logβ
softphone.onCallLogCreated = callLog => {
document.getElementById('call-log-event').innerHTML = `A new call log was created, its duration: ${callLog.duration}`;
};
β° Will react when the user receives a call log
When the user receive a message from the Wazo's Websocketβ
softphone.onWebsocketMessage = (message) => {
document.getElementById('websocket-event').innerHTML = `A new websocket message was received: ${JSON.stringify(message)}`;
};
β° Will react when the user receives a websocket message