yesssSMS

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

2023-02-23   Armin Fuerst <armin@fuerst.priv.at>

  Release 2.21
  Nail to old layout because WebSMS was removed
  from the new layout

2020-11-11   Armin Fuerst <armin@fuerst.priv.at>

  Release 2.20
  Implemented token introduced on website on November 11th, 2020
  Added status_line in case of errors when sending message

2019-08-25   Armin Fuerst <armin@fuerst.priv.at>

  Release 2.15
  Removed accidental remaining debug output

2019-08-25   Armin Fuerst <armin@fuerst.priv.at>

  Release 2.14
  Adopted due to little changes of the website


2018-09-04   Armin Fuerst <armin@fuerst.priv.at>

   Release 2.13
   Improved documentation for getSubscriptions().


2018-09-04   Armin Fuerst <armin@fuerst.priv.at>

   Release 2.12
   Corrected typo in description


2018-08-31   Armin Fuerst <armin@fuerst.priv.at>

   Release 2.11
   Added Changelog


2018-08-31   Armin Fuerst <armin@fuerst.priv.at>

   Release 2.10
   Added the possibility to change the sending phonenumber
   Login and selecting phonenumber reads details about tarifs and packages
   Details about tarif and packages are available through getSubscriptions


2014-08-01   Armin Fuerst <armin@fuerst.priv.at>

   Release 2.00
   Adopted for the new webinterface


2014-03-14   Armin Fuerst <armin@fuerst.priv.at>

   Release 1.00
   Initial release - allows to send short messages through
   the webinterface of yesss!

MANIFEST  view on Meta::CPAN

Makefile.PL
MANIFEST
README
t/yesssSMS.t
lib/yesssSMS.pm

META.yml  view on Meta::CPAN

---
abstract: 'Send text messages to mobile phones through the website of yesss!'
author:
  - 'Armin Fuerst <armin@fuerst.priv.at>'
build_requires:
  ExtUtils::MakeMaker: 0
configure_requires:
  ExtUtils::MakeMaker: 0
distribution_type: module
dynamic_config: 0
generated_by: 'ExtUtils::MakeMaker version 6.57_05'
license: unknown
meta-spec:
  url: http://module-build.sourceforge.net/META-spec-v1.4.html
  version: 1.4
name: yesssSMS
no_index:
  directory:
    - t
    - inc
requires: {}
version: 2.21

Makefile.PL  view on Meta::CPAN

use 5.014002;
use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
    NAME              => 'yesssSMS',
    VERSION_FROM      => 'lib/yesssSMS.pm', # finds $VERSION
    PREREQ_PM         => {
    	'HTML::Parser' => '3.71',
	'LWP::UserAgent' => '6.08',
	'HTTP::Cookies' => '6.01',
    }, # e.g., Module::Name => 1.1
    ($] >= 5.005 ?     ## Add these new keywords supported since 5.005
      (ABSTRACT_FROM  => 'lib/yesssSMS.pm', # retrieve abstract from module
       AUTHOR         => 'Armin Fuerst <armin@fuerst.priv.at>') : ()),
);

README  view on Meta::CPAN

yesssSMS version 2.21
=====================

Objects of the yesssSMS class are only able to send text messages to
mobile phones through the website of yesss! (Kontomanager). Kontomanager
might also be in use by other providers (probably Georg, Krone und Kurier, but
this is not tested). Adopting yesssSMS for the use with other providers might
be simple, feel free to contact me if you are willing to try.
To be able to use this service, you need to have an account at yesss!
(a mobile phone). The target phone number must be provided with the
international code starting with 00 (e.g. 0043 for Austria).

INSTALLATION

To install this module type the following:

   perl Makefile.PL
   make
   make install

DEPENDENCIES

This module requires these other modules and libraries:

 * strict
 * warnings
 * HTML::Parser
 * LWP::UserAgent
 * HTML::Cookies


COPYRIGHT AND LICENCE

Copyright (C) 2014-2023 by Armin Fuerst

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.


lib/test.pl  view on Meta::CPAN

#!/usr/bin/perl

use strict;
require "./yesssSMS.pm";

my $sms = yesssSMS->new();
$sms->login('06769510102','x16802');

