Thursday 31 May 2012

Google Talk add users to roster via Perl

Since we started moving to Google Apps we're having to manually add all other users in our corporation to our Google Talk roster. This is a nuisance for our users especially at the beginning as there is a large number of users that need to be added.


Thanks to Perl and a few modules from CPAN it shouldn't be that hard to get around this issue. I've got a spreadsheet with usernames and passwords in the following format from our initial setup.


"username@domain.com","123password","John Smith"


The script below will add all of those email addresses to each others rosters.



#!/usr/bin/perl
#

use Text::CSV;
use Net::XMPP;
use Data::Dumper;
use warnings;

my $config;
$config->{'resource'} = 'perl';
$config->{'debug'} = 1;
$config->{'company name'} = "Company";

my @accounts;
my $file = $ARGV[0];
if ( !$file ) {
print
"Call this script as shown: add_xmpp_contacts.pl email_accounts.csv.\n";
print "The format of the csv script shall be as follows:\n";
print '"username1@domain.com","password1","John Doe"' . "\n";
print '"username2@domain.com","password2","John Smith"' . "\n";
exit(0);
}

my $csv = Text::CSV->new();
open( CSV, "<", $file ) or die $!;
while (<CSV>) {
if ( $csv->parse($_) ) {
my @columns = $csv->fields();
print "USERNAME: " . $columns[0] . "\n";
my $account->{username} = $columns[0];
$account->{display} = $columns[2];
push( @accounts, $account );
}
else {
my $err = $csv->error_input;
print "Failed to parse line: $err";
}
}
close CSV;

open( CSV, "<", $file ) or die $!;
while (<CSV>) {
if ( $csv->parse($_) ) {
my @columns = $csv->fields();
if ( $config->{'debug'} == 1 ) {
print "USERNAME: " . $columns[0] . "";
print "PASSWORD: " . $columns[1] . "\n";
}
else {
print "USERNAME: " . $columns[0] . "\n";
}
&dump_data( $columns[0], $columns[1], @accounts );
}
else {
my $err = $csv->error_input;
print "Failed to parse line: $err";
}
}
close CSV;

##############################################################################
# Subroutines, don't touch unless you know what you're doing.
##############################################################################

sub dump_data() {
my ( $email, $password, @accounts ) = @_;
my ( $username, $domain ) = split( /\@/, $email );
print "Connecting for " . $username . "\n";
my $Connection = new Net::XMPP::Client();

# Connect to talk.google.com
my $status = $Connection->Connect(
hostname => 'talk.google.com',
componentname => $domain,
port => 5222,
tls => 1
);

if ( !( defined($status) ) ) {
print "ERROR: XMPP connection failed.\n";
print " ($!)\n";
exit(0);
}
else {
print "Connected\n";
}

# Change hostname
my $sid = $Connection->{SESSION}->{id};
$Connection->{STREAM}->{SIDS}->{$sid}->{hostname} = 'gmail.com';

# Authenticate
$Connection->AuthSend(
username => $username,
password => $password,
resource => $config->{'resource'}
);

if ( $Connection->Connected() == 0 ) {
print "ERROR: Authorization failed: $res - $msg\n";
exit(0);
}
else {
print "Connected OK for " . $username . "\n";
}
$Connection->PresenceSend( show => 'available' );
my $Roster = $Connection->Roster();
my %userlist;
my %roster = $Connection->RosterGet();
print Dumper( \%roster ) if $config->{'debug'} == 1;
while ( my ( $id, $data ) = each %roster ) {
print "ID: "
. $id . " '"
. $data->{'name'}
. "' Groups: '"
. @{ $data->{groups} } . "'\n"
if $config->{'debug'} == 1;
$userlist->{$id} = 1;
}
print Dumper($userlist) if $config->{'debug'} == 1;
foreach my $contact (@accounts) {
print "Checking: "
. $contact->{display} . " "
. $contact->{username} . "\n";
if ( exists $userlist->{ $contact->{username} } ) {
print "Already Exists: " . $contact->{display} . "\n";
}
else {
print "Adding: " . $contact->{display} . "\n";
$Connection->Roster->add(
jid => $contact->{username},
name => $contact->{display},
groups => []
);
$Connection->Subscription(
type => "subscribe",
to => $contact->{username}
);
}
sleep 1;
}
}



1 comment:

  1. We use google apps in my company.We want to use gtalk for internal chat but I don't like how gtalk use the roster user.Every user must invite to another to start chatting.I would like to have a roster syncing with google directory user or LDAP so when you set up a gtalk user in pidgin automatically sync with this roster so users dont need to invite all the time.Can I use this script for that? Thanks

    ReplyDelete