Showing posts with label Google Talk. Show all posts
Showing posts with label Google Talk. Show all posts

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;
}
}