if ($sms->getLastResult!=0)
{
	print STDERR "Error during login: ".$sms->getLastError()."\n";
	exit;
}

$sms->sendmessage('00436769510102','Testnachricht');
if ($sms->getLastResult!=0)
{
	print STDERR "Error during sendmessage: ".$sms->getLastError()."\n";
	exit;
}

$sms->logout();
if ($sms->getLastResult!=0)
{
	print STDERR "Error during logout: ".$sms->getLastError()."\n";
	exit;
}

lib/yesssSMS.pm  view on Meta::CPAN

package yesssSMS;

use 5.014002;
use strict;
use warnings;
use HTML::Parser;
use LWP::UserAgent;
use HTTP::Cookies;


require Exporter;

our @ISA = qw(Exporter);

# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.

# This allows declaration	use yesssSMS ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.
our %EXPORT_TAGS = ( 'all' => [ qw(
	
) ] );

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

our @EXPORT = qw(
	
);

our $VERSION = '2.21';

sub new
{
	my $self = {};
	$self->{LOGINSTATE} = 0;
	#$self->{URL}="https://www.yesss.at/kontomanager.at/";
	$self->{URL}="https://www.kontomanager.at/";
	# www.yesss.at
	# CookieSettings: %7B%22categories%22%3A%5B%22necessary%22%5D%7D / {"categories":["necessary"]}

	# create useragent and cookie jar
	$self->{UA} = LWP::UserAgent->new;
	$self->{COOKIEJAR} = HTTP::Cookies->new();
	$self->{COOKIEJAR}->set_cookie(0, 'CookieSettings', '{"categories":["necessary"]}', 
		'/', 'www.yesss.at', 443, 0, 0, 86400, 0);
	$self->{UA}->cookie_jar($self->{COOKIEJAR});

	bless ($self);
	return $self;
}

sub login
{
	my $self = shift;
	my $phoneParser;

	($self->{TELNR},
		$self->{PASS})=@_;

	# don't login if logged in...
	if ($self->{LOGINSTATE} == 1)
	{
		$self->{LASTERROR}='Cannot login when already logged in';
		$self->{RETURNCODE}=1;
		return 1;
	}

	# go to start page
	$self->{CONTENT}=$self->{UA}->get($self->{URL}."index.php?brand=yesss&callfromapp=1&appversion=2_3");

	# if there was an error on the start page, stop
	if (!($self->{CONTENT}->is_success))
	{
		$self->{LASTERROR}='Error loading startpage of YESSS!';
		$self->{RETURNCODE}=2;
		return 2;
	}

	# do the login post
	$self->{CONTENT}=$self->{UA}->post($self->{URL}."index.php",{'login_rufnummer' => $self->{TELNR},'login_passwort' => $self->{PASS}});

	# successful login results in redirect
	if (!($self->{CONTENT}->is_redirect))
	{
		$self->{LASTERROR}='Error sending credentials!';
		$self->{RETURNCODE}=3;
		return 3;
	}

	# usually, a redirect is replied
	while ($self->{CONTENT}->is_redirect)
	{
		# follow redirect
		$self->{CONTENT}=$self->{UA}->post($self->{CONTENT}->header("Location"),{'login_rufnummer' => $self->{TELNR},'login_passwort' => $self->{PASS}});

		# if there was an error during redirect, stop
		if (!($self->{CONTENT}->is_success))
		{
			$self->{LASTERROR}='Error during post-login redirect';
			$self->{RETURNCODE}=4;
			print $self->{CONTENT}->status_line;
			return 4;
		}
	}

	# parse interesting values
	$phoneParser=HTML::Parser->new(api_version=>3,
		start_h => [\&loginStartTagParse, "self,tagname,attr"],
		text_h => [\&loginTextParse, "self, text"],
		end_h => [\&loginEndTagParse, "self, tagname"]
	);
	# bring my "self" into the handlers without global vars
	# delete possible existing subscriptions
	# initialize some variables needed for the parser
	undef($self->{SUBSCRIPTIONS});
	$phoneParser->{'yesssSMSself'}=$self;
	$phoneParser->{'inSubscriber'}=0;
	$phoneParser->{'inProgresslist'}=0;
	$phoneParser->{'inProgressheading'}=0;
	$phoneParser->{'amountSubscriptions'}=0;
	$phoneParser->{'amountItems'}=0;
	$phoneParser->parse($self->{CONTENT}->decoded_content);

	# print found phone numbers and their values

	$self->{LOGINSTATE}=1;
	$self->{LASTERROR}='Login successful';
	$self->{RETURNCODE}=0;
	return 0;
}

