Friday, December 16, 2005

The Travails Of Using SMS Messaging To Communicate Server Downs

Recently, my company email servers have been flaky. It has been decided that we needed a way to communicate server downs to the IT staff so we can take corrective actions. The easiest way I could come up with was SMS messaging to our company cell phones. The only problem is that my company is cheap and SMS services that you can call programmatically cost money.

Perl came to the rescue yet again. I remembered that the T-Mobile website (our cell service provider) had a web page you could use to communicate with T-Mobile cellphones. You only needed an existing account setup on their site (with your mobile number and a password).

Armed with this knowledge I started using Samie and Win32::GuiTest to automate Internet Explorer to do the whole process automagically. Samie is a great package but it does have some issues. Some of the procedure calls do not work as expected. I've posted a modified version that works with my code at:

http://www.streamload.com/lamberms/Sam.pm

Anyway, here is the code solution to do SMS messaging. It comes in two parts, tmobile_sms.pl and kill_ie.pl. You call tmobile_sms.pl with five arguments, your T-Mobile cell phone number, account password, T-Mobile phone number to sms, from information and the message. It then automates IE to go to the T-Mobile web page, log in and send the message. When it is done doing this kill_ie.pl kills the popup the T-Mobile web site pops up (Samie does not do this well) and closes IE. Here is the tmobile_sms.pl code:

use Win32::OLE;
$Win32::OLE::Warn = 3;
use Win32::SAM;
$| = 1;
my $URL = "https://my.t-mobile.com/Communication/";
my $IEDocument;
my $seconds;
my $account_mobile_num = @ARGV[0];
my $account_mobile_pass = @ARGV[1];
my $mobilenum_to_page = @ARGV[2];
my $from_text = @ARGV[3];
my $msg_text = @ARGV[4];

if (@ARGV[0] eq "" || @ARGV[1] eq "" || @ARGV[2] eq "" || @ARGV[3] eq "" || @ARGV[4] eq "") {

       print "Invalid Command Used.  Command Should Be Formatted Like:\n";
print "tmobile_sms.exe your_cell_phone_num your_cell_phone_pass cell_phone_to_sms from_text msg_text\n";
exit;

}

StartIE();
$seconds = Navigate($URL);
print "First Page took $seconds seconds to load\n";
SetEditBox("txtMSISDN",$account_mobile_num);
SetEditBox("txtPassword",$account_mobile_pass);
ClickImage("https://my.t-mobile.com/images/mytmobile/ph/buttons/leftp.gif",0,1);
print "Second Page Loaded In $seconds.\n";
while (not VerifyTextPresent("SELECT A PHONE")) {

       print "Select A Phone Text Is Not Present\n";
sleep(1);

}
$seconds = Navigate($URL,0,1);
print "Third Page Took $seconds seconds\n";
while (not VerifyTextPresent("Characters left")) {

       print "Characters left Text Is Not Present\n";
sleep(1);

}
SetEditBox("txtNum","$mobilenum_to_page");
SetEditBox("txtFrom","$from_text");
SetEditBox("txtMessage","$msg_text");
$seconds = ClickImage("https://my.t-mobile.com/images/mytmobile/ph/buttons/left.gif",0,1);
if (-e ".\\kill_ie.exe") {
exec(".\\kill_ie.exe");
}

if (-e ".\\kill_ie.pl") {
exec(".\\kill_ie.pl");
}
exit;

And here is the kill_ie.pl code:

use Win32::GuiTest;

$| = 1;
my @windows = ();
my $time_counter = 0;
while ($#windows == -1 && $time_counter < 121) {

     @windows = Win32::GuiTest::FindWindowLike( undef, "^Microsoft Internet Explorer", "","",5 );
$time_counter++;
print "Looking For Popup Window\n";
Win32::Sleep(1000);

}

if ($time_counter == 120) {

     print "FAILURE Finding Microsoft Internet Explorer Window!!!!\n";
exit;

}

else {

if ( !bring_window_to_front( $windows[0] ) ) {

print "* Could not bring to front $window[0]\n";
}

     my @enterbutton = Win32::GuiTest::FindWindowLike( undef, "OK", "Button" );
if ($#enterbutton > -1) {
#Click OK Button
Win32::GuiTest::SendKeys("~",1);
Win32::GuiTest::SendKeys("%({F4})");
print "Clicking OK Button\n";
exit;
}
else {
print "Could Not Click Enter Button\n";
exit;
}

}

exit;

sub bring_window_to_front {


my $window = shift;
my $success = 1;
if ( Win32::GuiTest::SetActiveWindow($window) ) {
print "* Successfully set the window id: $window active\n";
}
else {
print "* Could not set the window id: $window active\n";
$success = 0;
}
if ( Win32::GuiTest::SetForegroundWindow($window) ) {
print "* Window id: $window brought to foreground\n";
}
else {
print "* Window id: $window could not be brought to foreground\n";
$success = 0;
}
return $success;

}

No comments: