Computer telephony integration
- name:
- Computer telephony integration
- description:
- Integrates telephony systems with iTop
- version:
- 1.2.0
- release:
- 2024-09-10
- itop-version-min:
- 3.2
- code:
- combodo-telephony-integration
- state:
- stable
- php-version-max:
- PHP 8.3
This extension provides an easy integration between iTop and a CTI (Computer Telephony Integration) system.
Features
The job of support agents may be eased by integrating iTop with a CTI. This is precisely what the Telephony Integration extension provides.
-
Inbound phone calls received by a support agent may be transformed into an iTop WEB page on the agent's own browser: a dashboard containing information on the caller(s) and his(their) ongoing tickets is displayed and the creation of new tickets can be directly launched from there,
-
Outbound phone calls may be initiated with the caller of a given ticket, directly from the ticket's detailed display,
-
New Phone Call object tracks the phone calls that occurred and that led to a ticket modification,
Behaviour of the extension is highly configurable to fit phone system capabilities and to best answer support teams' requirements.
Revision History
Version | Release Date | Comments |
---|---|---|
1.2.0 | 2024-09-03 | N°7550 - Propose the different Person's phone
attributes for outbound calls N°7736 - Interprete the “+” in front of phone numbers not as a space, but as a character N°7747 - Check caller's attributes before displaying E-Call menu |
1.1.0 | 2024-07-10 | N°5723 - Adapt extension to php 8.1 → 8.3 N°5879 - Provide capability to pre-process phone numbers provided by CTI N°7058 - Better handle rights on PhoneCall, namely for Support and Service Desk Agents N°7492 - Adapt Computer Telephony Integration to iTop 3.1+ |
1.0.1 | 2022-06-13 | First official version |
Limitations
The extension doesn't bring any new feature to the CTI itself, like defining the behaviour of the call routing process based on information stored in iTop. Such integration is possible but should be done on the CTI.
Requirements
The extension only works with iTop 3.2.0 and above.
Installation
Use the Standard installation process for this extension.
Configuration
The default configuration of the extension is brought by its XML datamodel. This configuration can be altered through standard XML customization and / or completed by an administrator through the configuration file.
By default, as shown in the XML datamodel extract, below:
-
The attribute phone is expected in the URL,
-
Parameters to retrieve and display callers are set,
-
Direct ticket creation is present but disabled,
-
Indirect creation of User Requests and Persons are allowed,
-
Ongoing tickets of the found user(s) and its(their) organization(s) are displayed.
- Default configuration defined in XML
-
<module_parameters> <parameters id="combodo-telephony-integration" _delta="define"> <!-- List here the parameters provided in the URL --> <url_parameters type="hash"> <phone>phone</phone> </url_parameters> <!-- This section defines how to retrieve in iTop the contacts related to the given parameters --> <caller_information type="hash"> <label>Contacts with phone number $phone$</label> <query>SELECT Person WHERE phone LIKE :phone OR mobile_phone LIKE :phone</query> <display_name>friendlyname, org_name</display_name><!-- Specify how to display them --> </caller_information> <!-- Should you wish to directly open a ticket when receiving a call, then this section is for you --> <direct_creation type="hash"> <UserRequest type="hash"> <enabled type="bool">false</enabled><!-- enable or disable the function --> <preset type="hash"> <org_id>SELECT Organization AS o JOIN Person AS p ON p.org_id = o.id WHERE p.id = :selected_caller</org_id> <caller_id>:selected_caller</caller_id> <origin>phone</origin> <public_log>Call from customer dated $datetime$</public_log> </preset> </UserRequest> </direct_creation> <!-- List here the class of objects that the agent could be creating from the listed contacts --> <indirect_creation type="hash"> <UserRequest type="hash"> <enabled type="bool">true</enabled> <preset type="hash"> <org_id>SELECT Organization AS o JOIN Person AS p ON p.org_id = o.id WHERE p.id = :selected_caller</org_id> <caller_id>:selected_caller</caller_id> <origin>phone</origin> <public_log>Call from customer dated $datetime$</public_log> </preset> </UserRequest> <Person type="hash"> <enabled type="bool">true</enabled> <preset type="hash"> <phone>:phone</phone> </preset> </Person> </indirect_creation> <!-- This section defines the different list of tickets that you'd like to see upon the reception of the call --> <display_tickets type="hash"> <lists type="array"> <class id="0" type="hash"> <enabled type="bool">true</enabled> <label>User Requests opened for this caller</label> <query>SELECT UserRequest AS u WHERE u.caller_id IN (:callers_list) AND u.status != 'closed'</query> </class> <class id="1" type="hash"> <enabled type="bool">true</enabled> <label>User Requests opened for the organization of the caller</label> <query>SELECT UserRequest AS u JOIN Organization AS o ON u.org_id = o.id JOIN Person AS p ON p.org_id = o.id WHERE p.id IN (:callers_list) AND u.status != 'closed'</query> </class> </lists> </display_tickets> </parameters> </module_parameters>
Should an iTop administrator wishes to change these parameters, he'd just need to add specific lines into the configuration file, under the 'Modules specific settings' section, in a 'combodo-telephony-integration' array. For instance:
- Configuration file
-
'combodo-telephony-integration' => array ( // List here the parameters provided in the URL 'url_parameters' => array ( 'phone' => 'phone', ), // This section defines how to retrieve in iTop the contacts related to the given parameters 'caller_information' => array ( 'label' => 'Contacts with phone number $phone$', 'label/FR FR' => 'Contacts ayant le numéro de téléphone $phone$', 'query' => 'SELECT Person WHERE phone LIKE :phone OR mobile_phone LIKE :phone', 'display_name' => 'friendlyname, org_name, location_name', // Specify how to display them ), // Should you wish to directly open a ticket when receiving a call, then this section is for you 'direct_creation' => array ( 'UserRequest' => array ( 'enabled' => false, 'preset' => array ( 'org_id' => 'SELECT Organization AS o JOIN Person AS p ON p.org_id = o.id WHERE p.id = :selected_caller', 'caller_id' => ':selected_caller', 'origin' => 'phone', 'public_log' => 'Call from customer dated $datetime$', ), ), ), // This section defines the different list of tickets that you'd like to see upon the reception of the call 'indirect_creation' => array ( 'UserRequest' => array ( 'enabled' => false, 'preset' => array ( 'org_id' => 'SELECT Organization AS o JOIN Person AS p ON p.org_id = o.id WHERE p.id = :selected_caller', 'caller_id' => ':selected_caller', 'origin' => 'phone', 'public_log' => 'Call from customer dated $datetime$', ), ), 'Incident' => array ( 'enabled' => true, 'preset' => array ( 'org_id' => 'SELECT Organization AS o JOIN Person AS p ON p.org_id = o.id WHERE p.id = :selected_caller', 'caller_id' => ':selected_caller', 'origin' => 'phone', 'public_log' => 'Call from customer dated $datetime$', ), ), 'Change' => array ( 'enabled' => true, 'preset' => array ( 'org_id' => 'SELECT Organization AS o JOIN Person AS p ON p.org_id = o.id WHERE p.id = :selected_caller', 'caller_id' => ':selected_caller', 'origin' => 'phone', 'private_log' => 'Call from customer dated $datetime$', ), ), 'Person' => array ( 'enabled' => true, 'preset' => array ( 'phone' => ':phone', ), ), ), // This section defines the different list of tickets that you'd like to see upon the reception of the call 'display_tickets' => array ( 'lists' => array ( 0 => array ( 'enabled' => true, 'label' => 'User Requests opened for this caller', 'query' => 'SELECT UserRequest AS u WHERE u.caller_id IN (:callers_list) AND u.status != \'closed\'', ), 1 => array ( 'enabled' => true, 'label' => 'User Requests opened for the organization of the caller', 'label/FR FR' => 'Demandes utilisateurs de l\'organisation de l\'appelant', 'query' => 'SELECT UserRequest AS u JOIN Organization AS o ON u.org_id = o.id JOIN Person AS p ON p.org_id = o.id WHERE p.id IN (:callers_list) AND u.status != \'closed\'', ), 2 => array ( 'enabled' => true, 'label' => 'Problems opened for this caller', 'label/FR FR' => 'Problèmes ouverts par l\'appelant', 'query' => 'SELECT Problem AS u WHERE u.caller_id IN (:callers_list) AND u.status != \'closed\'', ), 3 => array ( 'enabled' => true, 'label' => 'Incidents opened for this caller', 'label/FR FR' => 'Incidents ouverts par l\'appelant', 'query' => 'SELECT Incident AS u WHERE u.caller_id IN (:callers_list) AND u.status != \'closed\'', ), ), ), // Define here how to launch an outbound call from a ticket, using the caller's parameters 'ecall_parameters' => array ( 'url' => 'https://myctiserver/index.php', 'url_parameters' => array ( 'telephone' => 'phone', 'mailaddress' => 'email', ), ), ),
Inbound calls
The behaviour of the extension when processing inbound calls is fully driven by it's configuration. The following chapters will help you to understand how.
iTop URL to reach the telephony extension
When answering a phone call, a support agent may decide to visualize, in iTop, information related to the caller and his ongoing tickets. For that purpose, he launches an operation on his CTI that opens, on his own browser, a page containing the URL of the telephony extension. The called URL must have a specific format that holds both:
-
the path to the iTop server,
-
the parameters that will allow iTop to look for the caller in its data base.
This could be something like:
https://myitopserver/pages/exec.php?exec_module=combodo-telephony-integration&exec_page=index.php&phone=0987654321
The first (https://myitopserver/pages/exec.php?exec_module=combodo-telephony-integration&exec_page=index.php) part refers to the server and is static. The second (&phone=0987654321) one holds the caller's attributes, like here the 'phone' parameter that obviously corresponds to the phone number of the caller, and must correspond to what has been defined in the configuration file, under the 'url_parameters' section:
'url_parameters' => array ( 'phone' => 'phone', ),
That array specifies that the 'phone' parameter (on the left) used in the URL actually corresponds to the 'phone' attribute (right) of the class Person in iTop.
We could have defined another configuration, like:
'url_parameters' => array ( 'telephone' => 'phone', 'mailaddress' => 'email', ),
With:
-
'telephone' as the URL parameter that identifies the 'phone' attribute of the class Person in iTop,
-
'mailaddress' as the URL parameter that identifies the 'email' attribute of the class Person in iTop.
Then, the URL would have been :
https://myitopserver/pages/exec.php?exec_module=combodo-telephony-integration&exec_page=index.php&telephone=0987654321&mailaddress=mymail@mycompany.com
-
'myitopserver' should be replaced by iTop server's address or name and path to the iTop application,
-
each URL parameters should be set according to the caller's parameters
Caller(s) lookup
Once the CTI has launched the telephony page, iTop extracts the different parameters given in the URL as specified in the 'url_parameters' section. If any listed parameter is missing, an error is generated.
Should the URL contain additional parameters, these will be discarded.
Once all parameters are correctly extracted, iTop will search for the corresponding person(s) in its data base by executing the OQL query defined in the 'caller_information' section of the configuration.
'caller_information' => array ( 'label' => 'Contacts with phone number $phone$', 'label/FR FR' => 'Contacts ayant le numéro de téléphone $phone$', 'query' => 'SELECT Person WHERE phone LIKE :phone OR mobile_phone LIKE :phone', 'display_name' => 'friendlyname, org_name, location_name', ),
-
The label parameter allows administrator to set the title of the block displaying the found persons,
-
This label can be localized,
-
Parameters extracted from the URL may be used in the OQL query through placeholders. These are iTop attributes preset with a semi-column ':',
-
The display_name parameter allow the administrator to select the attributes that will be used to identify a person when displayed in the telephony page.
From there, the OQL may return nobody, a unique person or several persons. That result is processed accordingly through the following steps.
Preprocessing of incoming parameters to match iTop attributes' format
The format of phone numbers provided by the CTI (like 0987654321) may not be aligned with the de facto format used to store phone numbers in iTop (like +33 9 87 65 43 21). In order to enable a match between these 2 numbers, a preprocessing may be activated on the CTI's phone number:
-
This processing is handled by the method ReformatPhoneNumberToMatchiTopUsage defined in the XML datamodel file of the extension, under the class Contact.
-
The method is called by the CTI code on all entry parameters but does nothing by default (parameters are left untouched).
-
It may be overloaded by an extension so that real preprocessing is made.
-
The method contains some inactive examples that may be activated if required.
Direct ticket creation
iTop administrator may decide that a call to the telephony extension directly opens the creation form of a ticket. This is driven by the 'direct_creation' chapter of the configuration.
'direct_creation' => array ( 'UserRequest' => array ( 'enabled' => false, 'preset' => array ( 'org_id' => 'SELECT Organization AS o JOIN Person AS p ON p.org_id = o.id WHERE p.id = :selected_caller', 'caller_id' => ':selected_caller', 'origin' => 'phone', 'public_log' => 'Call from customer dated $datetime$', ), ), 'Incident' => array ( 'enabled' => true, 'preset' => array ( 'org_id' => 'SELECT Organization AS o JOIN Person AS p ON p.org_id = o.id WHERE p.id = :selected_caller', 'caller_id' => ':selected_caller', 'origin' => 'phone', 'public_log' => 'Call from customer dated $datetime$', ), ), ),
Direct creation is launched as soon as it exists one entry in the 'direct_creation' chapter with the 'enabled' status set to true.
-
Such entry must be named according to the name of an abstract or non abstract iTop class (UserRequest or Incident in the above example).
-
Should several such entries be enabled, only the first one will be processed.
-
Should no entry be enabled or should that chapter be missing, the telephony extension will skip that step and directly jump to the following one.
In the above example, the Incident creation form is opened when the telephony extension URL is called.
To help the support agent capturing the caller's request, some attributes may be preset in the creation form. These are specified in the 'preset' chapter of each 'direct_creation' entry.
-
external keys may be defined by an OQL that uses the same type of placeholders as the one defined in the caller information query,
-
some external keys may be directly defined by a placeholder,
-
the value of an enum or a string can be set,
-
an entry can be added into a log attribute.
The caller attribute of the ticket is preset according to the result of the caller(s) lookup:
-
If nobody has been found, the attribute is left empty,
-
If a unique person has been found, the caller is preset with that person,
-
If several persons have been found, the caller is preset with the first one that the OQL returned.
Indirect ticket creation
Should iTop administrator decide to not directly open the creation form of a ticket, he may select a set of objects (tickets, most of the time, but not necessary) that the support agent will be able to create once the telephony page is displayed. This is driven by the 'indirect_creation' chapter of the configuration.
'indirect_creation' => array ( 'UserRequest' => array ( 'enabled' => false, 'preset' => array ( 'org_id' => 'SELECT Organization AS o JOIN Person AS p ON p.org_id = o.id WHERE p.id = :selected_caller', 'caller_id' => ':selected_caller', 'origin' => 'phone', 'public_log' => 'Call from customer dated $datetime$', ), ), 'Incident' => array ( 'enabled' => true, 'preset' => array ( 'org_id' => 'SELECT Organization AS o JOIN Person AS p ON p.org_id = o.id WHERE p.id = :selected_caller', 'caller_id' => ':selected_caller', 'origin' => 'phone', 'public_log' => 'Call from customer dated $datetime$', ), ), 'Change' => array ( 'enabled' => true, 'preset' => array ( 'org_id' => 'SELECT Organization AS o JOIN Person AS p ON p.org_id = o.id WHERE p.id = :selected_caller', 'caller_id' => ':selected_caller', 'origin' => 'phone', 'private_log' => 'Call from customer dated $datetime$', ), ), 'Person' => array ( 'enabled' => true, 'preset' => array ( 'phone' => ':phone', ), ), ),
In the above example, the agent will be able to create an Incident, a Change or a Person through its telephony page. Choice for UserRequest creation will not be given because the 'enabled' parameter is set to false in the UserRequest section of the 'indirect_creation' chapter.
The list of callers is displayed in a combo box, according to who has been found previsouly. This can be:
Display | Persons found | Combo box choices | Number of choices |
---|---|---|---|
No one | Unknown Contact | 1 | |
A unique one | Contact #1 Unknown Contact |
2 | |
Several | All contacts found Contact #1 … Contact #n Unknown Contact |
n + 2 |
Selecting a person and clicking on a 'Create a new xxx' button opens the creation form of the xxx class, already preset according to what has been specified in the 'preset' section of the class, under the 'indirect_creation' chapter.
Tickets display
Next to the found person list and the object creation buttons, the telephony extension may display different groups of tickets, according to what is defined in the 'display_tickets' chapter of the extension configuration.
'display_tickets' => array ( 'lists' => array ( 0 => array ( 'enabled' => true, 'label' => 'User Requests opened for this caller', 'query' => 'SELECT UserRequest AS u WHERE u.caller_id IN (:callers_list) AND u.status != \'closed\'', ), 1 => array ( 'enabled' => true, 'label' => 'User Requests opened for the organization of the caller', 'label/FR FR' => 'Demandes utilisateurs de l\'organisation de l\'appelant', 'query' => 'SELECT UserRequest AS u JOIN Organization AS o ON u.org_id = o.id JOIN Person AS p ON p.org_id = o.id WHERE p.id IN (:callers_list) AND u.status != \'closed\'', ), 2 => array ( 'enabled' => false, 'label' => 'Problems opened for this caller', 'label/FR FR' => 'Problèmes ouverts par l\'appelant', 'query' => 'SELECT Problem AS u WHERE u.caller_id IN (:callers_list) AND u.status != \'closed\'', ), 3 => array ( 'enabled' => true, 'label' => 'Incidents opened for this caller', 'label/FR FR' => 'Incidents ouverts par l\'appelant', 'query' => 'SELECT Incident AS u WHERE u.caller_id IN (:callers_list) AND u.status != \'closed\'', ), ), ),
Each group may be enabled or disabled. Their description can be configured and localized through the label parameters and their content is defined by an OQL. Of course, a group will not be listed if the class defined by its OQL is not implemented in the data model. The above example would give:
-
Selecting another user will reload the different lists accordingly,
-
Selecting 'Unknow contact' will just remove the lists from the screen,
-
Selecting 'All contacts found' (In the case where multiple persons have been found) will reload the lists with the tickets of each persons.
From there, the support agent may select a given ticket and decide to just display its content or to open its modification form. No content is automatically added to the ticket at this stage.
Outbound calls
Nowadays, all Internet browsers offer a “click to call” feature that associates a phone call action (simply calling, usually) to specific attributes like phone numbers. Next to that standard capability, the Telephony extension allows support agents to directly launch a phone call from a ticket, where no phone attribute is usually displayed, to the caller of the ticket.
This behaviour is driven by the 'ecall_parameters' section of the Telephony configuration. Different flavours of the configuration are supported.
For version 1.1.0 and below:
'ecall_parameters' => array ( 'url' => 'https://myctiserver/index.php', 'url_parameters' => array ( 'telephone' => 'phone', 'mailaddress' => 'email', ), ),
Where:
-
'url' defines the url where to reach the CTI server,
-
'url_parameters' lists the parameters that need to be provided to the CTI and what they correspond to in iTop. Here:
-
'telephone' will contain the 'phone' attribute of the caller,
-
'mail' will contain the 'email' attribute of the caller.
-
For version 1.2.0 and above:
'ecall_parameters' => array ( 'url' => 'https://myctiserver/index.php', 'url_parameters' => array ( 'phone' => array ( 'icon' => 'fas fa-phone', 'attributes' => array ( 'telephone' => 'phone', 'mailaddress' => 'email', ), ), 'mobile_phone' => array ( 'icon' => 'fa fa-mobile', 'attributes' => array ( 'telephone' => 'mobile_phone', ), ), ), ),
Where:
-
'url' defines the url where to reach the CTI server,
-
'url_parameters' lists different actions that may be selected to launch the outbound call:
-
'phone' / 'mobile_phone':
-
'icon': icon that will be displayed next to the given action
-
'attributes' :parameters that need to be provided to the CTI for the selected action and what they correspond to in iTop.
-
-
With the above 1.1.0 configuration example, the generated URL would be something like:
https://myctiserver/index.php?telephone=0123456789&mailaddress=mymail@mycompany.com
Setting up this 'ecall_parameters' configuration section will activate the feature. In such case, a phone icon will appear in the list of the actions associated to a ticket. Clicking on it will just open a new tab with the correct URL.
Should you wish to move the menu at the top right of the ticket, next to the “Create” action, just add its name in the 'shortcut_actions' parameter of iTop's configuration, as shown below:
// shortcut_actions: Actions that are available as direct buttons next to the "Actions" menu // default: 'UI:Menu:Modify,UI:Menu:New' 'shortcut_actions' => 'UI:Menu:Modify,UI:Menu:New,telephony_integration_ecall_legacy,telephony_integration_ecall_phone,telephony_integration_ecall_mobile_phone',
-
The telephony_integration_ecall_legacy term relates to configuration type 1.1.0
-
The telephony_integration_ecall_phone or telephony_integration_ecall_mobile_phone term relates to configuration type 1.2.0
When activated, the feature is available on all tickets that inherit from the class Ticket.
-
Version 1.2.0+ of the extension accepts person's phone numbers that start with a '+' followed by a country code, as specified in E.164 standard. Such phone numbers are integrally transfered to the CTI, '+' included.
-
In the case where a phone number attribute is empty, the E-Call corresponding menu is not displayed on the ticket's detailed page.
Phone Calls
The Telephony extension brings a new object named Phone Call which purpose is to track inbound and outbound calls related to a ticket. Every time a ticket is created with the origin parameter set to phone (which is the case for tickets created from the “Telephony Control Panel”), a Phone Call is created and attached to the ticket. Similarly, every call launched from a ticket through the extension creates a Phone Call and attaches it to the ticket.
Phone Call Properties
Name | Type | Mandatory? |
---|---|---|
Contact | Foreign key to a(n) Person | No |
Agent | Foreign key to a(n) Person | Yes |
Ticket | Foreign key to a(n) Ticket | Yes |
Date | Date (year-month-day) | No |
Flow | Possible values : Inbound / Outbound | Yes |
Note | Multiline character string | No |
-
Modify / Bulk Modify as well as Delete rights on PhoneCall objects are granted to the Support and Service Desk Agents. Tickets, with a phone origin, created by other profiles won't have any PhoneCall created.
-
By default, Read / Bulk Read capabilities are given to all other profiles unless specifically denied by an extension or modification of the default data model.
Display a Phone Call
From the detailed display of a ticket, open the 'Phone Calls' tab and select one of the listed elements.
Ticket's tab
From a ticket perspective, a new tab called 'Phone Calls' is displayed on classes that do appear in the 'display_tickets' chapter of the Telephony configuration.
Integration use cases
The extension has been tested with different CTIs. This chapter provides information on how to configure both iTop and the CTI application to activate the features described here above.
3CX
See WEB site.
Inbound calls
In order to allow 3CX to open a page on your browser when a call is received, go to the “Settings / Integration” menu of your desktop application (web page or client app), then:
-
Select the option “Auto launch a Custom Contact URL using variables”
-
Set the contact URL to
http://your_itop/pages/exec.php?exec_module=combodo-telephony-integration&exec_page=index.php&phone=%CallerNumber%
-
Decide when to be connected: when the phone rings or when connected with the caller.