Skip to content
skyflak3s edited this page Nov 12, 2013 · 72 revisions

Table of Contents

Introduction

The Callinize module provides integration features between SugarCRM and Asterisk telephony software. Once installed, callinize provides one-click dial from within SugarCRM to contacts, accounts etc., as well as sophisticated call monitoring / logging.

NOTE: Pretty screenshots of what this app looks like can be found at the bottom the main wiki page.

Installation

Pre-Requisites

  • Sugar 6.0+. __Sugar OnDemand aka Sugar Cloud is not supported__.
  • Asterisk 1.6+, Asterisk 1.4 is partially supported. Some features such as Ring Groups and Queues probably do not work. Recommended version is Asterisk 1.8.
  • MySQL Database - The code does make some direct database calls. Sorry.
  • SugarCRM on-site... This will not work On Demand Versions since it needs to run a separate process.
  • Patience and willingness to read the documentation.
  • Internet Access is required for asteriskLogger.php to make soap calls (see https://github.com/blak3r/yaai/issues/39)
  • SELinux must be disabled for Click to Dial to work. See Click to Dial is not working for more.
  • Some users have had issues when php memory limit is less than 60MB but this is unconfirmed.

Update Instructions

There are two options when updating.

  1. Uninstall the old version first, then install the new one. This is the probably the safest method but it has some annoyances. When you uninstall the module in the module loader, it will delete the custom fields YAAI added to the User's Module such as the Asterisk Extension, Magic Dial Buttons and Call Notification. As a result, you will need to enter all the users' extensions and check Magic Dial Buttons and Call Notification for each user. To get around this you could backup the Users_cstm table before uninstalling and then restore it afterwards. Additionally, you will need to redo the layouts for the Users in studio. Even though the fields are removed from the Users database the fields will still appear in studio but they are no longer properly linked to the fields in DB. So, you will need to delete them from the layout (by dragging them off) and then dragging each of the fields back on to the form. If you don't redo the studio layout, you will still see them on the User Edit View but any changes you make will NOT be saved (therefore, after you click save they will be blank on the Detail View).
  2. Install the new version on top of (ie without uninstalling the old one). This method worked fine when I tested an upgrade install from 2.4 --> 2.6 on Sugar 6.5. But, I have not tried it with older versions of yaai and other versions of Sugar. On older versions I know of one issue (doesn't mean there aren't others). The one issue is you will end up with multiple entries in the /custom/modules/LogicHooks.php for the after_ui_frame logic hook. This is the logic hook that adds the javascript to the page... as a result you'll get two copies which could mess things up... at the very least it'll make page loads slower and you might get multiple call popups. If you did an upgrade install, you should check the file at /custom/modules/LogicHooks.php and remove the first one in the list (if there is more then one referencing custom/modules/Asterisk/include/AsteriskJS.php. There may be other issues as well with doing this that I'm not yet aware of which is why I recommend method #1 just to be safe. You might end up with multiple versions that appear in the Module Loader list or something way worse.

Step 1: "Module Loader"

Installation is done using the "Module Loader" from within SugarCRMs Admin section.

  • If you are updating YAAI on your sugar instance be sure to read the section above!

Step 2: Configuring Asterisk AMI

You will need to configure your asterisk box to allow for AMI (Asterisk Management Interface) connections.

In short, you need to create a user in manager.conf or manager_custom.conf that has

read=call,hud
write=originate,system,call

Configuring Asterisk is outside the scope of this project. Furthermore each distro (Trixbox,Elastix,PIAF,etc) have different ways of configuring AMI. You should probably google something like "elastic Asterisk Manager Setup". Please add links here to guides you found helpful in setting up AMI.

Here is a decent guide for asterisk in general. You should follow the portion of this guide by using telnet to troubleshoot whether or not AMI is configured properly. http://www.the-asterisk-book.com/unstable/asterisk-manager-api.html

Here's a sample:

[yaai]
secret = YOUR_PASSWORD
deny=0.0.0.0/0.0.0.0
permit=127.0.0.1/255.255.255.0
read = all 
; ^--- on some systems you can get away with just "call,hud"
write = originate,system,call

originate is needed for click to dial.
system is only needed if you want the block call option (uses DBPut)
call - is needed for transferring (Redirect).

If your Sugar instance is running on a different server, don't forget to permit that ip-address and ONLY that ip-address. AMI connections are not encrypted so you need this for some security.

Step 3: Configure System Settings

Please refer to the next section on Configuration Settings and then proceed to Step 4.

Step 4: Start Asterisk Logger!

Important: You must run from the command line (or as a service) asteriskLogger.php!!!

  1. cd to sugar_root/custom/modules/Asterisk
  2. php asteriskLogger.php
  3. Look at the output and look for errors when connecting to soap, database, or Asterisk Manager Interface.
  4. If you have any errors, then you should update the configuration settings for Asterisk Manager and SOAP and then restart asteriskLogger.
  5. Once asteriskLogger is running you will see "Waiting for events". Try making a call and you should see events start to come in.
Refer to the Components / Theory of Operation --> asteriskLogger section for complete instructions. At this point, I would recommend testing it as outlined in Troubleshooting --> nothing works before proceeding.

Step 5: Add New User Fields to User Layouts

Follow the instructions below based on your sugar version.

For 6.4+, the User layout is now configurable in studio.

  1. Open Studio
  2. Open User -> Edit View Layout
  3. Create a new panel and copy over the 3 new fields: Personal Extension, Magic Dial, Call Notification.
For Older versions

If you're using an older version of Sugar you have to manually merge some files to get this working... (Or if you haven't modified this at all... you can just overwrite it).

See the files in /SugarModules/modules/Asterisk/Users You can probably just open the .patch files and follow the instructions in them. Alternatively, if you look at the manifest.php I commented out all old files that used to be copied. You could just uncomment those before installing via module loader.

Please contribute back instructions, if you figure out the proper approach to merging in files. Since this issue is resolved in v6.4, didn't seem worth too much time invested in figuring this issue out. When the author tested on v6.1.1 I just copied all the files in /SugarModules/modules/Asterisk/Users into my /custom/modules/Users folder... (just copied the files not subdirs)

Step 6: Click To Dial Buttons

You might want to skip this step for now and return to it later.

The dialout.js looks for the .phone class. By default (at least in sugar 6.4) all the detail views have office phone, mobile phone, etc. wrapped in the .phone class. But, some of the list views do not unfortunately. Also, the Contacts subpanel does not have click to dial icons on an Account DetailView page.

To fix this...

  1. Copy include/SugarFields/Fields/Phone/ListView.tpl to custom/include/SugarFields/Fields/Phone/ListView.tpl cp include/SugarFields/Fields/Phone/ListView.tpl custom/include/SugarFields/Fields/Phone/ListView.tpl
  2. Change the last line to:
    <span class='phone'>{sugar_phone value=$phone usa_format=$usa_format}</span>

Thanks to Jason Eggers for this solution!

Step 6: (Optional) Call Durations

If you are planning on editting the calls and want to keep the correct duration, use the dropdown editor in studio and add 1 minute intervals to duration_interval. Or copy(the contents of) /utils/Duration/en_us.lang.php to custom/include/language/ (NOTE: if this file already exists, PLEASE copy the contents or you will lose your custom/editted dropdown lists.)

Step 7: (Optional) Install asteriskLogger as daemon (or Service)

Windows Installation

There currently isn't a documented method for running asteriskLogger.php on windows. There are some tools for doing this on windows and some are mentioned in the Project-TODO-List page.

Linux Installation

  1. wget https://raw.github.com/blak3r/yaai/master/misc/asterisk_logger -or- extract from the module zip you downloaded from sugarforge and get it from misc/asterisk_logger
  2. copy asterisk_logger to /etc/init.d/
  3. chmod 755 /etc/init.d/asterisk_logger
  4. Edit the script by opening /etc/init.d/asterisk_logger in your editor of choice
    • Find the USER variable towards the top and set it to what user APACHE runs as (usually apache or www-data).
    • Find the SUGAR_ROOT variable towards the top and set it to where your sugarcrm directory lives (usually /var/www/html, /var/www/html/sugarcrm, /var/www/sugarcrm, or /var/www)
  5. Install the Script (this step is distro dependent see reference below to identify)
    • For Centos, Red Hat, Fedora Core, Suse, etc)
      chkconfig --add asterisk_logger
    • For Debian, Ubuntu, and similar
      update-rc.d -f asterisk_logger start 80 2 3 4 5 . stop 30 0 1 6 .
