After much hacking and trial and error I created this PHP script, runnable from the shell, to import a user's address book.
I tested this with our own installation and it works. All you need is to have PHP CLI available, compiled with CURL.
For linux systems might be necessary to change the first line to: #!/usr/bin/php
Use it like this:
./import-to-zimbra.php username password csvfile.csv zimbra.domain.com
Output looks like this:
PHP Code:
Getting Auth Key
- Success. Auth Token: 0_2ab13ad27196762b.....8303b
Uploading CSV File [ csvs/emailtest.csv ]
- Done. AID: a9c937fe-485f-4cee-8abb-f50398342295:a55aacab-62c3-42ee-b4c9-e1ab39bd9480
Sending SOAP Request to Import Contacts...
- Done
Have fun!
PHP Code:
#!/usr/local/bin/php
<?php
/*********************************
* Work around code to import .csv address books into Zimbra 5.0.2
*
* Date : March 20, 2008
* Author: Benson Wong
* email: benwong@sutton.com
* web: http://www.mostlygeek.com
*********************************/
$username = $argv[1];
$password = $argv[2];
$csvfile = $argv[3];
$server = $argv[4];
if (!file_exists($csvfile)) {
print_die_usage("CSV File: $csvfile does not exist");
}
if (!$server) {
print_die_usage("Server name missing");
}
$url = "https://$server/service/soap";
// Get the AUTH Key
echo "Getting Auth Key \n";
$SOAPMessage = sprintf('<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header><context xmlns="urn:zimbra"/></soap:Header>
<soap:Body><AuthRequest xmlns="urn:zimbraAccount">
<account by="name">%s</account>
<password>%s</password>
</AuthRequest></soap:Body></soap:Envelope>',$username,$password);
$CurlHandle = GetCurlHandler($url);
curl_setopt($CurlHandle, CURLOPT_POSTFIELDS, $SOAPMessage);
if(!($ZimbraSOAPResponse = curl_exec($CurlHandle))) {
print("ERROR: curl_exec - (" . curl_errno($CurlHandle) . ") " . curl_error($CurlHandle));
}
if (strstr($ZimbraSOAPResponse,'AUTH_FAILED'))
die(" - ERROR: Authentication Failed\n");
$auth_token = ereg_replace('^.*<authToken>','',$ZimbraSOAPResponse);
$auth_token = ereg_replace('</authToken>.*$','',$auth_token);
echo ' - Success. Auth Token: '. substr($auth_token,0,18) . '.....' . substr($auth_token,-5)."\n";
// upload the file
echo "Uploading CSV File [ $csvfile ] \n";
$cmd = "curl -u $username:$password --header \"Content-Type: text/csv; name=$username.csv\" "
."--header \"Cookie: ZM_AUTH_TOKEN=$auth_token\" "
."--data-binary @$csvfile \"https://$server/service/upload?fmt=raw\" 2>/dev/null";
$resp = `$cmd`;
$resp = str_replace("'",'',$resp);
$aid = array_pop(explode(',',$resp));
$aid = trim($aid);
echo " - Done. AID: $aid \n";
$SOAPMessage = sprintf('<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap:Header>
<context xmlns="urn:zimbra">
<authToken>%s</authToken>
</context></soap:Header><soap:Body>
<ImportContactsRequest ct="csv" xmlns="urn:zimbraMail">
<content aid="%s"/>
</ImportContactsRequest>
</soap:Body></soap:Envelope>',$auth_token,$aid);
echo "Sending SOAP Request to Import Contacts... \n";
$CurlHandle = GetCurlHandler($url);
curl_setopt($CurlHandle, CURLOPT_POSTFIELDS, $SOAPMessage);
curl_setopt($CurlHandle, CURLOPT_USERPWD,"$username:$password" );
if(!($ZimbraSOAPResponse = curl_exec($CurlHandle))) {
print("ERROR: curl_exec - (" . curl_errno($CurlHandle) . ") " . curl_error($CurlHandle));
}
echo " - Done\n";
/**** FUNCTIONS ****/
function GetCurlHandler($url,$verbose=0) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
if ($verbose)
curl_setopt($ch, CURLOPT_VERBOSE,1);
return $ch;
}
function print_die_usage($message = '') {
global $argv;
echo "Error: $message\n";
echo "Usage: $argv[0] username password csvfilename server\n";
echo " example: $argv[0] emailtest PassWord944 emailtest.csv zimbra.domain.com\n";
die();
}