.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "RT::Extension::SMSNotify 3pm" .TH RT::Extension::SMSNotify 3pm "2021-02-27" "perl v5.32.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" RT::Extension::SMSNotify \- Send SMS notifications from RT via SMS::Send .SH "SYNOPSIS" .IX Header "SYNOPSIS" You don't generally use this module directly from your own code, it's an \s-1RT\s0 extension. See \*(L"\s-1CONFIGURATION\*(R"\s0 .SH "DESCRIPTION" .IX Header "DESCRIPTION" Use RT::Extension::SMSNotify to send text message notifications to mobile phones when events occur in \s-1RT,\s0 or via \s-1RT\s0 Crontool to do time-based alerting for things like \s-1SLA\s0 warnings. .PP Useful in conjunction with the RT::Extension::SLA module. .PP SMSes are sent using the SMS::Send module; this has been tested with SMS::Send::RedOxygen. You will need an SMS::Send driver module installed to use the SMSNotify extension. Writing them is easy if you can't find one for your provider. .PP \&\fBMost \s-1SMS\s0 providers only offer asynchronous non-guaranteed delivery\fR and there's no provision for asynchronous delivery status notification in the SMS::Send \s-1API.\s0 If a text message isn't immediately rejected by the provider this plugin will report that the message was dispatched successfully. SMSNotify can make no guarantees about whether the message was delivered. If you need reliable, guaranteed-delivery messaging you should look elsewhere \- but remember that no message is truly received until a human has read and acknowledged it. .PP If SMSes fail to send the resulting exception is reported to the address by default. You can provide your own error reporting function to override it; see \s-1CONFIGURATION\s0 below. .SH "INSTALLATION" .IX Header "INSTALLATION" Install RT::Extension::SMSNotify using \s-1CPAN\s0 or using the usual: .PP .Vb 3 \& perl Makefile.PL \& make \& sudo make install .Ve .PP process. .PP This extension can optionally install some scrip actions in your \s-1RT\s0 database. If you do not install them, you can't create scrips via the \s-1RT\s0 web \s-1UI,\s0 but you can still use \f(CW\*(C`RT::Action::SMSNotify\*(C'\fR via \f(CW\*(C`rt\-crontool\*(C'\fR etc. You can add scrip actions manually if you prefer, or run: .PP .Vb 1 \& make initdb .Ve .PP as a user that has read permission to your \f(CW\*(C`RT_SiteConfig.pm\*(C'\fR. \fBDo not run \&\f(CB\*(C`make initdb\*(C'\fB multiple times; this will result in duplicate entries in your \s-1RT\s0 database\fR. If you have created duplicates you can carefully delete the duplicates manually. Alternately, delete all scrips that use the actions then delete them all from your database's \f(CW\*(C`scripactions\*(C'\fR table with something like: .PP .Vb 1 \& DELETE FROM scripactions WHERE name LIKE \*(Aq[SMSNotify]%\*(Aq; .Ve .PP and add them back in by running \f(CW\*(C`make initdb\*(C'\fR \fIonce\fR. .SH "CONFIGURATION" .IX Header "CONFIGURATION" .Vb 3 \& # Add the plugin to your RT_SiteConfig.pm\*(Aqs plugin list. (Append to any existing \& # @Plugins setting rather than adding a new one). \& Set(@Plugins, qw(RT::Extension::SMSNotify)); \& \& # In RT_SiteConfig.pm, add entries for your SMS::Send provider and its setup \& # argument hash, eg: \& \& Set($SMSNotifyProvider, \*(AqRedOxygen\*(Aq); \& Set($SMSNotifyArguments, { \& _accountid => \*(AqXXXXXXXXXXX\*(Aq \& _email => \*(Aqxxxxx@xxxxxxxxxxxxxxx\*(Aq, \& _password => \*(Aqxxxxxxxx\*(Aq \& }); \& \& # Then use RT\-crontool to invoke the action or register it in the RT DB and use \& # it in scrips. .Ve .ie n .SS "$SMSNotifyProvider" .el .SS "\f(CW$SMSNotifyProvider\fP" .IX Subsection "$SMSNotifyProvider" The \f(CW$SMSNotifyProvider\fR parameter must be set to the name of an installed \f(CW\*(C`SMS::Send\*(C'\fR module as a string, without the \f(CW\*(C`SMS::Send\*(C'\fR qualifier. For example, to use SMS::Send::RedOxygen you'd use: .PP .Vb 1 \& Set($SMSNotifyProvider, \*(AqRedOxygen\*(Aq); .Ve .ie n .SS "$SMSNotifyArguments" .el .SS "\f(CW$SMSNotifyArguments\fP" .IX Subsection "$SMSNotifyArguments" The \f(CW$SMSNotifyArguments\fR parameter must be set to a hash reference with the parameters the SMS:Send driver expects. The exact parameters will vary from driver to driver. The sample given in \*(L"\s-1CONFIGURATION\*(R"\s0 shows settings for \&\f(CW\*(C`SMS::Send::RedSMS\*(C'\fR. .ie n .SS "$SMSNotifyGetPhoneForUserFn" .el .SS "\f(CW$SMSNotifyGetPhoneForUserFn\fP" .IX Subsection "$SMSNotifyGetPhoneForUserFn" This config-overridable method is useful for filtering users to limit the recipients of a message. For example, you might want to return a user's phone number only when their local time is between 08:00 and 17:00. .PP If set, this variable must be either a function reference or a string that names a module with a function named GetPhoneForUser. In either case the variable is set in RT_SiteConfig.pm. .PP If defined this function must take an RT::User as the 1st argument and returns a phone number as a string. The default implementation looks up the RT::User's PagerPhone attribute, which is shown as Pager in the \s-1RT UI,\s0 but you can replace this with an \s-1LDAP\s0 query or whatever you want. .PP Two additional arguments are passed: the Ticket being operated on or undef if no ticket, and a user-defined hint extracted from the action argument if found as documented in SMS::Action::SMSNotify. .PP Return undef or the empty string if no phone number exists for a user. More than one phone number may be returned by returning an array (not an arrayref); all of them will be notified. .PP To set it as an anonymous function reference: .PP .Vb 4 \& Set($SMSNotifyGetPhoneForUserFn, sub { \& my ($user, $ticket, $hint) = @_; \& return $user\->PagerPhone; \& }); .Ve .PP Alternately and preferably if the above code were put in a function named GetPhoneForUser in a module named 'My::Module' with a matching 'package' declaration the configuration would be: .PP .Vb 1 \& Set($SMSNotifyGetPhoneForUserFn, \*(AqMy::Module\*(Aq); .Ve .PP Note that this method has full access to the \s-1RT\s0 system so write it carefully and don't trust user-supplied code. .ie n .SS "$SMSNotifyErrorAlertFn" .el .SS "\f(CW$SMSNotifyErrorAlertFn\fP" .IX Subsection "$SMSNotifyErrorAlertFn" This config-overridable method lets you change this extension's error reporting for when SMSes fail to send. You might want this if you're using a pre-paid service and want to alert when you're out of credit, for example. .PP It works like \f(CW$SMSNotifyGetPhoneForUserFn\fR in that it can be set to a function reference or to the string name of a module with a function named 'ErrorAlert'. .PP The function (whether in a module or a func ref) must accept four arguments: .PP * The SMS::Send result code (non-zero) * The SMS::Send error message * The destination phone number * The destination RT::User or undef if none .PP The default implementation sends an email to the rt owner address. .SS "Use with rt-crontool" .IX Subsection "Use with rt-crontool" This is an example of RT::Extension::SMSNotify use with rt-crontool in /etc/crontab format. The example presumes the existence of a template named \&'\s-1SLA\s0 Alert \s-1SMS\s0' and assumes that your local \s-1RT\s0 user is named 'requesttracker4'. There must be a user in the \s-1RT\s0 database with 'gecos' set to the local \s-1RT\s0 user Cron uses. The action argument specifies that notifications should be sent to all ticket AdminCc users/groups and queue AdminCc watchers. Action arguments are documented in RT::Action::SMSNotify. .PP The search filter is a TicketSQL expression. You can use the \s-1RT\s0 query builder to generate TicketSQL, but it's very limited so you will usually want to write your own. You can test it by pasting it into the Advanced search in \s-1RT.\s0 This search sends SMSes for any ticket with a due date set that's due 24\-25 mins, 11\-12 mins, or 3\-5 mins from now. Since it runs every minute (\f(CW\*(C`*/1\*(C'\fR; could just be written as \f(CW\*(C`*\*(C'\fR) this will generate one message for each of the first time ranges and two for the 2nd. .PP The crontab entry: .PP .Vb 1 \& */1 * * * * requesttracker4 rt\-crontool \-\-transaction last \-\-search RT::Search::FromSQL \-\-search\-arg "(Status=\*(Aqnew\*(Aq OR Status=\*(Aqopen\*(Aq) AND (Due > \*(AqJan 1, 1970\*(Aq) AND ((Due < \*(Aq25 minutes\*(Aq AND Due >= \*(Aq24 minutes\*(Aq) OR (Due < \*(Aq12 minutes\*(Aq AND Due >= \*(Aq11 minutes\*(Aq) OR (Due < \*(Aq5 minutes\*(Aq AND Due >= \*(Aq3 minutes\*(Aq))" \-\-action RT::Action::SMSNotify \-\-action\-arg "TicketAdminCc,QueueAdminCc" \-\-template \*(AqSLA Alert SMS\*(Aq .Ve .PP If you want to test sending messages from cron use a simple search for ticket \s-1ID,\s0 eg: .PP .Vb 1 \& rt\-crontool \-\-search RT::Search::FromSQL \-\-search\-arg \*(AqId = 1033\*(Aq \-\-action RT::Action::SMSNotify \-\-action\-arg "TicketAdminCc,QueueAdminCc" \-\-template \*(AqSLA Alert SMS\*(Aq .Ve .PP or to send direct to a specified phone number: .PP .Vb 1 \& rt\-crontool \-\-search RT::Search::FromSQL \-\-search\-arg \*(AqId = 1033\*(Aq \-\-action RT::Action::SMSNotify \-\-action\-arg "p:+1234123132" \-\-template \*(AqSLA Alert SMS\*(Aq .Ve .SH "TEMPLATES" .IX Header "TEMPLATES" Unlike email templates, your \s-1SMS\s0 templates don't need a header. \s-1RT\s0 will complain if you don't leave the first line blank in your template as it thinks you still need headers. .PP Your template may use the following variables: .PP .Vb 6 \& Argument The argument to this invocation of RT::Extension::SMSNotify \& TicketObj The ticket object (undef if none) this action is acting on \& TransactionObj The current transaction \& PhoneNumber The phone number this template invocation will be sent to \& UserObj The RT::User whose pager number this is, or undef if it \& was supplied by other means like the argument. .Ve .PP The template is executed once per \s-1SMS.\s0 If a user has more than one phone number it'll be executed once per phone number so you'll see the same UserObj more than once. Remember that UserObj can be \f(CW\*(C`undef\*(C'\fR. .PP For example, a template for due date alerting could be: .PP .Vb 1 \& RT alert: {$Ticket\->SubjectTag} is due in { $Ticket\->DueObj\->AgeAsString() } .Ve .SH "AUTHOR" .IX Header "AUTHOR" Craig Ringer .SH "COPYRIGHT" .IX Header "COPYRIGHT" Copyright 2013 Craig Ringer .PP This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. .PP The full text of the license can be found in the \s-1LICENSE\s0 file included with this module.