ちょこちょこいじってGmaiの連絡先メールアドレスをLDAPに取り込むPerlスクリプト完成\(^o^)/
なかったのでこんな感じでつくったのだ。
#!/usr/bin/perl
use strict;
use utf8;
use LWP::UserAgent;
use HTTP::Request::Common;
use URI::Escape;
use XML::Simple;
use Net::LDAP;
use Time::Piece;
#XML::Simpleのエラー回避
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
#アプリケーション設定
my $uid_prefix = 'Gmail_';
#Googleアカウント情報
my $gdata_user = 'あなた@gmail.com';
my $gdata_pass = 'あなたのパスワード';
#UserAgent設定
my $ua = LWP::UserAgent->new();
my ( $req, $res, $url );
#LDAP設定
my $ldap_server = 'example.com';
my $base_dn = 'dc=example, dc=com';
my $root_cn = 'cn=Manager';
my $root_passwd ='LDAP管理者パスワード';
my $secure = 1; #LDAPSの場合:1
#LDAP接続
my ( $ldap_scheme, $ldap_port );
if( $secure ){
$ldap_scheme = 'ldaps';
$ldap_port = 636;
}
else{
$ldap_scheme = 'ldap';
$ldap_port = 389;
}
my $ldap = Net::LDAP->new( $ldap_server, port => $ldap_port, scheme => $ldap_scheme, );
unless( $ldap ){
print &now, "LDAP server connect failed.\n";
die "LDAP server connect failed.\n";
}
#LDAPログイン
my $ldap_msg = $ldap->bind( "$root_cn, $base_dn", password => $root_passwd );
if( $ldap_msg->code ){
print &now, "LDAP account login failed.\n";
die "LDAP account login failed.\n";
}
print &now, "LDAP server logined.\n";
#登録中uidを検索→削除
{
my $filter = "(uid=$uid_prefix*)";
$ldap_msg = $ldap->search( base => $base_dn, filter => $filter );
if( $ldap_msg->code ){
print &now, "uid search failed.\n";
die "uid search failed.\n";
}
foreach my $entry ( $ldap_msg->entries ){
my $uid = $entry->get_value( 'uid' ),"\n";
my $delete_dn = "uid=$uid, ou=People, " . $base_dn;
$ldap_msg = $ldap->delete( $delete_dn );
if( $ldap_msg->code ){
print &now, "uid:$uid delete failed.\n";
die "uid:$uid delete failed.\n";
}
}
print &now, "All old entries deleted.\n";
}
#Googleアカウントにログイン
{
$url = 'https://www.google.com/accounts/ClientLogin';
my %post_data = (
'Email' => $gdata_user,
'Passwd' => $gdata_pass,
'accountType' => 'GOOGLE',
'source' => 'Google-Contact-Lister',
'service' => 'cp',
);
$req = POST( $url, [ %post_data ] );
$res = $ua->request( $req );
}
#セッション・承認情報取得
my %session;
foreach my $line ( split( /\n/, $res->content ) ){
my ( $key, $data ) = split( /=/, $line );
$session{ $key } = $data;
}
#ログイン成功確認
unless( $session{ 'Auth' } ){
print &now, "Google account login failed.\n";
die "Google account login failed.\n";
}
print &now, "Google account logined.\n";
{
#Google Acontact APIの検索設定
my $index = 1;
my $paging = 100; # 2以上に設定すること
my $total_results;
my $add_count = 0;
do {
$url = 'https://www.google.com/m8/feeds/contacts/' .
uri_escape( $gdata_user ) .
"/full?start-index=$index&max-results=$paging";
$req = GET( $url );
$req->header( Authorization => "GoogleLogin auth=$session{ 'Auth' }" );
$res = $ua->request( $req );
my $xml_parser = XML::Simple->new();
my $parsed_data = $xml_parser->XMLin( $res->content );
$total_results = $parsed_data->{ 'openSearch:totalResults' };
foreach my $key ( keys( %{ $parsed_data->{ 'entry' } } ) ){
#Google Acontactのデータパース
my $uid = $uid_prefix . ( split( /\//, $key ) )[-1];
my $common_name = $parsed_data->{ 'entry' }{ $key }{ 'title' }{ 'content' };
my ( $surname, $given_name ) = split( / /, $common_name );
#email複数対応
my @email_list;
my $elem = $parsed_data->{ 'entry' }{ $key }{ 'gd:email' };
#エントリーが1つだけの時
if ( $elem =~ /^HASH/ ){
push( @email_list, $elem->{ 'address' } );
}
#エントリーが複数の時
elsif( $elem =~ /^ARRAY/ ){
foreach my $temp ( @$elem ){
push( @email_list, $temp->{ 'address' } );
}
}
my $suffix = 1;
foreach my $email ( @email_list ){
#LDAP操作
my $uid_s = $uid . "_$suffix";
my $add_dn = "uid=$uid_s, ou=People, " . $base_dn;
if( $email ne '' ){
my %attrs = (
'uid' => $uid_s,
'cn' => $common_name,
'sn' => $surname,
'objectClass' => [ 'inetOrgPerson', 'top', ],
'mail' => $email,
'description' => "Gmail to LDAP uid: $uid_s",
);
if( $given_name ne '' ){
$attrs{ 'givenName' } = $given_name;
}
$ldap_msg = $ldap->add( $add_dn, attrs => [ %attrs ] );
if( $ldap_msg->code == 0 ){
$add_count++;
}
}
$suffix++;
}
}
$index += $paging;
} while( $index unbind;
print &now, "Operation completed.\n";
sub now{
my $now = Time::Piece::localtime();
return '[' . $now->strftime('%Y-%m-%d %H:%M:%S') . '] ';
}
機能的には電話番号とか住所も取り込んだり、双方向でデータのやりとりができるといいかな?