To test that you set up the script properly after step 4, you can run /etc/init.d/asterisk_logger start if you have errors you’ll most likely see them on the console. You can also do tail -f asterisk_log if you have this configured in sugarconfig and you should see that it connected successfully.

Not sure what distro you have? Try running one of these "distro dependent" commands until you find one that gives you helpful info: /etc/version,/proc/version,uname -a

Configuration settings

This chapter provides information on required settings to get YAAI up and running.

System Settings

These settings affect the overall operations of YAAI (and asteriskLogger.php in particular). To review these settings, navigate to Admin → ASTERISK SugarCRM Connector::ASTERISK Configuration:

Parameter Description
Asterisk Manager Host Obviously, the node where Asterisk is running
Asterisk Manager Port The Port where the Manager API is running – Default is 5038
Asterisk Manager Login Username configured in Asterisks manager.conf
Asterisk Manager Password Login credentials (manager.conf)
Dial Context Asterisk context where outgoing calls are placed. Check extensions.conf for proper value.
Dialout Prefix Optional number prefixed to all outgoing calls (e.g. „0“ to get an external connection)
Dialpattern for inbound/outbound matching To provide proper call logging, asteriskLogger.php needs to distinguish incoming from outgoing calls. Here you may provide a regular expression to detect an internal trunk. This pattern is matched against the caller id sent by Asterisk, which is usually something like „SIP/xxx-yyyyy“, where xxx identifies your internal extension. Thus, for the popular case of internal phones to have 2 or 3 digit extensions, the pattern would be ^SIP/[1-9][0-9][0-9]? Hint: this approach should fit most needs, for more complex scenarios, you might want to tweak asteriskLogger.php Hint: The pattern matching is done case-insensitive
Asterisk SOAP User AsteriskLogger uses this user to make SOAP calls to SugarCRM; this user owns all unassignable call records. You should provide some unprivileged dummy user for that purpose.