sub selectPhonenumber
{
	my $self = shift;
	my ($telnr)=@_;
	my $phoneParser;

	# switching is only possible after login
	if ($self->{LOGINSTATE} == 0)
	{
		$self->{LASTERROR}='Not logged in while trying to select phonenumber';
		$self->{RETURNCODE}=1;
		return 1;
	}

	# check, if the requested phonenumber is valid
	if (! defined($self->{SUBSCRIBERS}->{$telnr}))
	{
		$self->{LASTERROR}='Requested phonenumber not available in account';
		$self->{RETURNCODE}=6;
		return 6;
	}

	$self->{CONTENT}=$self->{UA}->post($self->{URL}."kundendaten.php",
		{
			'subscriber' => $self->{SUBSCRIBERS}->{$telnr},
			'groupaction' => 'change_subscriber'
		}
		);

	# stop on error
	if (!($self->{CONTENT}->is_success))
	{
		$self->{LASTERROR}='Error while selecting phonenumber';
		$self->{RETURNCODE}=7;
		return 7;
	}

	# parse interesting values
	$phoneParser=HTML::Parser->new(api_version=>3,
		start_h => [\&loginStartTagParse, "self,tagname,attr"],
		text_h => [\&loginTextParse, "self, text"],
		end_h => [\&loginEndTagParse, "self, tagname"]
	);
	# bring my "self" into the handlers without global vars
	undef($self->{SUBSCRIPTIONS});
	$phoneParser->{'yesssSMSself'}=$self;
	$phoneParser->{'inSubscriber'}=0;
	$phoneParser->{'inProgresslist'}=0;
	$phoneParser->{'inProgressheading'}=0;
	$phoneParser->{'amountSubscriptions'}=0;
	$phoneParser->{'amountItems'}=0;
	$phoneParser->parse($self->{CONTENT}->decoded_content);
	
}

sub sendmessage
{
	my $self = shift;
	my ($telnr,$message)=@_;
	my $tokenParser;

	# only send message when login was successful
	if ($self->{LOGINSTATE} == 0)
	{
		$self->{LASTERROR}='Not logged in while trying to send a message';
		$self->{RETURNCODE}=1;
		return 1;
	}

	if (!($telnr=~/^00/) || (length($telnr)<14))
	{
		$self->{LASTERROR}='Invalid destination (not starting with 00 or too short)';
		$self->{RETURNCODE}=3;
		return 3;
	}

	# go to correct menu item
	$self->{CONTENT}=$self->{UA}->post($self->{URL}."websms.php");

	# stop on error
	if (!($self->{CONTENT}->is_success))
	{
		$self->{LASTERROR}='Error while selecting SMS menu';
		$self->{RETURNCODE}=4;
		return 4;
	}

	# get token for websms.php
	$tokenParser=HTML::Parser->new(api_version=>3,
		start_h => [\&websmsGetTokenStartTagParse, "self,tagname,attr"],
		end_h => [\&websmsGetTokenEndTagParse, "self, tagname"]
	);
	$self->{'websmsToken'}='';
	$tokenParser->{'inWebsmsSendForm'}=0;
	$tokenParser->{'yesssSMSself'}=$self;
	$tokenParser->parse($self->{CONTENT}->decoded_content);

	# try to send message
	$self->{CONTENT}=$self->{UA}->post($self->{URL}."websms_send.php",
		{ 'to_netz' => 'a',
			'to_nummer' => $telnr,
			'nachricht' => $message,
			'token' => $self->{'websmsToken'}
		});

	# stop on error
	if (!($self->{CONTENT}->is_success))
	{
		$self->{LASTERROR}='Error while sending message ('.
			$self->{CONTENT}->status_line.')';
		$self->{RETURNCODE}=5;
		return 5;
	}

	$self->{LASTERROR}='Message sent successfully';
	$self->{RETURNCODE}=0;
	return 0;
}

