NAME
SMS::Handler::Email - Process Email related commands
SYNOPSIS
use SMS::Handler::Email;
my $h = SMS::Handler::Email->new(-queue => $queue_obj,
-state => $ref_to_hash,
-secret => $my_secret_phrase,
-addr => '9.9.5551212',
-pop => 'pop.your.com',
-smtp => 'smtp.your.com',
-maxlen => 160,
-maxfetch => 1024,
-compact => 1,
-spamcheck => $obj,
-cmds => { ... },
-help => { ... },
-maxspam => 10,
);
$h->handle({ ... });
DESCRIPTION
This module implements a simple responder class. It will respond to any message directed to the specified phone number, with the specified message.
The Email message is assumed to be in ISO-8859-1 (Latin1) encoding. Mappings are provided to convert the messages to a safe 7-Bit character set which is believed to be compatible with any SMS receiver. This mapping is lossy in the sense that accents and special characters are converted to a close but incorrect representation. For instance, an a with a tilde is converted to a plain a.
SUPPORTED COMMANDS
The following commands are supported in the first line of the SMS. Commands can be abbreviated to any unique substring. The first line can be separated by the rest of the message either with a new-line or two consecutive space characters.
- .ACCOUNT login password
-
Associates the given account with the source address of the SMS. Further commands coming from this address are attempted with these supplied credentials, which are the login or username and password of the POP server.
- .CHECK
-
Checks all the messages in the mailbox looking for spam. This requires that a spamcheck item be passed to
->new()
at object creation time. A specially formatted response message, suitable to remove all the SPAM messages will be returned.If this command is followed by the ! symbol, messages recognized as SPAM will be erased automatically.
- .SEND to subject
-
Sends the remainder of the SMS as a message to the address(es) specified in the to field. Multiple addresses can be specified by separating them with commas. No spaces are allowed in the addresses.
Before the actual sending of the message, a POP authentication is attempted. Only if this authentication succeeds will the message be sent.
- .LIST
-
Retrieves the current list of messages in the POP server.
- .DELETE msg
-
Deletes the message msg from the POP server. When omitting msg, the command will refer to the most recent message. 0 is a synonim to 1.
- .REPLY msg
-
Replies to the message specified by msg. When omitting msg, the command will refer to the most recent message. 0 is a synonim to 1.
- .ALL msg
-
Replies to the message specified by msg. When omitting msg, the command will refer to the most recent message. 0 is a synonim to 1. All recipients of the original message are copied of the response.
- .FORWARD msg to
-
Forwards the message specified by msg to the addresses specified in to. When omitting msg, the command will refer to the most recent message. 0 is a synonim to 1.
- .GET msg [block]
-
Retrieves the message msg from the POP server. Only the first chars of the body are retrieved. If a numeric block is specified, that block of octets is presented to the user. The first block is 1. The first block of the most recent message can be requested by omitting msg and block. msg must be specified in order for block to be specified too. A msg 0 is synonim to 1.
- .ALIAS [address] nick
-
Creates a nick for the user whose address is specified. If no address is specified, erases the nick. Nick names or aliases, are used as shorthand for the complete email address of a user.
- .HELP
-
Sends a (very) short usage summary.
The variable $SMS::Handler::Email::DefaultLanguage
can be used to choose the default language of all the answers.
HELP TABLE
The help table is a hash stored in %SMS::Handler::Email::Help
. Each key of the hash, is a command name. Each corresponding value is the reference to a hash, whose key is a language code and its value is a brief explanation of what the command does in the corresponding language.
Probably it is wise to avoid explanations that use 8 bit characters, as those are not safely handled by all the phones out there.
RESPONSE TABLE
The commands must supply responses to the user based on its success. In order to support multiple languages, responses are stored in a hash table (%SMS::Handler::Email::Messages
). Each key on this hash table correspond to a language tag as described in I18N::LangTags. The corresponding value, is a reference to a hash whose keys are message tags (ie, an identifier for the message) and a message in the required language.
Please see the source code for the specific message identifiers used. Note that you must call init()
if this table is changed.
Supported languages must be added to the %SMS::Handler::Email::SupportedLangages
hash before calling the init method.
The following methods are provided:
->new()
-
Creates a new
SMS::Handler::Email
object. It accepts parameters as a number of key / value pairs. The following parameters are supported.queue => $queue_obj
-
An object obeying the interface defined in Queue::Dir, where the response message generated by this module will be stored.
state => $ref_to_hash
-
Reference to a (potentially
tie()
d) hash where state about the user will be stored. Passwords will be stored in this hash, under the protection of reversible crypto. Therefore, care must be taken to prevent unauthorized access to this. secret => $my_secret_phrase
-
A secret phrase used to obscure the passwords stored for the users.
addr => $my_addr
-
The address assigned to this service, in pon.npi.phone format. The destination address of the SMS, must match this argument. If this address is left unspecified, the SMS will be accepted no matter what destination address is used.
pop => $your_pop_server
-
The name or IP address of the POP server.
smtp => $your_smtp_server
-
The name or IP address of the SMTP server.
maxlen => $max_sms_length
-
Maximum length of an SMS. Defaults to 160.
maxfetch => $max_message_length
-
The amount of bytes to fetch from the body of the email. Defaults to 1024 bytes.
compact => $fold_whitespace
-
If set to a true value (the default) forces successions of whitespace to be folded into single spaces. This generally improves readability of the SMS.
spamcheck => $obj
-
If passed, this is assumed to be an object supporting a
->check()
method as described in Mail::SpamAssassin. This is used to test fetched messages for SPAM-iness. cmds -> $hashref
-
Allows the specification of a new command table which overrides the default.
maxspam -> $max
-
Defines the maximum number of messages to check for spamminess for each CHECK command. Defaults to test all the messages. Note that checking a large number of messages at once can take very long.
->handle()
-
Process the given SMS. Commands are taken from a dispatch table and appropiate handlers are called. Commands must be in the first line of the SMS.
An exception to this rule, is the fancy syntax supported by some phones, that looks like
you@some.where(subject)this is the message body you@some.where (subject) this is the message body you(subject)this is the message body you (subject) this is the message body
This syntax is transparently converted to our command based syntax.
->dispatch_error
-
Produce an error when a given command does not exist. Causes the current SMS to be discarded from the queue.
->_CMD_ACCOUNT
-
Handler method for the ACCOUNT command. Note that access to the underlying hash (
$self->{state}
) must be done in a manner thatMLDBM
likes, as most likely the passed hash is tied using this class.Also, the implementation must assume that other items of state information might be stored in that hash. Those items should be preserved.
->_CMD_ALIAS
-
Handler method for the ALIAS command.
->_CMD_INTERFACE
-
Handler for setting the interface language.
->_CMD_SEND
-
Handler method for the SEND command.
->_CMD_LIST
-
Handler method for the LIST command.
->_CMD_HELP
-
Handler method for the HELP command. Sends a SMS message for each supported command, containing the help messages defined.
->_CMD_DELETE
-
Handler method for the DELETE command.
->_CMD_REPLY
-
Handler method for the REPLY command.
->_CMD_REPLY_ALL
-
Handler method for the ALL command.
->_CMD_FORWARD
-
Handler method for the FORWARD command.
->_CMD_GET
-
Handler method for the GET command.
->_CMD_CHECK
-
Handler method for the CHECK command. Only makes sense if
->new()
is called with spamcheck defined. Currently a noop.
CUSTOMIZABLE HANDLERS
To further enhance the customization of this class, the following functions can be overriden to tweak the behavior of this module.
fixup_state($self, $source)
-
This method is invoked after issuing the call to
->_fetch_state()
(and failing). Its main purpose is to allow the definition of default credentials for every user. It can return a false value (the default) to cause an error to be reported when no credentials are available. This function should provide values to$self->{_state}
. It is called with the source address of the cellular phone in the formatNPI.TON.NUMBER
. fixup_phone($self, $hsms, $phone)
-
This function is used to convert a number in
NPI.TON.NUMBER
format to a phone number as expected by cellular users. It must return the phone number as expected by the user. fixup_sms($self, $hsms)
-
This function is invoked from within the
->handle
method, before dispatching to the handlers. This can be used to perform custom transformations in the messages before processing. The default method, provides a translation from Nokia-like syntax into the expected .SEND syntax.
ENCRYPTION OF THE USER PASSWORDS
The encription of the user passwords is intended to prevent a casual observer looking at the hash, from getting the passwords. Since the crypto is both, simplistic and reversible, you should assume that any compromise of the hash containing the passwords lead directly to password compromise.
EXPORT
None by default.
LICENSE AND WARRANTY
This code comes with no warranty of any kind. The author cannot be held liable for anything arising of the use of this code under no circumstances.
This code is released under the terms and conditions of the GPL. Please see the file LICENSE that accompains this distribution for more specific information.
This code is (c) 2002 Luis E. Muñoz.
HISTORY
$Log: Email.pm,v $ Revision 1.55 2003/03/13 20:41:54 lem Fixed case where a command was not followed by any options or any whitespace
Revision 1.54 2003/03/10 22:07:31 lem Messages were being mixed under certain conditions
Revision 1.53 2003/03/09 16:24:52 lem Patch mpicone
Revision 1.52 2003/02/26 14:50:46 lem Improved readability of replies and forwards.
Revision 1.51 2003/02/26 02:45:18 lem Changed .ALIAS order as per compadre's patch
Revision 1.50 2003/02/19 15:25:12 lem Fix for _setup_decoder bug
Revision 1.49 2003/02/18 20:50:30 lem Added patch from luis
Revision 1.48 2003/02/18 15:57:29 lem Reinstate msg number 0 == 1
Revision 1.47 2003/02/18 15:52:35 lem Omitting the message number, tries to use the latest message
Revision 1.46 2003/02/17 18:48:28 lem First attempt at handling multipart/alternative correctly
Revision 1.45 2003/02/13 13:12:23 lem Fix typo in the docs. Added fixup_sms(). Changed the calling protocol for the rest of the remaining fixup_* methods (more power to them).
Revision 1.44 2003/02/12 15:22:39 lem Patch from compadre. The help can be passed to ->new() and also, fixed a typo in the docs
Revision 1.43 2003/02/12 14:38:02 lem Improved clean-up of attachments left behind
Revision 1.42 2003/02/12 00:50:33 lem Message truncation is now working
Revision 1.41 2003/02/11 15:45:04 lem Added fixup_phone and fixup_state
Revision 1.40 2003/02/10 17:34:01 lem Added .ALL
Revision 1.39 2003/02/06 19:49:42 lem Various variables and refs factored in the object
Revision 1.38 2003/02/04 21:33:16 lem Added ! to .REPLY and .FORWARD. Testing is needed
Revision 1.37 2003/02/04 16:01:26 lem Omitting msg now means "last". 0 == 1
Revision 1.36 2003/01/28 18:10:47 lem Added lowercasing when the message body is in ALL CAPS. Added display of the origin phone number when the email was sent from a cellular.
Revision 1.35 2003/01/27 20:44:27 lem .ACCOUNT now stores the date in which it executed in the hash
Revision 1.34 2003/01/14 20:32:34 lem Got rid of Net::SMPP::XML
Revision 1.33 2003/01/08 02:39:03 lem Body was not being updated by _CMD_SEND. "Nokia" format send command is now properly understood. First segment of the message is being sent by .FORWARD and .REPLY.
Revision 1.32 2003/01/05 00:49:08 lem It seems that the bug is not in HTML::Parser either. Taking the md5_hex() of its input before invoking ->parse() seems to get rid of the problem under darwin. More testing is needed to find out where the bug manifests. I am guessing that Perl might be the culprit.
Revision 1.31 2003/01/04 03:38:03 lem Current 8-bit conversion bug has been traced to HTML::Parser. Unable to reproduce in smaller sample program. Testing needed in another platform. The HTML::Parser, Unicode::Map8 and MIME::Decode as well as other items are now kept in $self and initialized only once (and reused) when possible.
Revision 1.30 2003/01/04 00:15:31 lem Fixed some bugs related to stopping the HTML parser when the desired chunk has been parsed.
Revision 1.29 2003/01/03 01:33:44 lem Added .ALIAS. Fixed minor bug with alternate syntax for .SEND.
Revision 1.28 2003/01/02 18:17:26 lem Added -spammax to control how many messages can be check for spamminess
Revision 1.27 2002/12/31 17:08:33 lem Minor fixes in error messages
Revision 1.26 2002/12/31 15:46:10 lem Introduced Map8 workaround using tr///. Looks ugly but seems to work
Revision 1.25 2002/12/31 05:27:16 lem Documented the Unicode::Map8 bug (?) in a newly added BUGS section
Revision 1.24 2002/12/31 05:15:15 lem Factoring of code that access ->{state} (_fetch_state and _store_state). GET now can fetch message chunks to read in entirely. Minor fix in the reply message legend.
Revision 1.23 2002/12/29 22:11:54 lem Improved decoding of MIME QP. Non-MIME messages are now handled by MIME::Parser. Dropped superfluous MIME module
Revision 1.22 2002/12/27 20:10:40 lem Updated docs
Revision 1.21 2002/12/27 19:43:42 lem Added ::Dispatcher and ::Utils to better distribute code. This should make easier the writting of new methods easier
Revision 1.20 2002/12/26 19:11:31 lem Two spaces can be used instead of \n to separate a command from the body of the SMS
Revision 1.19 2002/12/24 08:21:54 lem $Debug = 0. Improved HTML parsing by ignoring <script> and <style> stuff. Better message truncation support.
Revision 1.18 2002/12/23 06:36:04 lem Huge rewrite of the message parsing. Now MIME is handled properly, including fancy multipart messages. Attachments are detected and signalled when within the message size boundary. Message fetching process is lighter and uses on-disk files for caching (and to reduce memory hungriness). .CHECK is more efficient now.
Revision 1.17 2002/12/23 03:17:49 lem Wrapped call to check_message_text() in a special eval{} to avoid the nasty warns of non-essential modules being loaded by Mail::SpamAssassin
Revision 1.16 2002/12/23 01:18:13 lem Added .CHECK command. Also updated the license to GPL
Revision 1.15 2002/12/22 19:04:18 lem Changed license to GPL. Preliminary SPAM tagging support. Needs testing
Revision 1.14 2002/12/22 04:08:19 lem Added README to MANIFEST. Added .FORWARD. We understand HTML messages now, complete with MIME/QuotedPrintable support. Minor fixes in the treatment of MIME messages in .REPLY and .FORWARD. Included some left-over messages into the multi-language support.
Revision 1.13 2002/12/21 23:29:09 lem Added multilanguage support (en, es). Added .INTERFACE and .HELP for specific commands
Revision 1.12 2002/12/20 01:25:57 lem Changed emails for redistribution
Revision 1.11 2002/12/19 18:44:39 lem MIME-Version must be pushed only once
Revision 1.10 2002/12/19 18:40:31 lem Added .REPLY. Also, added MIME headers to outgoing messages. MIME types are preserved in .REPLY. For .SEND, ISO-8859-1 is assumed
Revision 1.9 2002/12/19 17:12:45 lem Added conditional whitespace folding
Revision 1.8 2002/12/19 16:39:30 lem Added truncation indicator at end of large messages
Revision 1.7 2002/12/19 16:12:21 lem Added Date::Parse. This helps us reduce the size of the Date header, saving space in the SMS
Revision 1.6 2002/12/19 06:00:12 lem Fixed minor issues with regexps. Also improved the foo@bar.baz syntax to allow messages with no subject
Revision 1.5 2002/12/19 05:10:41 lem
- Added foo@bar.baz(subject)body notation through a simple transform
Revision 1.4 2002/12/19 04:54:44 lem Added last() to the result of .LIST
Revision 1.3 2002/12/19 04:43:16 lem
- handle() is now a dispatch handler - Commands are handled through self-contained methods (_CMD_*) - Improved error handling a bit
Revision 1.2 2002/12/18 22:01:46 lem More functionality added. Some is still missing
Revision 1.1 2002/12/18 08:45:13 lem
- Added prereqs for Net::SMTP and Net::POP3 - Added SMS::Handler::Email. Still not completely functional - Added some tests for ::Email
BUGS
It looks like HTML::Parser 3.26 is returning the 8-bit data mungled after its first use. This is currently being investigated and no work-around exists.
AUTHOR
Luis E. Muñoz <luismunoz@cpan.org>
SEE ALSO
SMS::Handler, Queue::Dir, perl(1).
3 POD Errors
The following errors were encountered while parsing the POD:
- Around line 2093:
You forgot a '=back' before '=head2'
- Around line 2195:
=back without =over
- Around line 2211:
Non-ASCII character seen before =encoding in 'Muñoz.'. Assuming CP1252