NOTE: This is not a complete list of options. Starting in yaai 2.6 we started putting little ? tooltips next to each label. So, mouse over those for a description.```

Per User Settings

Asterisk Extension The Asterisk extension assigned to that particular user. The extension is used to match inbound calls with some SugarCRM user. User can have several extensions separated by the comma, plugin will assign a user if any of them matches. Example: "5501,5502".
Call notification Activate visual call notification. You usually want this ;-)
Magic Dial Buttons Puts little call icons by each phone number to enable Click To Dial Functionality. (See Post installation notes).

Components / Theory of operation

In this section, we shall provide an overview on the different components of YAAI, along with a brief description of their interaction. This should give you an idea how YAAI works, but is surely no complete description of the system. However, all is written in PHP, so "use the source"....

asteriskLogger.php

This script provides the glue between Asterisk and SugarCRM. This script is not part of the SugarCRM GUI, it must be run "standalone". What this means is you need to open a command window and execute:

php <path-to-sugarcrm></path-to-sugarcrm>/Asterisk/asteriskLogger.php

This will run the script in foreground mode, echoing its operational messages to the console. It is possible to run this script as a background service, please see the "misc" folder when you extract the module for some contributed startup scripts that work on linux. Currently, there is no windows service solution.

From a design standpoint, it's obviously not ideal to have to have an external script needed to make this work. But, the alternative has a completely different set of challenges which are arguably worse. The alternative is to write a number of AGI scripts and modify every one of your users' dial command to invoke them. Getting these custom scripts that run on the asterisk box working would make isolating the source of the problem even harder and they'd be less universal between different flavors of asterisk such as trixbox, elastic, etc. The end result is having difficult configuration challenges on both your asterisk box and on your sugarcrm box. As a result, updating becomes a real hassle, development becomes difficult, ... so having everything in PHP becomes a lot more attractive. Eventually, adding more AGI scripts might be inevitable in order to add more features like Caller ID overriding, call recording etc. A greater discussion on the pros/cons of this approach will be had another wiki page.

Note: Internet Access is required for asteriskLogger.php to make soap calls (see https://github.com/blak3r/yaai/issues/39).

NOTE: it's possible to make the script run as a service see the installation steps above.

asteriskLogger.php registers itself as a client to Asterisk's Manager API, so it receives notifications on Asterisk's activities. Most notably, the events we are interested in are Dial, NewcallerID, Hangup and Bridge. It uses the information received from these events for two purposes:

  • Maintain the state of current calling activity in database table "asterisk_log". The information held in asterisk_log is used by SugarCRMs GUI (dialin.js/callListener.php) to display call notifications in a popup.
  • On receiving the "Hangup" event, a record is created in SugarCRM's Calls module, providing information about the callers ID, date and time of the call, duration, etc.
References: For a description of Asterisk's Manager API, see:
http://www.voip-info.org/wiki/view/Asterisk+manager+API
http://www.voip-info.org/wiki/view/asterisk+manager+events

pre_install.php

This script is called during installation of the YAAI module. The tasks performed during installation are: creation of table asterisk_log in database (Note: this is done with straight SQL)

post_install.php

This script is called during installation of the YAAI module. It creates the 3 entry points needed for AJAX calls.

AsteriskJS.php

This script is installed as after_ui_frame logic hook and provides the magic to enhance all pages in the GUI with YAAI's functionality. Depending on users settings, it conditionally includes dialin.js and/or dialout.js, and jquery (if it hasn't already been included by some other module).

callPopups.js (formerly dialin.js)

This script is responsible for monitoring calls. It uses AJAX calls (Whoa! Did I already mention we use AJAX?) to callListener.php (which in turn peeks into asterisk_log) to poll (and display) the current state of Asterisk's call activity. Note this script is responsible for both incoming and outgoing calls.

In version 2.0 this file got a major facelift and is where all the chat box ui code is. It uses some cookies to keep track of various ui states of the windows. Has the code for saving memos... etc.

dialout.js

This script – when included – uses jQuery to dynamically add a dialout button icon for each phone number fields. When the icon is pressed, the number is passed to callCreate.php (through an entryPoint) which then in turn issues an AMI originate command to start the call process.

callListener.php

This is the AJAX listener for callPopups.js. It retrieves all the relevant calls from the table asterisk_log and returns the list of calls as JSON encoded data.

It also is where any OpenCNAM lookups are performed if caller isn't found in the database.

callCreate.php

This script is invoked to initiate an outgoing call. It simply opens a socket connection to Asterisk Manager and sends an „Originate“ action to place an outgoing call.

controller.php (new in v2.0)

This script handles several actions such as memoSave, and uiState. CallListener and CallCreate should be refactored into this class eventually.

  • MemoSave Action. Called when user clicks save in the chat box. It write the call notes to the call record.
  • UIState Action. Called when the user clicks the 'X' button to close a chat box. Once a chat box has been closed it's uistate is written to the database so that the appropriate call is no longer returned by callListener.php.
  • Transfer Action - Added in 2.2, transfers the call to extension/number provided.
  • setContactId Action - Used to resolve conflicts between multiple contacts.

FAQ

How are multiple matching contacts handled / When are calls related to Accounts?

When the user doesn't intervene (by selecting from a list of matching contacts or manually relating), the first matching contact found in the database is picked. This happens when the hangup action occurs.

Unattended (aka not logged into Sugar) Behavior:

  • If phone number matches an account phone number, log it to account only.
  • If it matches multiple contacts and each of them is from the same account, then log it to account only.
  • If it matches multiple contacts and the account name differs... We can't determine for sure who this should be logged to so we do not relate it to anyone to avoid confusion.
Attended Behavior (From Call Popups)

If the user is currently logged into sugar and they have call notification enabled, when there are multiple matching contacts the user can select the contact by clicking on a radio button.

  • If phone number matches an account only, the account is displayed. The user should probably create a contact under that account...
  • If phone number matches an account and contact --> It'll show the contact name + Account.
  • If phone number matches multiple contacts --> it'll show all of them with radio buttons which the user can select from. Once selected, setBeanId ajax call is triggered which updates the bean_id column in the asterisk_log table. When the Dial End event occurs, Asterisk logger will look to see if a contact has already been established for this call and will not do a lookup if a decision has been made in call popups.

Troubleshooting

I upgraded from 2.6 to 3.5 and it doesn't work anymore

3.5 required that you had at least one custom field in your account and contacts module. This requirement has been removed. We recommend upgrading to 3.6.

Nothing seems to be working... / I don't get any call popups

  1. Did you follow the steps in the Post Install section? There are some manual steps you must do after installing the module loader. Specifically, did you remember to run asteriskLogger.php from the command line? This is what most people will forget to do.
  2. Now that you're running asteriskLogger.php analyze the output when it starts up. It will attempt to connect to the your asterisk server and also it will try to login to your SugarCRM box via soap. Read the output of the script and if either fail then you probably have some error in your System Settings.
  3. If you didn't get any errors, then make a call on your PBX system (like pick up a phone the old fashioned way and call anyone). Do you see events popping up? If so, then we know that the user you logged into AMI with has the correct permissions. If you don't, then you most likely have a missing priviledge for your user in your manager.conf. To narrow this down, set
    read = all
    write = all 

See if that resolves your problem and then tighten up the security later. I think the permissions that are needed are call, originate, and hud... but I seem to recall it varying from version to version of Asterisk. (Someone update this documentation if they know definitively.) If you still aren't getting events popping up, something on the asterisk end of things is not working and you're on your own i'm afraid. You need to be able to telnet into your asterisk box on port 5038, initiate a login and then start seeing events show up in there. If you don't, then something is not configured your manager.conf properly.

  1. When testing, make sure you use an outside line. Call popups aren't created for Internal to Internal calls. So, use a cell phone for example.

Click To Dial Icons Aren't Showing Up

In order for this to work:

  1. Did you remember to turn on "Magic Dial" in the user preferences? This is a per user setting.
  2. Make sure that dialout.js is being included. View the source of the webpage and search for "dialout.js" see if it's included. If so, see if there are any javascript errors on the page.
  3. Jquery is used to find phone numbers on the page. It does this by looking for specific id's / classes depending on the version of sugar you are using... In version 6.1.1 pro, ID's were used. So, phone_work had id="phone_work", phone_other had id="phone_other" etc. As a result, the JQuery selectors are #phone_work,#phone_other,#phone_mobile,#phone_mobile_span.
In Sugar 6.4.1 pro, all the phone numbers in the detail views had the class "class=phone". The jquery selector for that is ".phone".

I don't know what is used in version 6.0 or 6.3 so perhaps it's something different. Check this by inspecting the HTML for the phone number and noting whether the number is surrounded by a span that has a useful class name or a id set. Then, make sure in dialout.js the appropriate selector is in the list on the line is like:

(&#39;&#35;phone_work,&#35;phone_office,&#35;phone_mobile&#39;)

If you have any 3rd party plugins installed, they could be changing the class the phone numbers are wrapped in. Two known integrations are: Letriums Quick Edit Detail View and IZeno SMS. Support for these two modules has been added. If you encounter a module which changes the class please post an issue so we can add it to the list of selectors.

Note: everything stated above only applies to the Detail Views. For list contact subpanels on Accounts pages, you may need to add some "customCode" in the meta data. This is discussed in the installation steps.

Click To Dial isn't working

Getting click to dial working has less dependencies then getting inbound call windows working. So, it's recommended that you attempt this first.

These are the dependencies:

  1. Asterisk AMI settings are configured properly.
  2. The Dial Command settings are wrong. The default is something like /SIP###, you may need to edit that.
  3. Dialout Prefix: If this isn't configured properly I would expect your local phone to ring but then you wouldn't get connected to the remote person.
  4. SELinux must be disabled. Fsockopen will fail in CreateCall.php. To determine if this is the problem follow the instructions below for how to debug in Chrome. You'll see an error message with Error Number 13 in it. Follow this procedure here to disable it: http://archives.ryandaigle.com/articles/2005/9/27/mythweb-howto-fix-fsockopen-function-fsockopen-unable-to-connect-to-127-0-0-1-6543-permission-denied-error
  5. Look on a Detail View of a Contact first, if they are appearing there but not in list views. See installation steps regarding Click To Dial Icons.
How to debug: Open up Chrome, right click on the page somewhere and do "Inspect Element". Then, click on the Network tab. After you click on the icon a new index.php call should popup (make sure you get the one for CallCreate instead of Listener as they'll popup every 5s or so also. In the response is the result of the AMI login and CreateCall request. So, you should be able to see a useful error message hopefully.

See Debugging With Chrome for a page with screenshots illustrating how to debug this.

Inbound Calls aren't being properly matched to a contact (Call window is appearing though)

  1. Check your dialin prefix. For example if the number is appearing as +1999-888-7777 but the contact's phone number in sugarcrm is 999-888-7777 you need to set your dialin_prefix as "+1".
  2. The wrong contact is being selected. In yaai v2.0, multiple contacts handling wasn't implemented. The logic selected the first matching number. You most likely have multiple contacts with the same phone number and it's picking the first one it finds. Version 2.3 and on handles this as outlined in the section on How are multiple contacts handled.
  3. Lastly, the problem could be soap isn't properly configured.

Calls aren't being assigned to the appropriate user.

  1. Make sure that all your users have an extension configured. If they don't, then they can't be assigned.
  2. If you have a custom dial plan, you might need to edit the regex for user extension matching. If you only have issues with Inbound calls and not outbound this is especially the case.
  3. To rule out whether or not the issue is logic built into sugar, run asteriskLogger.php with a test argument. Then, edit asteriskLogger.php... Search for: "test" and you should find an if condition like:
if( $argc &gt; 1 &amp;&amp; $argv&#91;1&#93; &#61;&#61; &quot;test&quot; )
You should be able to modify some of the function calls for extensions you know exist and see if they return the appropriate results.

I'm getting $ not defined or Jquery related errors

  1. Open up /custom/modules/Asterisk/include/AsteriskJS.php, then read the notes about conditionally including of javascript. Experiment by commenting/uncommenting the various jquery lines. See the Project TODO Page section on JQuery including.
Since Sugar 6.5, jquery is included by Sugar, so we don't include our own JQuery when we detect v6.5 or higher.

I'm getting "Call Record ID returned from server is -1" OR problem with SOAP

This is an issue with Asterisk Logger not having a working SOAP connection.

  1. Make sure you configured your SOAP user in the configuration
  2. When you start asteriskLogger.php a soap connection is attempted, review the output for error messages.
  3. Make sure you have the site_url parameter set properly in your config.php. The soap endpoint url it's trying to use is revealed in the log statements. Verify this url returns something.
  4. Finally, make sure the user has password requirements met. One user reported this was his problem.

I see PHP Warning: Attempt to modify property of non-object in /sugarcrm/include/nusoap/nusoap.php on line 6163

This warning can be ignored. It does not affect it's functionality.

SOAP all the sudden stopped working, I am now using SugarCRM 6.5

Note: This is only applicable to versions of yaai < 2.4

Prior to version 6.5, passwords were stored in the database as a MD5 Hash. The soap code would simply grab that hash and use it to login via soap. As of 6.5, passwords are now stored with crypt( md5( hash ) ) but when logging in through soap you still just provide MD5 hash (so their incompatible now).

But, if you upgraded from sugar 6.4 to sugar 6.5 the passwords aren't converted over to the new format until the user changes their password. So, one day a user is going to change his admin password and it's going to break yaai.

In version 2.4 we added the ability to specify the password in the Asterisk Configuration section since we can no longer take it out of the database.

Call Duration Isn't Computed Properly

This is caused by MySQL timezone being out of sync with the PHP timezone. Specifying the correct timezone in php.ini should fix this. See https://github.com/blak3r/yaai/issues/40#issuecomment-7208065

Thanks to @kerio-fstedronsky for finding this bug.

I upgraded yaai and now things don't work

Please read the Update instructions above. You probably need to do a quick repair and rebuild.

OTHER POTENTIAL ISSUES, UNCATEGORIZED

Clone this wiki locally