Created
October 9, 2013 13:32
-
-
Save ogarrett/6901360 to your computer and use it in GitHub Desktop.
Stingray SMS gateway - see https://splash.riverbed.com/community/product-lines/stingray/blog/2012/06/29/receiving-sms-alerts-from-stingray-traffic-manager-01072009. Original code by Andy Knox
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
use warnings; | |
use strict; | |
use Getopt::Long; | |
sub uri_escape( $ ); | |
# Default country code to add to phone numbers that start with | |
# a 0 so the SMS gateway will accept them. | |
my $country_code = "+44"; # UK | |
my $usage = "Usage: sendsms.pl --destination=telno[,telno...] [--eventtype=<eventtype>] [--debug] message"; | |
my( $destination, $eventtype, $help, $debug ); | |
GetOptions( | |
'help|h|?' => \$help, | |
'destination=s' => \$destination, | |
'eventtype=s' => \$eventtype, | |
'debug=s' => \$debug, | |
) or die "\nInvalid arguments.\n\n$usage\n"; | |
my $message = shift @ARGV; | |
if ( !$message || $help ) { | |
print "\n$usage\n"; | |
exit 0; | |
} | |
my @destinations = split ',', $destination; | |
# Numbers must be in country code format | |
for( my $i=0; $i < scalar @destinations; $i++ ) { | |
$destinations[$i] =~ s/^\s+//; | |
$destinations[$i] =~ s/^0/$country_code/; | |
die "Invalid destination: ".$destinations[$i] unless $destinations[$i] =~ /^\+\d+/; | |
} | |
# Join the numbers back up for the SMS Gateway | |
$destination = join ',', @destinations; | |
# Create the content of the SMS message | |
my @alert = split "\t", $message; | |
if( scalar @alert > 2 ) { | |
# Looks like a ZXTM event message - format it... | |
# Message format: | |
# Event Type: | |
# INFO: | |
# section/object | |
# primary tag | |
# additional tags | |
# | |
# message | |
my $alerttext = pop @alert; | |
# Get the error level | |
$message = " ".(shift @alert).":\n"; | |
# Get the other information - the section, | |
# primary tag and additional tags. This could | |
# be improved to only include information that | |
# is useful to see in a text message for each | |
# event that can trigger this program to be run. | |
foreach my $object( @alert ) { | |
$message .= " $object\n"; | |
} | |
# Add the description of the event | |
$message .= "\n$alerttext"; | |
} | |
# Add the event type that triggered this program to the message. | |
$message = $eventtype.": ".$message if $eventtype; | |
# The URL of the SMS Gateway. | |
my $url = "http://ws.textanywhere.net/HTTPRX/SendSMSEx.aspx"; | |
# Parameters to send to the gateway... | |
my %params = ( Client_ID => "AB1234567", | |
Client_Pass => "password", | |
Client_Ref => "my_company", | |
Billing_Ref => "zxtm", | |
Connection => $debug ? 1 : 2, | |
Originator => "ZXTM", | |
OType => 1, | |
DestinationEx => $destination, | |
Body => "$message", | |
SMS_Type => 0, | |
Reply_Type => 0 | |
); | |
my $body = ""; | |
# URL encode the parameters | |
foreach my $param( keys %params ) { | |
$body .= "&" if $body; | |
$body .= uri_escape($param)."=".uri_escape($params{$param}); | |
} | |
# Send the request | |
my $httpclient = $ENV{ZEUSHOME}."/admin/bin/httpclient"; | |
open FH, "echo '$body' | $httpclient -m POST $url |" or die "Could not execute httpclient: $!"; | |
# Get the response | |
my $responseline = <FH>; | |
if( !$responseline ) { | |
die "SMS Send failed: Could not execute $httpclient or no response received from remote server"; | |
} | |
my $responsecode = $1 if $responseline =~ /^HTTP\/1\.1 (\d+)/; | |
if( $responsecode && $responsecode == 200 ) { | |
# Gateway successfully receieved the request... | |
my %responses = ( | |
1 => "SMS Sent", | |
2 => "Authentication failed: Account not found", | |
22 => "Authentication failed: Account is currently suspended", | |
3 => "SMS failed", | |
31 => "SMS failed: Insufficient message credits on your account", | |
311 => "SMS failed: This Connection does not exist", | |
32 => "SMS failed: Originator format not recognised", | |
321 => "SMS failed: OType invalid", | |
33 => "SMS failed: Destination(s) format not recognised", | |
34 => "SMS failed: Reply_Type invalid or Reply_Data empty", | |
35 => "SMS failed: Client_Ref too long or empty (maximum 50 characters)", | |
36 => "SMS failed: Billing_Ref too long or empty (maximum 50 characters)", | |
37 => "SMS failed: Body too long or empty (maximum 160 characters)", | |
38 => "SMS failed: Wrong message type", | |
39 => "SMS failed: Wrong message encoding" | |
); | |
# Skip the headers | |
while( <FH> ) { | |
last if /^\r\n/; | |
} | |
my $codes_received = 0; | |
# We're at the body data... | |
while( <FH> ) { | |
# Get the return codes for each destination | |
my @returncodes = split ',', $_; | |
foreach my $returncode( @returncodes ) { | |
my( $num, $code ) = split ':', $returncode; | |
next unless $num && $code; | |
$codes_received++; | |
if( $code == 1 ) { | |
# Message sent OK | |
print "$num: SMS Sent\n"; | |
next; | |
} | |
# Gateway could not send this message - look up the error code | |
# in the table above to get an indication of why it failed. | |
warn "$num: ". (exists $responses{$code} ? $responses{$code} : "SMS failed - unknown error") ."\n"; | |
} | |
} | |
# Extra check to make sure the gateway tried all the numbers we sent it. | |
warn "SMS Gateway did not send a response code for all numbers.\n" if $codes_received < scalar @destinations; | |
} else { | |
# Gateway returned a non-200 response | |
warn "Failed to send SMS message".(scalar @destinations > 1 ? "s" : ""). ".\n"; | |
warn "SMS Gateway returned response code $responsecode\n" if $responsecode; | |
} | |
close FH; | |
exit 0; | |
### END ### | |
sub uri_escape( $ ) | |
{ | |
my( $str ) = @_; | |
$str =~ s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg; | |
return $str; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment