Fixed a whole lot of brokenness in Inbox SMS/Email notifications

WebGUI::Inbox::Message::create now passes isInbox flag to WebGUI::Mail::Send::create
so that per-user notification settings get used

SMS Gateway setting field is now 'text' instead of 'email' so that user can enter a
properly formed value (such as 'myemailgateway.com', which is not an email address).

Added SMS notification template as distinct from email notification template because
SMSs should not be HTML and in general you will want to make your SMS notification
message a lot shorter than your html email notification message (160 char limits in
many countries). As a result, SMSs are now sent as separate emails to gateway rather
than being CCd on email notification.

Added smsGatewaySubject setting because many SMS Gateways use email subject for
authentication. For consistency, also added Email notification email subject.

Fixed handling of different combinations of site-wide sendInboxNotificationsOnly with
per-user receiveInboxEmailNotifications and receiveInboxSmsEmailNotifications.
 * sendInboxNotificationsOnly && receiveInboxEmailNotifications = email notification
 * sendInboxNotificationsOnly && !receiveInboxEmailNotifications = no email
 * !sendInboxNotificationsOnly = ignore receiveInboxEmailNotifications
 * In all cases, SMS is optional and only dependent on receiveInboxSmsEmailNotifications

Updated tests and i18n
This commit is contained in:
Patrick Donelan 2009-08-16 09:42:35 +00:00
parent 3cc02af6bb
commit 388a0b1267
12 changed files with 264 additions and 109 deletions

View file

