Enable WebGUI sites to send SMS messages as inbox notifications.

This commit is contained in:
Colin Kuskie 2009-05-13 21:55:33 +00:00
commit f54e975c14
8 changed files with 303 additions and 18 deletions

View file

@ -31,6 +31,7 @@
- rfe #9907: Inbox: Notifications - rfe #9907: Inbox: Notifications
- rfe #9134: Pluggable Storage to support Amazon S3 and Cloudfront - rfe #9134: Pluggable Storage to support Amazon S3 and Cloudfront
- Added PayPal paydriver. (Thanks to Paul Wrightson) - Added PayPal paydriver. (Thanks to Paul Wrightson)
- rfe #9908: Inbox: SMS delivery
7.7.5 7.7.5
- Adding StoryManager. - Adding StoryManager.

View file

@ -39,6 +39,9 @@ addListingsCacheTimeoutToMatrix( $session );
addSurveyFeedbackTemplateColumn( $session ); addSurveyFeedbackTemplateColumn( $session );
installCopySender($session); installCopySender($session);
installNotificationsSettings($session); installNotificationsSettings($session);
installSMSUserProfileFields($session);
installSMSSettings($session);
upgradeSMSMailQueue($session);
addPayDrivers($session); addPayDrivers($session);
finish($session); finish($session);
@ -163,6 +166,49 @@ sub installNotificationsSettings {
$session->setting->add('inboxNotificationTemplateId', 'b1316COmd9xRv4fCI3LLGA'); $session->setting->add('inboxNotificationTemplateId', 'b1316COmd9xRv4fCI3LLGA');
} }
<<<<<<< .mine
sub installSMSUserProfileFields {
my $session = shift;
WebGUI::ProfileField->create(
$session,
'receiveInboxEmailNotifications',
{
label => q!WebGUI::International::get('receive inbox emails','Message_Center')!,
visible => 1,
required => 0,
protected => 1,
editable => 1,
fieldType => 'yesNo',
dataDefault => 1,
},
4,
);
WebGUI::ProfileField->create(
$session,
'receiveInboxSmsNotifications',
{
label => q!WebGUI::International::get('receive inbox sms','Message_Center')!,
visible => 1,
required => 0,
protected => 1,
editable => 1,
fieldType => 'yesNo',
dataDefault => 0,
},
4,
);
}
sub installSMSSettings {
my $session = shift;
$session->setting->add('smsGateway', '');
}
sub upgradeSMSMailQueue {
my $session = shift;
$session->db->write('alter table mailQueue add column isInbox TINYINT(4) default 0');
}
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
# Describe what our function does # Describe what our function does
sub addPayDrivers { sub addPayDrivers {

View file

@ -267,16 +267,28 @@ A unique id for this message, in case you want to see what replies come in for i
If this is a reply to a previous message, then you should specify the messageId of the previous message here. If this is a reply to a previous message, then you should specify the messageId of the previous message here.
=head3 isInbox
A flag indicating that this email message is from the Inbox, and should follow per user settings
for delivery.
=cut =cut
sub create { sub create {
my $class = shift; my $class = shift;
my $session = shift; my $session = shift;
my $headers = shift; my $headers = shift;
my $isInbox = shift;
if ($headers->{toUser}) { if ($headers->{toUser}) {
my $user = WebGUI::User->new($session, $headers->{toUser}); my $user = WebGUI::User->new($session, $headers->{toUser});
if (defined $user) { if (defined $user) {
my $email = $user->profileField("email"); my $email;
if ($isInbox) {
$email = $user->getInboxAddresses;
}
else {
$email = $user->profileField("email");
}
if ($email) { if ($email) {
if ($headers->{to}) { if ($headers->{to}) {
$headers->{to} .= ','.$email; $headers->{to} .= ','.$email;
@ -286,9 +298,9 @@ sub create {
} }
} }
} }
my $from = $headers->{from} || $session->setting->get('comanyName') . " <".$session->setting->get("companyEmail").">"; my $from = $headers->{from} || $session->setting->get('comanyName') . " <".$session->setting->get("companyEmail").">";
my $type = $headers->{contentType} || "multipart/mixed"; my $type = $headers->{contentType} || "multipart/mixed";
my $replyTo = $headers->{replyTo} || $session->setting->get("mailReturnPath"); my $replyTo = $headers->{replyTo} || $session->setting->get("mailReturnPath");
# format of Message-Id should be '<unique-id@domain>' # format of Message-Id should be '<unique-id@domain>'
my $id = $headers->{messageId} || "WebGUI-" . $session->id->generate; my $id = $headers->{messageId} || "WebGUI-" . $session->id->generate;
@ -326,7 +338,7 @@ sub create {
delete $headers->{toGroup}; delete $headers->{toGroup};
$message->attach(Data=>"This message was intended for ".$to." but was overridden in the config file.\n\n"); $message->attach(Data=>"This message was intended for ".$to." but was overridden in the config file.\n\n");
} }
bless {_message=>$message, _session=>$session, _toGroup=>$headers->{toGroup} }, $class; bless {_message=>$message, _session=>$session, _toGroup=>$headers->{toGroup}, _isInbox => $isInbox }, $class;
} }
#------------------------------------------------------------------- #-------------------------------------------------------------------
@ -469,10 +481,10 @@ sub send {
else { else {
my $smtp = Net::SMTP->new($smtpServer); # connect to an SMTP server my $smtp = Net::SMTP->new($smtpServer); # connect to an SMTP server
if (defined $smtp) { if (defined $smtp) {
$smtp->mail($mail->head->get("X-Return-Path")); $smtp->mail($mail->head->get('X-Return-Path'));
$smtp->to(split(",",$mail->head->get("to"))); $smtp->to( split(',', $mail->head->get('to') ));
$smtp->cc(split(",",$mail->head->get("cc"))); $smtp->cc( split(',', $mail->head->get('cc') ));
$smtp->bcc(split(",",$mail->head->get("bcc"))); $smtp->bcc( split(',', $mail->head->get('bcc') ));
$smtp->data(); # Start the mail $smtp->data(); # Start the mail
$smtp->datasend($mail->stringify); $smtp->datasend($mail->stringify);
$smtp->dataend(); # Finish sending the mail $smtp->dataend(); # Finish sending the mail
@ -492,15 +504,21 @@ sub send {
if ($group) { if ($group) {
my $group = WebGUI::Group->new($self->session, $group); my $group = WebGUI::Group->new($self->session, $group);
return $status if !defined $group; return $status if !defined $group;
$mail->head->replace("bcc", undef); $mail->head->replace('bcc', undef);
$mail->head->replace("cc", undef); $mail->head->replace('cc', undef);
foreach my $userId (@{$group->getAllUsers(1)}) { USER: foreach my $userId (@{$group->getAllUsers(1)}) {
my $user = WebGUI::User->new($self->session, $userId); my $user = WebGUI::User->new($self->session, $userId);
next unless $user->status eq 'Active'; ##Don't send this to invalid user accounts next USER unless $user->status eq 'Active'; ##Don't send this to invalid user accounts
if ($user->profileField("email")) { my $emailAddress;
$mail->head->replace("To",$user->profileField("email")); if ($self->{_isInbox}) {
$self->queue; $emailAddress = $user->getInboxAddresses;
} }
else {
$emailAddress = $user->profileField('email');
}
next USER unless $emailAddress;
$mail->head->replace('To', $emailAddress);
$self->queue;
} }
#Delete the group if it is flagged as an AdHocMailGroup #Delete the group if it is flagged as an AdHocMailGroup
$group->delete if ($group->isAdHocMailGroup); $group->delete if ($group->isAdHocMailGroup);

View file

@ -295,6 +295,14 @@ sub definition {
hoverHelp=>$i18n->get('mail return path help'), hoverHelp=>$i18n->get('mail return path help'),
defaultValue=>$setting->get("mailReturnPath") defaultValue=>$setting->get("mailReturnPath")
}); });
push(@fields, {
tab => 'messaging',
fieldType => 'email',
name => 'smsGateway',
label => $i18n->get('sms gateway'),
hoverHelp => $i18n->get('sms gateway help'),
defaultValue => $setting->get('smsGateway'),
});
# misc # misc
push(@fields, { push(@fields, {
tab=>"misc", tab=>"misc",

View file

@ -504,6 +504,34 @@ sub getGroupIdsRecursive {
#------------------------------------------------------------------- #-------------------------------------------------------------------
=head2 getInboxAddresses ( )
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.
=cut
sub getInboxAddresses {
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 getProfileFieldPrivacySetting ( [field ]) =head2 getProfileFieldPrivacySetting ( [field ])
Returns the privacy setting for the field passed in. If no field is passed in the entire hash is returned Returns the privacy setting for the field passed in. If no field is passed in the entire hash is returned

View file

@ -4359,12 +4359,13 @@ Users may override this setting in their profile.
'recaptcha public key' => { 'recaptcha public key' => {
message => 'reCAPTCHA Public Key' message => 'reCAPTCHA Public Key'
}, },
'Ad Space control name' => { 'Ad Space control name' => {
message => q|Ad Space|, message => q|Ad Space|,
lastUpdated => 0, lastUpdated => 0,
context => q|name for the Ad Space control| context => q|name for the Ad Space control|
}, },
'global head tags label' => { 'global head tags label' => {
message => 'Global Head Tags', message => 'Global Head Tags',
lastUpdated => 0, lastUpdated => 0,
@ -4376,6 +4377,17 @@ Users may override this setting in their profile.
context => 'Description of setting', context => 'Description of setting',
}, },
'sms gateway' => {
message => q|SMS gateway|,
context => q|email to SMS/text email address for this site.|,
lastUpdated => 1235685248,
},
'sms gateway help' => {
message => q|The email address that this site would use to send an SMS message.|,
lastUpdated => 1235695517,
},
}; };
1; 1;

View file

@ -16,6 +16,7 @@ use FindBin;
use lib "$FindBin::Bin/../lib"; use lib "$FindBin::Bin/../lib";
use JSON qw( from_json to_json ); use JSON qw( from_json to_json );
use Test::More; use Test::More;
use Test::Deep;
use File::Spec; use File::Spec;
use Data::Dumper; use Data::Dumper;
use MIME::Parser; use MIME::Parser;
@ -69,7 +70,7 @@ if ($hasServer) {
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
# Tests # Tests
plan tests => 11; # Increment this number for each test you create plan tests => 18; # Increment this number for each test you create
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
# Test create # Test create
@ -272,6 +273,134 @@ SKIP: {
} }
#----------------------------------------------------------------------------
#
# Test sending an Inbox message to a user who has various notifications configured
#
#----------------------------------------------------------------------------
my $inboxUser = WebGUI::User->create($session);
WebGUI::Test->usersToDelete($inboxUser);
$inboxUser->username('red');
$inboxUser->profileField('receiveInboxEmailNotifications', 1);
$inboxUser->profileField('receiveInboxSmsNotifications', 0);
$inboxUser->profileField('email', 'ellis_boyd_redding@shawshank.gov');
$inboxUser->profileField('cellPhone', '55555');
$session->setting->set('smsGateway', 'textme.com');
my $emailUser = WebGUI::User->create($session);
WebGUI::Test->usersToDelete($emailUser);
$emailUser->username('heywood');
$emailUser->profileField('email', 'heywood@shawshank.gov');
my $lonelyUser = WebGUI::User->create($session);
WebGUI::Test->usersToDelete($lonelyUser);
$lonelyUser->profileField('receiveInboxEmailNotifications', 0);
$lonelyUser->profileField('receiveInboxSmsNotifications', 0);
$lonelyUser->profileField('email', 'jake@shawshank.gov');
my $inboxGroup = WebGUI::Group->new($session, 'new');
WebGUI::Test->groupsToDelete($inboxGroup);
$inboxGroup->addUsers([$emailUser->userId, $inboxUser->userId, $lonelyUser->userId]);
SKIP: {
my $numtests = 1; # Number of tests in this block
# Must be able to write the config, or we'll die
skip "Cannot test email notifications", $numtests unless $smtpServerOk;
# Send the mail
$mail = WebGUI::Mail::Send->create( $session, {
toUser => $inboxUser->userId,
},
'fromInbox',
);
$mail->addText( 'sent via email' );
my $received = sendToServer( $mail ) ;
# Test the mail
is($received->{to}->[0], '<ellis_boyd_redding@shawshank.gov>', 'send, toUser with email address');
$inboxUser->profileField('receiveInboxEmailNotifications', 0);
$inboxUser->profileField('receiveInboxSmsNotifications', 1);
# Send the mail
$mail = WebGUI::Mail::Send->create( $session, {
toUser => $inboxUser->userId,
},
'fromInbox',
);
$mail->addText( 'sent via SMS' );
my $received = sendToServer( $mail ) ;
# Test the mail
is($received->{to}->[0], '<55555@textme.com>', 'send, toUser with SMS address');
$inboxUser->profileField('receiveInboxEmailNotifications', 1);
$inboxUser->profileField('receiveInboxSmsNotifications', 1);
# Send the mail
$mail = WebGUI::Mail::Send->create( $session, {
toUser => $inboxUser->userId,
},
'fromInbox',
);
$mail->addText( 'sent via SMS' );
my $received = sendToServer( $mail ) ;
# Test the mail
cmp_bag(
$received->{to},
['<55555@textme.com>', '<ellis_boyd_redding@shawshank.gov>',],
'send, toUser with SMS and email addresses'
);
}
#----------------------------------------------------------------------------
#
# Test sending an Inbox message to a group with various user profile settings
#
#----------------------------------------------------------------------------
my @mailIds;
@mailIds = $session->db->buildArray('select messageId from mailQueue');
my $startingMessages = scalar @mailIds;
$mail = WebGUI::Mail::Send->create( $session, {
toGroup => $inboxGroup->getId,
},
'fromInbox',
);
$mail->addText('Mail::Send test message');
@mailIds = $session->db->buildArray('select messageId from mailQueue');
is(scalar @mailIds, $startingMessages, 'creating a message does not queue a message');
$mail->send;
@mailIds = $session->db->buildArray('select messageId from mailQueue');
is(scalar @mailIds, $startingMessages+2, 'sending a message with a group added two messages');
@mailIds = $session->db->buildArray("select messageId from mailQueue where message like ?",['%Mail::Send test message%']);
is(scalar @mailIds, $startingMessages+2, 'sending a message with a group added the right two messages');
my @emailAddresses = ();
foreach my $mailId (@mailIds) {
my $mail = WebGUI::Mail::Send->retrieve($session, $mailId);
push @emailAddresses, $mail->getMimeEntity->head->get('to');
}
cmp_bag(
\@emailAddresses,
[
'heywood@shawshank.gov'."\n",
'ellis_boyd_redding@shawshank.gov,55555@textme.com'."\n",
],
'send: when the original is sent, new messages are created for each user in the group, following their user profile settings'
);
# TODO: Test the emailToLog config setting # TODO: Test the emailToLog config setting
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
# Cleanup # Cleanup

View file

@ -20,7 +20,7 @@ use WebGUI::Cache;
use WebGUI::User; use WebGUI::User;
use WebGUI::ProfileField; use WebGUI::ProfileField;
use Test::More tests => 194; # increment this value for each test you create use Test::More tests => 203; # increment this value for each test you create
use Test::Deep; use Test::Deep;
use Data::Dumper; use Data::Dumper;
@ -804,6 +804,47 @@ ok(! $neighbor->canViewField('email', $admin), "... returns 0 when the field's p
ok(! $neighbor->canViewField('email', $buster), "... returns 0 when the field's privacy setting is friends, even for some other user"); ok(! $neighbor->canViewField('email', $buster), "... returns 0 when the field's privacy setting is friends, even for some other user");
$friend->deleteFromGroups([$neighbor->friends->getId]); $friend->deleteFromGroups([$neighbor->friends->getId]);
################################################################
#
# getInboxAddresses
#
################################################################
my $origSmsGateway = $session->setting->get('smsGateway');
$session->setting->set('smsGateway', '');
my $inmate = WebGUI::User->create($session);
WebGUI::Test->usersToDelete($inmate);
$inmate->profileField('email', '');
$inmate->profileField('cellPhone', '');
$inmate->profileField('receiveInboxEmailNotifications', 0);
$inmate->profileField('receiveInboxSmsNotifications', 0);
is ($inmate->getInboxAddresses, '', 'getInboxAddresses: with no profile info, returns blank');
$inmate->profileField('receiveInboxEmailNotifications', 1);
is ($inmate->getInboxAddresses, '', 'getInboxAddresses: with receiveInboxEmailNotifications=1, but not email address, returns blank');
$inmate->profileField('email', 'andy@shawshank.com');
is ($inmate->getInboxAddresses, 'andy@shawshank.com', 'getInboxAddresses: email address only');
$inmate->profileField('receiveInboxSmsNotifications', 1);
is ($inmate->getInboxAddresses, 'andy@shawshank.com', 'getInboxAddresses: receive only email address, with receiveInboSMSNotifications=1 but no other profile info');
$inmate->profileField('cellPhone', '37927');
is ($inmate->getInboxAddresses, 'andy@shawshank.com', 'getInboxAddresses: receive only email address, with receiveInboSMSNotifications=1 and cell phone but no gateway');
$inmate->profileField('cellPhone', '');
$session->setting->set('smsGateway', 'textme.com');
is ($inmate->getInboxAddresses, 'andy@shawshank.com', 'getInboxAddresses: receive only email address, with receiveInboSMSNotifications=1 and gateway but no cell phone');
$inmate->profileField('cellPhone', '37927');
is ($inmate->getInboxAddresses, 'andy@shawshank.com,37927@textme.com', 'getInboxAddresses: receive only email address, with receiveInboSMSNotifications=1 and gateway but no cell phone');
$inmate->profileField('receiveInboxEmailNotifications', 0);
is ($inmate->getInboxAddresses, '37927@textme.com', 'getInboxAddresses: can get SMS and no email, even with email info present');
$inmate->profileField('receiveInboxSmsNotifications', 0);
is ($inmate->getInboxAddresses, '', 'getInboxAddresses: can get no SMS and no email, even with profile info present');
END { END {
foreach my $testGroup ($expiredGroup, values %groupSet) { foreach my $testGroup ($expiredGroup, values %groupSet) {
if (defined $testGroup and ref $testGroup eq 'WebGUI::Group') { if (defined $testGroup and ref $testGroup eq 'WebGUI::Group') {
@ -822,6 +863,8 @@ END {
$newProfileField->delete() if $newProfileField; $newProfileField->delete() if $newProfileField;
$session->setting->set('smsGateway', $origSmsGateway);
$testCache->flush; $testCache->flush;
} }