Dans la structure dans laquelle je travaille nous disposons d’un outil type CRM développé sur mesure (PHP/SQL). D’un autre côté nous utilisons avec bonheur depuis plusieurs années Kerio Connect comme solution de Groupware (mails, calendriers, carnets d’adresse).
L’intégration de Kerio (via le protocole Exchange) sur les terminaux mobiles est parfaite et nous trouvions dommage de ne pas pouvoir utiliser le répertoire “Public” de Kerio pour pouvoir accéder en consultation aux coordonnées de contacts de notre CRM.
Précisons en plus Kerio est hébergé sur un Mac OS X Server 10.6 et que notre CRM tourne sur un Debian Squeeze.
Pour réaliser cela nous sommes partis sur le principe :
1. D’un script PHP sur le serveur hébergeant le CRM qui réalise un export de la totalité des contacts en VCard v3 (ce script sera appelé périodiquement via curl).
2. D’un script lancé périodiquement sur l’OS X Server hébergeant Kerio Connect. Ce script (appelé via un LaunchDaemons) est chargé :
- De générer à distance les VCards (via le script PHP appelé par curl évoqué plus haut)
- De télécharger ce fichier VCards (toujours grace à curl)
- De traiter ces VCards en les découpant, puis en générant des fichiers .eml contenant les informations de contact (pour cette partie j’ai réutilisé un script trouvé ici http://aplawrence.com/Kerio/webmail_import_contacts.html que j’ai un peu modifié). N’étant pas un as de Perl j’ai choisi d’appeler ce script modifié depuis mon script shell. Je sais, c’est pas ultra propre pour les puristes … mais ça marche.
- Le tout en enregistrant une liste des modifications et en générant des journaux pour pouvoir débugger le cas échéant …
- Pour finir, on force la réindexation du répertoire public de Kerio Connect en supprimant le fichier d’index et en redémarrant en ligne de commande Kerio.
Voici donc le script shell qui réalise la majorité du travail (certaines parties sont à adapter évidemment si vous souhaitez le réutiliser ….) :
#!/bin/sh CURRENT_DIR=$(dirname $0); INPUT="$CURRENT_DIR/tmp/bdd-vcard-avec-liens.vcf"; INPUT_REVIEW="$CURRENT_DIR/tmp/bdd-vcard-avec-liens2.vcf"; OUTPUT_TEMP_DIR="$CURRENT_DIR/out-temp"; LAST_FILE="$CURRENT_DIR/lastfile.tmp"; LOG="$CURRENT_DIR/current.log"; LOG_CUMUL="/var/log/Kerio_import_vCards.log"; LAST_FILE_LIST="$CURRENT_DIR/lastlist.tmp"; OLD_VCARDS="$CURRENT_DIR/old-vCards"; ## Le script qui sera intercalé en Perl SCRIPT_PERL_EXPORT="$CURRENT_DIR/export.pl"; KERIO_PUBLIC_STORE="/usr/local/kerio/mailserver/store/mail/XXXXXXXXXXX/#public/Contacts"; OUTPUT_DIR="$KERIO_PUBLIC_STORE/#msgs"; MAIL_ADMIN="moi@moi.moi"; DATE_DU_JOUR=$(date); if [ `whoami` != 'root' ] then echo "Ce script doit être utilisé par le compte root. Utilisez SUDO." exit 1 fi rm -f $LOG echo " " >> $LOG echo "****************************** $DATE_DU_JOUR ******************************" >> $LOG #testons si une connection internet est ouverte { } curl -f http://checkip.dyndns.org ERROR=$(echo $?) if [ $ERROR -ne 0 ] then echo "ERROR checkip.dyndns.org : " $ERROR >> $LOG echo "Non connecté à internet. Nous quittons le script." >> $LOG exit 0 else # générons le vCard sur le site distant http://XXXXXXXXX.php cd $CURRENT_DIR; curl -k https://www.test.fr/bdd-vcard.php?liens; ## adresse du script distant sur le CRM permettant de générer un export au format VCARD. # récupérons le fichier généré dans un répertoire temporaire mkdir $CURRENT_DIR/tmp; cd $CURRENT_DIR/tmp; rm -f $INPUT; rm -f $INPUT_REVIEW; curl -O -k https://www.test.fr/bdd-vcard-avec-liens.vcf; # supprimons par sécurité les lignes vierges dans le fichier généré sed '/^$/d' $INPUT > $INPUT_REVIEW mv $INPUT_REVIEW $INPUT # testons si un import a déjà été réalisé # testons si une liste de fichier existe / return-code = 1 si fichier absent test -f $LAST_FILE_LIST RETURN_CODE=$? PREVIOUS_IMPORT=0 if [ $RETURN_CODE -eq 1 ] then echo "Pas de précédent import détecté" >> $LOG else VAR=`wc -w $LAST_FILE_LIST | awk '{print $1}'` if [ "$VAR" -eq 0 ] then echo "Pas de précédent import détecté" >> $LOG else PREVIOUS_IMPORT=1 echo "Une précédente importation a été trouvée" >> $LOG # récupérons les noms des vCardS importées lors du précédent import # déplacons les vCard importées lors du précédent import réussi dans le fichier old # par précaution vidons le avant tout rm -R $OUTPUT_TEMP_DIR; cd $CURRENT_DIR; rm -R $OLD_VCARDS; mkdir $OLD_VCARDS; cd $OUTPUT_DIR; for FILE in $(cat $LAST_FILE_LIST); do mv "$FILE" $OLD_VCARDS/ ; done fi fi # comptons et listons les fiches vCard encore présentes et plaçons le dernier nom dans un fichier $LAST_FILE NBFILE=$(ls -A1 $OUTPUT_DIR/*.eml | wc -l); echo "Il y a actuellement " $NBFILE " contacts dans le répertoire PUBLIC CONTACTS de Kerio" >> $LOG; cd $OUTPUT_DIR; LISTE=$(ls -A1 *.eml); echo "Liste des fichiers présents (hors dernier import) : " $LISTE >> $LOG; LAST=${LISTE: -12}; echo "Le dernier contact porte le nom suivant : " $LAST >> $LOG; LAST_NAME=$(echo $LAST | cut -d"." -f1); # écriture dans un fichier tmp $LAST_FILE du nom du dernier fichier à ne pas écraser # par précaution écrasons le fichier de passage avant d'écrire dedans rm -f $LAST_FILE; echo $LAST_NAME > $LAST_FILE; # comptons le nombre de fiches vCard à importer TEST_GREP=$(grep -c "BEGIN:VCARD" ${INPUT}) TEST_GREP2=$(grep -c "END:VCARD" ${INPUT}) if [ $TEST_GREP -gt $TEST_GREP2 ] then NUMBER=$TEST_GREP else NUMBER=$TEST_GREP2 fi # lançons le script Perl qui exporte le vCard en fichiers eml séparés # préparons le répertoire temp mkdir -p $OUTPUT_TEMP_DIR; /usr/bin/perl "$SCRIPT_PERL_EXPORT"; RETURN_CODE_PERL=$? echo "Code retour PERL : $RETURN_CODE_PERL" >> $LOG; if [ $RETURN_CODE_PERL -eq 0 ] then echo "Pas de problème détecté lors de la création des fichiers vCards en .eml." >> $LOG # enregistrons la liste des fichiers importés dans notre fichier $LAST_FILE_LIST # par précaution supprimons le avant cd $OUTPUT_TEMP_DIR; LISTE2=$(ls -A1 *.eml); rm -f $LAST_FILE_LIST; echo $LISTE2 > $LAST_FILE_LIST; # déplaçons les fichiers créés dans le répertoire STORE PUBLIC de KERIO cd $OUTPUT_TEMP_DIR for FILE in $(cat $LAST_FILE_LIST); do mv "$FILE" $OUTPUT_DIR/ ; done # réindexons le répertoire STORE PUBLIC de KERIO rm -f $KERIO_PUBLIC_STORE/index.bad mv $KERIO_PUBLIC_STORE/index.fld $KERIO_PUBLIC_STORE/index.bad /usr/local/kerio/mailserver/KerioMailServer stop sleep 60 /usr/local/kerio/mailserver/KerioMailServer start sleep 60 # enregistrons la trace dans le LOG DATE_DU_JOUR=$(date) DEBUT_LOG=$(echo "$NUMBER vCards importées avec succès le ") echo $DEBUT_LOG $DATE_DU_JOUR echo $DEBUT_LOG $DATE_DU_JOUR >> $LOG; cat $LOG | mail -s "[OK] Rapport execution script import vCards (${0})" $MAIL_ADMIN cat $LOG >> $LOG_CUMUL rm -f $LAST_FILE exit 0; else echo "Problème détecté : l'import des vCards n'est pas effectué correctement." >> $LOG if [ $PREVIOUS_IMPORT == "1" ] then echo "Nous vidons le répertoire temporaire du Script et déplaçons à nouveau les fichiers pour rétablir le STORE PUBLIC de KERIO." >> $LOG cd $OLD_VCARDS; for FILE in $(cat $LAST_FILE_LIST); do mv "$FILE" $OUTPUT_DIR/ ; done ; rm -R $OLD_VCARDS; fi # gardons une trace de l'erreur dans les logs DATE_DU_JOUR=$(date) DEBUT_LOG=$(echo "Les $NUMBER vCards n'ont pas été importées correctement le ") FIN_LOG=$(echo " - Code d'erreur : ") echo $DEBUT_LOG $DATE_DU_JOUR echo $DEBUT_LOG $DATE_DU_JOUR $FIN_LOG $RETURN_CODE_PERL >> $LOG; cat $LOG | mail -s "[FAILED] Rapport ERREUR script import vCards (${0})" $MAIL_ADMIN cat $LOG >> $LOG_CUMUL # petit nettoyage avant de terminer rm -R $CURRENT_DIR/tmp; rm -R $OUTPUT_TEMP_DIR; rm -f $LAST_FILE; exit 1; fi fi
Côté Perl, le script qui découpe notre VCARD est le suivant :
#!/usr/bin/perl $CURRENT_DIR="/usr/local/Kerio_import_vCards"; $INPUT="$CURRENT_DIR/tmp/bdd-vcard-avec-liens.vcf"; $OUTPUT_TEMP_DIR="$CURRENT_DIR/out-temp"; $LAST_FILE="$CURRENT_DIR/lastfile.tmp"; my $FILE=$LAST_FILE; open(FIC,$FILE) or exit(1); $LIGNE=<FIC>; chop($LIGNE); $DECVAL= hex($LIGNE); $VALEUR = sprintf("%u", $DECVAL); $X=$VALEUR+1; open(I,$INPUT); writefile(); while (<I>) { chomp; $NOMHEXA=sprintf "%0.8x.eml\n",$X; print "Création du fichier contact $X : $NOMHEXA"; if (/^END:VCARD/) { print O "$_\n"; close O; $X++; writefile() if not eof(I); next; } print O "$_\n"; } sub writefile { $OFILE=sprintf "%0.8x.eml\n",$X; open(O,">$OUTPUT_TEMP_DIR/$OFILE"); print O <<EOF; Subject: Date: Sun, 25 Mar 2012 11:29:38 -0400 Content-Type: text/vcard; charset="utf-8" Content-Transfer-Encoding: 8bit EOF } exit(0);