@ -237,6 +237,12 @@ sub editSettingsForm {
hoverHelp => $i18n->get('send inbox notifications only help'),
defaultValue => $setting->get('sendInboxNotificationsOnly'),
);
$f->text(
name => 'inboxNotificationsSubject',
label => $i18n->get('inbox notifications subject'),
hoverHelp => $i18n->get('inbox notifications subject help'),
defaultValue => $setting->get('inboxNotificationsSubject'),
);
$f->template(
name => 'inboxNotificationTemplateId',
label => $i18n->get('inbox notification template'),
@ -244,6 +250,13 @@ sub editSettingsForm {
defaultValue => $self->getInboxNotificationTemplateId,
namespace => 'Account/Inbox/Notification',
);
$f->template(
name => 'inboxSmsNotificationTemplateId',
label => $i18n->get('inbox sms notification template'),
hoverHelp => $i18n->get('inbox sms notification template help'),
defaultValue => $self->getInboxSmsNotificationTemplateId,
namespace => 'Account/Inbox/Notification',
);
return $f->printRowsOnly;
}
@ -284,12 +297,14 @@ sub editSettingsFormSave {
$setting->set("inboxInviteUserTemplateId", $form->process("inboxInviteUserTemplateId", "template"));
$setting->set("inboxInviteUserConfirmTemplateId", $form->process("inboxInviteUserConfirmTemplateId", "template"));
#General Inbox Settings
$setting->set("inboxRichEditId", $form->process("inboxRichEditId", "selectRichEditor") );
$setting->set("inboxRichEditId", $form->process("inboxRichEditId", "selectRichEditor") );
$setting->set("inboxCopySender", $form->process("inboxCopySender", "yesNo"));
#Inbox Notification Settings
$setting->set("sendInboxNotificationsOnly", $form->process("sendInboxNotificationsOnly", "yesNo"));
$setting->set("inboxNotificationsSubject", $form->process("inboxNotificationsSubject", "text"));
$setting->set("inboxNotificationTemplateId", $form->process("inboxNotificationTemplateId","template"));
$setting->set("inboxSmsNotificationTemplateId", $form->process("inboxSmsNotificationTemplateId","template"));
}
@ -321,6 +336,19 @@ sub getInboxNotificationTemplateId {
#-------------------------------------------------------------------
=head2 getInboxSMSNotificationTemplateId ( )
This method returns the template ID for inbox SMS notifications.
=cut
sub getInboxSmsNotificationTemplateId {
my $self = shift;
return $self->session->setting->get("inboxSmsNotificationTemplateId") || "i9-G00ALhJOr0gMh-vHbKA";
}
#-------------------------------------------------------------------
=head2 getInvitationCount ( )
This method returns the total number of invitations in the invitation box.
@ -1302,39 +1330,84 @@ sub www_sendMessageSave {
#Let sendMessage deal with displaying errors
return $self->www_sendMessage($errorMsg) if $hasError;
my $messageProperties = {
message => $message,
subject => $subject,
status => 'unread',
sentBy => $fromUser->userId
};
if ($session->setting->get('sendInboxNotificationsOnly')) {
my $template = WebGUI::Asset::Template->new($session, $self->getInboxNotificationTemplateId);
if ($template) {
##Create template variables
my $var = {
fromUsername => $fromUser->username,
subject => $messageProperties->{subject},
message => $messageProperties->{message},
inboxLink => $session->url->append($session->url->getSiteURL, 'op=account;module=inbox'),
};
##Fill in template
my $output = $template->process($var);
##Evaluate macros by hand
WebGUI::Macro::process($session, \$output);
##Assign template output to $messageProperties->{emailMessage}
$messageProperties->{emailMessage} = $output;
}
else {
$session->log->warn(sprintf "Unable to instanciate notification template: ". $self->getInboxNotificationTemplateId);
}
}
foreach my $uid (@toUsers) {
my $messageProperties = {
message => $message,
subject => $subject,
status => 'unread',
sentBy => $fromUser->userId
};
my $messageOptions = {};
# Handle Email/SMS Notifications
my $user = WebGUI::User->new($session, $uid);
# Sender only gets CCd on inbox message (not real email)
my $isSender = $uid == $session->user->userId;
$messageOptions->{no_email} = 1 if $isSender;
# Optionally set SMS notification details (excluding sender)
my $smsAddress = $user->getInboxSmsNotificationAddress;
if ( $smsAddress && !$isSender ) {
my $smsNotificationTemplate
= WebGUI::Asset::Template->new($session, $self->getInboxSmsNotificationTemplateId);
if ($smsNotificationTemplate) {
##Create template variables
my $var = {
fromUsername => $fromUser->username,
subject => $messageProperties->{subject},
message => $messageProperties->{message},
inboxLink => $session->url->append($session->url->getSiteURL, 'op=account;module=inbox'),
};
##Fill in template
my $output = $smsNotificationTemplate->process($var);
##Evaluate macros by hand
WebGUI::Macro::process($session, \$output);
##Assign template output to $messageProperties->{emailMessage}
$messageProperties->{smsMessage} = $output;
$messageProperties->{smsAddress} = $smsAddress;
$messageProperties->{smsSubject} = $self->session->setting->get('smsGatewaySubject');
}
else {
$session->log->warn(sprintf "Unable to instanciate notification template: ". $self->getInboxSmsNotificationTemplateId);
}
}
# Optionally set email notification details (excluding sender)
if ($session->setting->get('sendInboxNotificationsOnly') && !$isSender) {
my $notificationAddresses = $user->getInboxNotificationAddresses;
# If user has turned off email notifications and admin has turned on sendInboxNotificationsOnly,
# user gets no email at all - because email and email notification are mutually exclusive.
# Note that they can still possibly get SMS notification above
if (!$notificationAddresses) {
$messageOptions->{no_email} = 1;
} else {
my $template = WebGUI::Asset::Template->new($session, $self->getInboxNotificationTemplateId);
if ($template) {
##Create template variables
my $var = {
fromUsername => $fromUser->username,
subject => $messageProperties->{subject},
message => $messageProperties->{message},
inboxLink => $session->url->append($session->url->getSiteURL, 'op=account;module=inbox'),
};
##Fill in template
my $output = $template->process($var);
##Evaluate macros by hand
WebGUI::Macro::process($session, \$output);
##Assign template output to $messageProperties->{emailMessage}
$messageProperties->{emailMessage} = $output;
$messageProperties->{emailSubject} = $session->setting->get('inboxNotificationsSubject');
}
else {
$session->log->warn(sprintf "Unable to instanciate notification template: ". $self->getInboxNotificationTemplateId);
}
}
}
$messageProperties->{userId} = $uid;
my $thisMessage = $inbox->addMessage($messageProperties);
my $thisMessage = $inbox->addMessage($messageProperties, $messageOptions);
if ($uid eq $session->user->userId) {
$thisMessage->setRead;
}

View file

@ -97,6 +97,18 @@ Email message to use rather than inbox message contents.
Email subject to use rather than inbox message subject.
=head4 smsMessage
SMS notification message to send to C<smsAddress>
=head4 smsSubject
SMS notification subject (typically used for SMS Gateway authentication)
=head4 smsAddress
Email address that SMS notification is sent to (typically the user's C<cellPhone> C<@> C<smsGateway>)
=head3 options
A hash reference containing options for handling the message.
@ -106,6 +118,17 @@ A hash reference containing options for handling the message.
If no_email is true, then no email will be made or sent. Only
the inbox message will be made.
=head4 no_sms
If no_sms is true, then no attempt to sms notifications will be sent.
=head4 overridePerUserDelivery
If true, then the C<isInbox> flag will not be passed to L<WebGUI::Mail::Send::Create>, and thus the
per-user settings for email delivery will not be used. Useful if you want to force this message to
be sent as an Email rather than allowing the user's C<receiveInboxEmailNotifications> setting to
take effect.
=cut
sub create {
@ -127,6 +150,9 @@ sub create {
$self->{_properties}{userId} = $session->user->userId;
}
my $status = $self->{_properties}{status};
my $smsMessage = $properties->{smsMessage};
my $smsSubject = $properties->{smsSubject};
my $smsAddress = $properties->{smsAddress};
if ($status eq "completed") {
$self->{_properties}{completedBy} = $session->user->userId;
@ -158,13 +184,15 @@ sub create {
);
}
}
if ( $options->{ to_email } ) {
my $subject = (defined $properties->{emailSubject}) ? $properties->{emailSubject} : $self->{_properties}{subject};
unless ( $options->{ no_email } ) {
my $subject = (defined $properties->{emailSubject}) ? $properties->{emailSubject} : $self->{_properties}{subject};
my $mail = WebGUI::Mail::Send->create($session, {
toUser=>$self->{_properties}{userId},
toGroup=>$self->{_properties}{groupId},
subject=>$subject,
});
},
$options->{overridePerUserDelivery} ? undef : 'isInbox',
);
my $preface = "";
my $fromUser = WebGUI::User->new($session, $properties->{sentBy});
#Don't append prefaces to the visitor users or messages that don't specify a user (default case)
@ -177,6 +205,23 @@ sub create {
$mail->addFooter;
$mail->queue;
}
unless ( $options->{ no_sms } ) {
# If smsAddress provided, send smsMessage too
if ( $smsAddress && $smsMessage) {
my $sms = WebGUI::Mail::Send->create(
$session,
{ to => $smsAddress,
subject => $smsSubject,
}
);
if ($sms) {
$sms->addText($smsMessage);
$sms->queue;
}
}
}
$self->{_session} = $session;
bless $self, $class;
}

View file

@ -284,7 +284,7 @@ sub create {
if (defined $user) {
my $email;
if ($isInbox) {
$email = $user->getInboxAddresses;
$email = $user->getInboxNotificationAddresses;
}
else {
$email = $user->profileField("email");
@ -511,7 +511,7 @@ sub send {
next USER unless $user->status eq 'Active'; ##Don't send this to invalid user accounts
my $emailAddress;
if ($self->{_isInbox}) {
$emailAddress = $user->getInboxAddresses;
$emailAddress = $user->getInboxNotificationAddresses;
}
else {
$emailAddress = $user->profileField('email');

View file

@ -305,11 +305,19 @@ sub definition {
});
push(@fields, {
tab => 'messaging',
fieldType => 'email',
fieldType => 'text',
name => 'smsGateway',
label => $i18n->get('sms gateway'),
hoverHelp => $i18n->get('sms gateway help'),
defaultValue => $setting->get('smsGateway'),
});
push(@fields, {
tab => 'messaging',
fieldType => 'text',
name => 'smsGatewaySubject',
label => $i18n->get('sms gateway subject'),
hoverHelp => $i18n->get('sms gateway subject help'),
defaultValue => $setting->get('smsGatewaySubject'),
});
# misc
push(@fields, {

View file

@ -704,30 +704,55 @@ sub getId {
#-------------------------------------------------------------------
=head2 getInboxAddresses ( )
=head2 getInboxNotificationAddresses ( )
Return a string with addresses that the user wants to receive Inbox
notifications. If the user does not want Inbox notifications, then
the string will be empty.
This is called by L<WebGUI::Mail::Send>, and has the effect that if
the site C<sendInboxNotificationsOnly> setting is on and the user
has turned off C<receiveInboxEmailNotifications>, no email at all is
sent.
=cut
sub getInboxAddresses {
sub getInboxNotificationAddresses {
my $self = shift;
my $emails = '';
if ( $self->profileField('receiveInboxEmailNotifications')
&& $self->profileField('email')) {
$emails = $self->profileField('email');
}
if ( $self->profileField('receiveInboxSmsNotifications')
&& $self->profileField('cellPhone')
&& $self->session->setting->get('smsGateway')) {
$emails .= ',' if $emails;
my $phoneNumber = $self->profileField('cellPhone');
$phoneNumber =~ tr/0-9//dc; ##remove nonnumbers
$emails = join '', $emails, $phoneNumber, '@', $self->session->setting->get('smsGateway');
}
return $emails;
}
#-------------------------------------------------------------------
=head2 getInboxSmsNotificationAddress ( )
Return the email address that SMS notifications will be sent to for
this user, constructed as:
cellPhone@smsGateway
=cut
sub getInboxSmsNotificationAddress {
my $self = shift;
return unless $self->profileField('receiveInboxSmsNotifications');
my $smsGateway = $self->session->setting->get('smsGateway');
return unless $smsGateway;
my $cellPhone = $self->profileField('cellPhone');
return unless $cellPhone;
# Remove non-numbers from cellPhone
$cellPhone =~ tr/0-9//dc;
return join q{}, $cellPhone, '@', $smsGateway;
}
#-------------------------------------------------------------------

View file

@ -774,6 +774,17 @@ our $I18N = {
message => q|Should WebGUI just send notifications about Inbox messages, instead of the message itself?|,
lastUpdated => 1235696295,
},
'inbox notifications subject' => {
message => q|Inbox Notification Email Subject|,
context => q|Site setting. A notification is a short message that a message is in the Inbox.|,
lastUpdated => 0,
},
'inbox notifications subject help' => {
message => q|The email subject to use for inbox notifications|,
lastUpdated => 0,
},
'inbox notification' => {
message => q|You have a new message in your Inbox.|,
@ -790,6 +801,22 @@ our $I18N = {
message => q|Choose a template that will be used to display Inbox Notifications.|,
lastUpdated => 1242274703,
},
'inbox sms notification' => {
message => q|You have a new message in your Inbox.|,
lastUpdated => 1235708853,
},
'inbox sms notification template' => {
message => q|Inbox SMS Notification Template|,
context => q|Site setting. A notification is a short SMS message that a message is in the Inbox.|,
lastUpdated => 1242274705,
},
'inbox sms notification template help' => {
message => q|Choose a template that will be used to display Inbox SMS Notifications.|,
lastUpdated => 1242274703,
},
};

View file

@ -4555,7 +4555,7 @@ Users may override this setting in their profile.
},
'sms gateway' => {
message => q|SMS gateway|,
message => q|SMS Gateway|,
context => q|email to SMS/text email address for this site.|,
lastUpdated => 1235685248,
},
@ -4564,6 +4564,17 @@ Users may override this setting in their profile.
message => q|The email address that this site would use to send an SMS message.|,
lastUpdated => 1235695517,
},
'sms gateway subject' => {
message => q|SMS Gateway Subject|,
context => q|Subject to use for the SMS Gateway for this site.|,
lastUpdated => 0,
},
'sms gateway subject help' => {
message => q|The email subject to pass to the SMS Gateway (typically used for SMS Gateway authorization).|,
lastUpdated => 0,
},
'Select One' => {
message => q|Select One|,