Working with dynamic user data

Better customer engagement need better data. Now, you may already have a simple company website and customer portal in place, where you also publish your contact info. You may even have placed some call-to-action buttons for your customers to call you if they have any problems or questions.

However, when they call you with questions, requests or problems, giving you every opportunity to make them happy, your agents must ask them again and again about their customer id, name, why they are calling, etc.

If you look closely, you can see that it’s highly likely that you already know the answers to these questions, but those answers were on your website or application. Luckily, now you have a way to carry all that data through SIP to your servers and contact centers.

To make it happen, you couldn’t just use a single number or a single static button on every page. You should leverage the dynamic data generated on your web application :

1. Build the dynamic data into a format (preferably JSON) so you can make sense of it afterwards,
2. Send it through the call,
3. Present the data to the person who’s answering the call.

Obviously, the third step has to be done on your premises. This tutorial aims to show how you can handle steps 1 and 2.


What you can modify dynamically

All information about the call your users make from your website using WebRTC buttons is stored in data tags. Below is the complete list of tags available to modify.


Data Attribute Allowed Values Description
widget_texts JSON string Contains text messages presented on the call widget
test_setup Boolean Whether or not to place WebRTC testing link.
custom_button_color HEX RGB Background color of the click-to-call button
incompatible_browser_configuration “link_button_to_a_page”,”hide_widget” or “show_text_html” Tells the SDK what to do if the user’s browser doesn’t support WebRTC. Depending on your preference, you should also update “text_html” for “show_text_html” and “redirect_url” for “link_button_to_a_page”
rating Boolean Whether or not to ask for feedback after the call ends.
caller_id String Caller ID to be presented. The format is “{caller_id}”
context String Custom context data to be sent using the “X-Voxbone-Context” header. JSON representation is highly suggested.
did E164 Voxbone DID number to be called. Only valid if you are using our **[portal widget generator](**
send_digits String Automatically send DTMF digit(s) after a call is connected. This is useful for automatically navigating IVRs or entering access codes for a conference bridge. Digits should use the following format: `1,2,3,1200ms,4,5,900ms,6,#` This string will generate `1` `2` `3`, `wait 1200 milliseconds`, enter `4`, `5`, `wait 900 milliseconds` then enter `6`, `#`.
placement “bottom-right”,”bottom-left”,”top-right” or “top-left” States where the call widget will appear.
display_button Boolean States if we should display the button.Set to `false` if you are using a floating button. Defaults to `true`.
draggable Boolean Enable users to drag the call widget on your webpages. Defaults to `false`.


Step 1 : Decide on a trigger

After copying and pasting the code you generated on our portal, you need to decide on when and how to dynamically modify its data attributes. This depends on how you are planning to get that data from your application. Here are some alternatives :

* window.onload event: Update dynamic data after page is loaded. You can use this if you are mainly extracting the data you need from URL parameters.
* Form submission/log in : Update dynamic data after customer logs in or fills a form. Potentially, you can use the data entered into the form, as well.
* Custom events in your application: You may already have events/functions that are executed to extract user data. You can trigger updating your widget after these are executed.
* API/Web Service calls: If you are doing AJAX or HTTP requests to get user data from your databases and servers, you can update your widget after you successfully received response.

After you decided, the first thing you should do is store the click-to-call button into a variable. Ideally, you can set an id attribute for your widget manually and use document.getElementById or you can use the existing class selector voxButton and document.getElementsByClassName 

var callButton = document.getElementsByClassName(`voxButton`)[0];
var callButton = document.getElementById(`callButton`);

Step 2 : Update data attributes

Now simply update necessary data attributes depending on your implementation.

callButton.setAttribute(`data_something`,`your custom dynamic data`);

Update caller ID to understand who is calling and why

Update the caller ID to see which customer is calling, or to understand why they are calling. If you place buttons on specific product pages, you can specify the caller id to match the product or service name to help your sales team. If you have the button on a support page, you can add the support ticket number or inquiry subject to the caller id.

callButton.setAttribute('data-caller_id', 'product_123456');

Send extensive context data on user behaviour

Use the context header to pass more extensive data. To get the best out of this feature, you should parse the X-Voxbone-Context header in your SIP server and pass it to your client application you use to answer the calls.

var context = {};
context.customerid = '123123124';
context.relatedProduct = '123456';
context.browseHistory = 'household>electronics>TVs>Samsung';
callButton.setAttribute('data-context', JSON.stringify(context));

Update DID to dynamically change where the button is calling

You may have different numbers/SIP URIs for different departments, products or country of operations. Modify data-did on the code generated via the portal widget generator  to call SIP URIs.

callButton.setAttribute('data-did', '3225883229');

Update DTMF preset to bypass IVR menus or PIN entries

Asking your users to “press a number” when they are calling from the web doesn’t really make sense if you don’t really have to. If you have an IVR that plays “press 1 for sales, 2 for accounting…” and your button is supposed to “Call Sales” directly, leverage the `send_digits` attribute.
If your buttons are dialling into a conference call which asks for a meeting number or a PIN code and they are already there on the page that your user is placing the call from, it is the same story. Dynamically update the send_digits from your application to directly connect your end users, with no hassle.

callButton.setAttribute('data-send_digits', '3,2,1,3,4,#');

Update widget texts dynamically to support different languages

If your website has different language versions or you have different numbers/services for different countries, it makes sense to update the widget texts accordingly. Build different JSON strings for different languages and modify widget_texts dynamically.

var widget_texts_english = '{ 
"button":"Call Sales",
"test_your_setup":"Test your setup",
"powered_by":"powered by",
"hang_up":"hang up",
"waiting_user_media":"waiting for user media",
"in_call":"in call",
"rating_question":"How was the quality of your call?",
"rating_comment":"Any additional feedback?",
"thank_you_after_call":"Thank you for using our service",
"unable_to_access_mic":"Oops. It looks like we are unable to use your microphone.",
"unable_to_access_mic_instructions":"Please enable microphone access in your browser to allow this call",
"failed":"call failed",
"error_webrtc":"WebRTC error",
"error_no_answer":"no answer",
"error_no_ack":"no ack",
"error_dialog_error":"dialog error",
"error_user_denied_media":"user denied media access",
"error_bad_media_description":"bad media description",
"error_rtp_timeout":"RTP timeout",
"error_connection_error":"connection error",
"error_request_timeout":"request timeout",
"error_sip_failure":"sip failure code",
"error_internal_error":"internal error",
"error_sip_not_found":"Not Found",
"error_sip_address_incomplete":"Address Incomplete",
"error_sip_incompatible_sdp":"Incompatible SDP",
"error_sip_missing_sdp":"Missing SDP",
"error_sip_authentication":"Authentication Error"
var widget_texts_spanish = '{
"custom": {
"button":"Llama a ventas", 
"test_your_setup":"Prueba tu configuración", 
"powered_by":"creado por",
"waiting_user_media": "Esperando acepte compartir microfono", 
"calling": "Llamando",
if(language == `EN`)
callButton.setAttribute('data-widget_texts', widget_texts_english);
else if(language == `ES`)
callButton.setAttribute('data-widget_texts', widget_texts_spanish);