sub getLoginstate
{
	my $self = shift;
	
	return $self->{LOGINSTATE};
}

sub logout
{
	my $self = shift;

	# don't logout if not logged in...
	if ($self->{LOGINSTATE} == 0)
	{
		$self->{LASTERROR}='Cannot logout when not logged in.';
		$self->{RETURNCODE}=1;
		return 1;
	}

	# post the logout url
	$self->{CONTENT}=$self->{UA}->post($self->{URL}."index.php?dologout=1");

	# if there was an error during logout, stop
	if (!($self->{CONTENT}->is_success))
	{
		$self->{LASTERROR}='Error during logout.';
		$self->{RETURNCODE}=2;
		return 2;
	}

	# reset LOGINSTATE
	$self->{LOGINSTATE}=0;
	$self->{LASTERROR}='Logout successful';
	$self->{RETURNCODE}=0;
	return 0;
}

sub getLastResult
{
	my $self = shift;

	return $self->{RETURNCODE};
}

sub getLastError
{
	my $self = shift;

	return $self->{LASTERROR};
}

sub getContent
{
	my $self = shift;

	return $self->{CONTENT};
}

sub getSubscriptions
{
	my $self = shift;

	return $self->{SUBSCRIPTIONS};
}

sub DESTROY
{
	my $self = shift;
	if ($self->{LOGINSTATE}==1)
	{
		$self->logout();
	}
}


####### methods for parser
# login/switch phone number

sub loginStartTagParse
{
	my ($self, $tagname, $attr) = @_;

	if (($self->{'inSubscriber'} != 1) &&
		($self->{'inProgresslist'} < 1))
	{
		if (($tagname eq 'select') &&
			($attr->{'id'} eq 'subscriber'))
		{
			$self->{'inSubscriber'}=1;
		}
		elsif (($tagname eq 'div') && 
			(defined ($attr->{'class'})) &&
			($attr->{'class'} eq 'progress-list'))
		{
			$self->{'inProgresslist'}++;
		}
	}
	elsif ($self->{'inSubscriber'} == 1)
	{
		if ($tagname eq 'option')
		{
			$self->{'lastValue'}=$attr->{'value'};
		}
	}
	elsif ($self->{'inProgresslist'} >= 1)
	{
		if ($tagname eq 'div')
		{
			if ($attr->{'class'} eq 'info-list-item')
			{
				$self->{'inProgresslist'}=0;
				$self->{'amountItems'}=0;
			}
			elsif ($attr->{'class'} eq 'progress-item')
			{
				$self->{'amountItems'}++;
				$self->{'inProgresslist'}++;
			}
			else
			{
				$self->{'inProgresslist'}++;
			}
		}
		if ($tagname eq 'h3')
		{
			if ((defined($attr->{'id'})) &&
				($attr->{'id'} eq 'kostenkontrolle'))
			{
				# we ignore 'Kostenkontrolle'
				$self->{'inProgresslist'}=0;
				$self->{'amountItems'}=0;
			}
			else
			{
				$self->{'inProgressheading'}=1;
			}
		}
	}
}

