During development of our recently launched invite your friends referral system, we looked at many different options for importing contacts. The first contact importer we tried was OpenInviter, it’s free and supports many different email providers, or is supposed to; importing from some of the most popular providers didn’t even work on their own site! So OpenInviter was out and we started looking at alternatives.
CloudSponge
Diagram showing the process of importing contacts through Cloudsponge
We couldn’t find any free alternatives, so we decided on Cloudsponge because although they don’t support as many email providers as OpenInviter, they support the biggest ones, as well as having other nice features like using Oauth for gmail/yahoo/hotmail and including an applet for importing from Outlook or Mac address book. Another nice thing about Cloudsponge is they have an affordable monthly payment option, where other services will charge you $200+ and only provide 6 months to a year of updates, which afterwards you would then have to buy it again if it stopped working. Cloudsponge has an option for just $25/month, updates included, and they even include 1 month free!
Cloudsponge offers a widget that you can just copy and paste onto your site, but it didn’t match the design we had in mind, so we used their php api, which is open source, so you can check it out without paying anything.
HiretheWorld uses CodeIgniter as its php framework, so I created a simple interface library for CodeIgniter to access the Cloudsponge api; the functions aren’t entirely necessary, but I added them to simplify the output.
<? /** * Interface for gathering a users contacts using CloudSponge * **/ require_once 'cloudsponge/csimport.php'; class CloudSponge extends CSImport { /** * Constructor * * @access public * */ public function __construct() { } /** * requestContacts * Starts the process of gathering contacts from cloudsponge * * @param string $service The service to use(gmail/yahoo/windowslive/aol/plaxo/outlook/addressbook) * @param string $username The username to use, only needed for aol/plaxo * @param string $password The password to use, only needed for aol/plaxo * * @return array Response from cloudsponge, containing an import-id, consent_url applet tag and/or error message **/ public function requestContacts($service, $username, $password) { $output = $this->begin_import($service, $username, $password, NULL); if (isset($output['import_id'])) { $result['import'] = $output['import_id']; if (!is_null($output['consent_url'])) { $result['url'] = $output['consent_url']; } else if (!is_null($output['applet_tag'])) { $result['applet'] = htmlspecialchars($output['applet_tag']); } } return $result; } /** * importContacts * Attempts to get contacts from cloudsponge * * @param int $import_id the import id to use to request contacts from cloudsponge * * @return mixed Returns an array of contacts, or an error message **/ public function importContacts($import_id) { if(empty($import_id)) { return 'Invalid import id'; } $status = $this->get_events($import_id); foreach ($status as $state) { if($state['status']=='ERROR') { return $state['description']; } if($state['event_type'] == "COMPLETE" && $state['status'] == "COMPLETED" && $state['value'] == 0) { return $this->get_contacts($import_id); } } return 'An error has occured.'; } } ?> |
I then added functions in the controller that use the functions from the library.
The basic process of importing contacts from code igniter is:
Create a contact request from Cloudsponge, providing the service to retrieve from and a username/password if needed.
This will return an import id as well as a consent/login page url that the user must fill out for Oauth services or an applet code snippet for Outlook or Mac address book.
Poll Cloudsponge’s server using the import id from the previous step in javascript for the status of the import, once it is complete, continue to the next step.
There are 3 stages to this: initializing, gathering and completion. Each stage could possibly have errors, so you need to check for them. One difficulty I had was how to tell if the user closed the consent window for an Oauth service. I solved this by creating a timeout after the popup was closed and if the status was still not ‘gathering’, abort the process.
Grab the contact list from Cloudsponge.
Here is the controller function I made to check the status, it’s called through ajax using jQuery:
/** * getImportStatus * Returns the current import status from cloudsponge * * @param int $import_id the import id to use to request contacts from cloudsponge * * @return prints out json encoded response of the current status from cloudsponge **/ public function getImportStatus($import_id) { if(empty($import_id)) { $this->load->view('ajax-response', array('data' => json_encode(array('state'=>'no import id')))); return; } $this->load->library('cloudsponge'); $status = $this->cloudsponge->get_events($import_id); if(empty($status)) { $this->load->view('ajax-response', array('data' => json_encode(array('state'=>'no update')))); return; } $gathering = false; foreach ($status as $state) { if($state['status']=='ERROR') { $this->load->view('ajax-response', array('data' => json_encode(array('state'=>'error')))); return; } if($state['event_type'] == "COMPLETE" && $state['status'] == "COMPLETED" && $state['value'] == 0) { $this->load->view('ajax-response', array('data' => json_encode(array('state'=>'complete')))); return; } elseif(($state['event_type']=='GATHERING') || ($state['event_type']=='INITIALIZING' && $state['status'] == "COMPLETED")) { $gathering = true; } } if($gathering) $this->load->view('ajax-response', array('data' => json_encode(array('state'=>'gathering')))); else $this->load->view('ajax-response', array('data' => json_encode(array('state'=>'initializing')))); return; } |
You can see this all in action in our invite your friends feature. If anyone has any questions about this, just ask and I’ll do my best to help you out!