sub loginTextParse
{
	my ($self, $text) = @_;
	my $phonenumber;
	my $progressname;
	my $value;

	&trim(\$text);
	if (($self->{'inSubscriber'} == 1) &&
		(length($text)>1))
	{
		($phonenumber)=$text=~/^([0-9]+)[^0-9]/;
		$self->{'yesssSMSself'}->{SUBSCRIBERS}->{$phonenumber}=$self->{'lastValue'};
	}
	elsif (($self->{'inProgressheading'} == 1) &&
		(length($text)>1))
	{
		($progressname)=$text=~/\s*(.*)\s*:$/;
		$self->{'amountSubscriptions'}++;
		$self->{'yesssSMSself'}->{SUBSCRIPTIONS}->[$self->{'amountSubscriptions'}-1]->{'name'}=$progressname;
	}
	elsif (($self->{'inProgresslist'} >= 1) &&
		(length($text)>1))
	{
		if ($text=~/^[0-9]+\s/)
		{
			($value)=$text=~/^[0-9]+\s(.+)$/;
			$self->{'yesssSMSself'}->{SUBSCRIPTIONS}->
				[$self->{'amountSubscriptions'}-1]->{'items'}->[$self->{'amountItems'}-1]->{'unit'}=$value;
		}
		elsif ($text=~/^Verbraucht:/)
		{
			($value)=$text=~/^Verbraucht: ([0-9]+)\s*$/;
			$self->{'yesssSMSself'}->{SUBSCRIPTIONS}->
				[$self->{'amountSubscriptions'}-1]->{'items'}->[$self->{'amountItems'}-1]->{'used'}=$value;
		}
		elsif ($text=~/^Verbraucht Inland:/)
		{
			($value)=$text=~/^Verbraucht Inland: ([0-9]+)\s*$/;
			$self->{'yesssSMSself'}->{SUBSCRIPTIONS}->
				[$self->{'amountSubscriptions'}-1]->{'items'}->[$self->{'amountItems'}-1]->{'used'}+=$value;
		}
		elsif ($text=~/^Verbleibend/)
		{
			($value)=$text=~/^Verbleibend: ([0-9]+)$/;
			$self->{'yesssSMSself'}->{SUBSCRIPTIONS}->
				[$self->{'amountSubscriptions'}-1]->{'items'}->[$self->{'amountItems'}-1]->{'remaining'}=$value;
		}
	}
}

sub loginEndTagParse
{
	my ($self, $tagname) = @_;

	if ($self->{'inSubscriber'} == 1)
	{
		if ($tagname eq 'select')
		{
			$self->{'inSubscriber'}=0;
		}
	}
	elsif ($self->{'inProgresslist'} >= 1)
	{
		if ($tagname eq 'div')
		{
			$self->{'inProgresslist'}--;
			if ($self->{'inProgresslist'} == 0)
			{
				$self->{'amountItems'}=0;
			}
		}
		if ($self->{'inProgressheading'} == 1)
		{
			if ($tagname eq 'h3')
			{
				$self->{'inProgressheading'}=0;
			}
		}
	}
}

## methods for parsing websms_send.php for the token
sub websmsGetTokenStartTagParse
{
	my ($self, $tagname, $attr) = @_;

	if ($self->{'inWebsmsSendForm'} != 1)
	{
		if ($tagname eq 'form')
		{
			if ($attr->{'action'} eq 'websms_send.php')
			{
				$self->{'inWebsmsSendForm'} = 1,
			}
		}
	}
	else
	{
		if ($tagname eq 'input')
		{
			if (($attr->{'type'} eq 'hidden') &&
				($attr->{'name'} eq 'token'))
			{
				$self->{'yesssSMSself'}->{'websmsToken'}=$attr->{'value'};
			}
		}
	}
}

sub websmsGetTokenEndTagParse
{
	my ($self, $tagname) = @_;

	if ($self->{'inWebsmsSendForm'} == 1)
	{
		if ($tagname eq 'form')
		{
			$self->{'inWebsmsSendForm'} = 0;
		}
	}
}


sub trim
{
	my $string=$_[0];

	$$string =~ s/^\s+//;
	$$string =~ s/\s+$//;
}

1;
__END__
# Below is the documentation for the module.

=head1 NAME

yesssSMS - Send text messages to mobile phones through the website of yesss!

=head1 SYNOPSIS

 use yesssSMS;
 use strict;
 
 # create SMS object
 my $sms=yesssSMS->new();
 
 # login to the site with your phone number and the password
 $sms->login("06811234567","MyPassword");
 
 # check whether login was successful
 if ($sms->getLastResult!=0)
 {
 	print STDERR "Error during login: ".$sms->getLastError()."\n";
 }

 # if multiple phonenumbers are available, switch if needed
 $sms->selectPhonenumber('4368187654321');

 # check whether the switch was successfull
 if ($sms->getLastResult!=0)
 {
 	print STDERR "Error during selectPhonenumber: ".
		$sms->getLastError()."\n";
 }
 
 # print remaining units of the main subscription
 print "Remaining: ";
 print $sms->{SUBSCRIPTIONS}->[0]->{'items'}->[0]->{'remaining'}." ";
 print $sms->{SUBSCRIPTIONS}->[0]->{'items'}->[0]->{'unit'}."\n";

 # send a text message
 $sms->sendmessage('00436817654321','Just testing...');
 
 # check whether the message was delivered
 if ($sms->getLastResult!=0)
 {
 	print STDERR "Error during sendmessage: ".
		$sms->getLastError()."\n";
 }
 
 # logout of site
 $sms->logout();
 
 # check whether login was successful
 if ($sms->getLastResult!=0)
 {
 	print STDERR "Error during logout: ".$sms->getLastError()."\n";
 }


=head1 DESCRIPTION

Objects of the yesssSMS class are only able to send text messages to
mobile phones through the website of yesss! (Kontomanager). Kontomanager
might also be in use by other providers (probably Georg, Krone und Kurier, but
this is not tested). Adopting yesssSMS for the use with other providers might
be simple, feel free to contact me if you are willing to try.
To be able to use this service, you need to have an account at yesss!
(a mobile phone). The target phone number must be provided with the
international code starting with 00 (e.g. 0043 for Austria).

This module requires following modules:

 * strict
 * warnings
 * HTML::Parser
 * LWP::UserAgent
 * HTTML::Cookies

=head1 METHODS

The following method is used to construct a new yesssSMS object:

=over

=item $sms = yesssSMS->new()

=back


The following method logs into the website with your phone number and the password:

=over

=item $sms->login(MyPhonenumber,Password)

=back


The following method selects the sending phonenumer (for accounts with multiple phones):

=over

=item $sms->selectPhonenumer(MyAlternatePhonenumer)

=back


The following method sends a text message if a login was successful before:

=over

=item $sms->sendmessage(OtherPhonenumer,Textmessage)

It is possible to send multiple text messages during one login.

=back

The following method logs out of the website of yesss!

=over

=item $sms->logout()

=back

The following method returns the hash to all subscription details:

=over

=item $sms->getSubscriptions()

Returns an array with the subscription details:

* each array contains a hash with "type", "name" and "items".

* "name" is the name of the subscription

* "items" contains an array with all items contained in the subscription.

* each item-array contains a hash with "unit", "used" and "remaining"

* "used" is the amount of already used units during the current accounting period

* "remaining" is the amount of already remaining units during the current accounting period

* "unit" contains the unit of "used" and "remaining"

=back

The following method returns the current login state:

=over

=item $sms->getLoginstate()

0 means: not logged in

1 means: logged in

=back

The following method returns the result of the last operation:

=over

=item $sms->getLastResult()

0 means: successful

>0 means: an error occured

=back

The following method returns a textual description of the result of the
last operation:

=over

=item $sms->getLastError()

=back


The following method returns the LWP::UserAgent last return content:

=over

=item $sms->getContent()

=back

=head1 HISTORY

=over 8

=item 1.00

Original version

=item 2.00

Adopted for the new website being online since August 1st, 2014

=item 2.10

Added the possibility to change the sending phonenumber

Login and selecting phonenumber reads details about tarifs and packages

Details about tarif and packages are available through getSubscriptions

=item 2.11

Added "Changes"

=item 2.12

Corrected typo in description

=item 2.13

Improved documentation for getSubscriptions().

=item 2.14

Little adoptions due to changes in the website

Removed 'type' from subscriptions as they were removed from the site.

=item 2.15

Removed accidental remaining debug output

=item 2.20

Implemented token introduced on website on November 11th, 2020

Added status_line in case of errors when sending message

=item 2.21

Nailed to old interface because websms was removed from the new UI

=back

=head1 AUTHOR

Armin Fuerst

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2014 by Armin Fuerst

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.


=cut

t/yesssSMS.t  view on Meta::CPAN

# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl yesssSMS.t'

#########################

# change 'tests => 1' to 'tests => last_test_to_print';

use strict;
use warnings;

use Test::More tests => 1;
BEGIN { use_ok('yesssSMS') };

#########################

# Insert your test code below, the Test::More module is use()ed here so read
# its man page ( perldoc Test::More ) for help writing this test script.



( run in 0.442 second using v1.01-cache-2.11-cpan-397a349f891 )