227 lines
7 KiB
Perl
227 lines
7 KiB
Perl
|
|
# This code was forked from the LiveJournal project owned and operated
|
||
|
|
# by Live Journal, Inc. The code has been modified and expanded by
|
||
|
|
# Dreamwidth Studios, LLC. These files were originally licensed under
|
||
|
|
# the terms of the license supplied by Live Journal, Inc, which can
|
||
|
|
# currently be found at:
|
||
|
|
#
|
||
|
|
# http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt
|
||
|
|
#
|
||
|
|
# In accordance with the original license, this code and all its
|
||
|
|
# modifications are provided under the GNU General Public License.
|
||
|
|
# A copy of that license can be found in the LICENSE file included as
|
||
|
|
# part of this distribution.
|
||
|
|
|
||
|
|
package LJ::NotificationMethod::Email;
|
||
|
|
|
||
|
|
use strict;
|
||
|
|
use v5.10;
|
||
|
|
use Log::Log4perl;
|
||
|
|
my $log = Log::Log4perl->get_logger(__PACKAGE__);
|
||
|
|
|
||
|
|
use Carp qw/ croak /;
|
||
|
|
|
||
|
|
use DW::Stats;
|
||
|
|
use LJ::Web;
|
||
|
|
|
||
|
|
use base 'LJ::NotificationMethod';
|
||
|
|
|
||
|
|
sub can_digest { 1 }
|
||
|
|
|
||
|
|
# takes a $u
|
||
|
|
sub new {
|
||
|
|
my $class = shift;
|
||
|
|
|
||
|
|
croak "no args passed"
|
||
|
|
unless @_;
|
||
|
|
|
||
|
|
my $u = shift;
|
||
|
|
croak "invalid user object passed"
|
||
|
|
unless LJ::isu($u);
|
||
|
|
|
||
|
|
my $self = { u => $u };
|
||
|
|
|
||
|
|
return bless $self, $class;
|
||
|
|
}
|
||
|
|
|
||
|
|
sub title { BML::ml('notification_method.email.title') }
|
||
|
|
|
||
|
|
sub new_from_subscription {
|
||
|
|
my $class = shift;
|
||
|
|
my $subs = shift;
|
||
|
|
|
||
|
|
return $class->new( $subs->owner );
|
||
|
|
}
|
||
|
|
|
||
|
|
sub u {
|
||
|
|
my $self = shift;
|
||
|
|
croak "'u' is an object method"
|
||
|
|
unless ref $self eq __PACKAGE__;
|
||
|
|
|
||
|
|
if ( my $u = shift ) {
|
||
|
|
croak "invalid 'u' passed to setter"
|
||
|
|
unless LJ::isu($u);
|
||
|
|
|
||
|
|
$self->{u} = $u;
|
||
|
|
}
|
||
|
|
croak "superfluous extra parameters"
|
||
|
|
if @_;
|
||
|
|
|
||
|
|
return $self->{u};
|
||
|
|
}
|
||
|
|
|
||
|
|
# send emails for events passed in
|
||
|
|
sub notify {
|
||
|
|
my $self = shift;
|
||
|
|
croak "'notify' is an object method"
|
||
|
|
unless ref $self eq __PACKAGE__;
|
||
|
|
|
||
|
|
my $u = $self->u;
|
||
|
|
my $vars = {
|
||
|
|
sitenameshort => $LJ::SITENAMESHORT,
|
||
|
|
sitename => $LJ::SITENAME,
|
||
|
|
siteroot => $LJ::SITEROOT
|
||
|
|
};
|
||
|
|
|
||
|
|
my @events = @_;
|
||
|
|
croak "'notify' requires one or more events"
|
||
|
|
unless @events;
|
||
|
|
|
||
|
|
foreach my $ev (@events) {
|
||
|
|
croak "invalid event passed" unless ref $ev;
|
||
|
|
|
||
|
|
$vars->{'hook'} = LJ::Hooks::run_hook( "esn_email_footer", $ev, $u );
|
||
|
|
my $footer = LJ::Lang::get_default_text( 'esn.footer.text2', $vars );
|
||
|
|
|
||
|
|
my $plain_body = LJ::Hooks::run_hook( "esn_email_plaintext", $ev, $u );
|
||
|
|
unless ($plain_body) {
|
||
|
|
$plain_body = $ev->as_email_string($u) or next;
|
||
|
|
|
||
|
|
# only append the footer if we can see this event on the subscription interface
|
||
|
|
$plain_body .= $footer if $ev->is_visible;
|
||
|
|
}
|
||
|
|
|
||
|
|
# Record stats about how long it has been since this user was active; we're doing
|
||
|
|
# some introspection on how much money we're spending sending emails to users who
|
||
|
|
# haven't used the site in a long time. Age in 30 day periods since login.
|
||
|
|
my $user_idle_since = int( ( time() - $u->get_timeactive ) / 86400 / 180 );
|
||
|
|
DW::Stats::increment( 'dw.mail.user_idle_since', 1, [ 'sixmonths:' . $user_idle_since ] );
|
||
|
|
|
||
|
|
# run transform hook on plain body
|
||
|
|
LJ::Hooks::run_hook(
|
||
|
|
"esn_email_text_transform",
|
||
|
|
event => $ev,
|
||
|
|
rcpt_u => $u,
|
||
|
|
bodyref => \$plain_body
|
||
|
|
);
|
||
|
|
|
||
|
|
my %headers = (
|
||
|
|
"X-LJ-Recipient" => $u->user,
|
||
|
|
%{ $ev->as_email_headers($u) || {} },
|
||
|
|
%{ $self->{_debug_headers} || {} }
|
||
|
|
);
|
||
|
|
|
||
|
|
my $email_subject = LJ::Hooks::run_hook( "esn_email_subject", $ev, $u )
|
||
|
|
|| $ev->as_email_subject($u);
|
||
|
|
|
||
|
|
if ($LJ::_T_EMAIL_NOTIFICATION) {
|
||
|
|
$LJ::_T_EMAIL_NOTIFICATION->( $u, $plain_body );
|
||
|
|
}
|
||
|
|
elsif ( $u->{opt_htmlemail} eq 'N' ) {
|
||
|
|
LJ::send_mail(
|
||
|
|
{
|
||
|
|
to => $u->email_raw,
|
||
|
|
from => $LJ::BOGUS_EMAIL,
|
||
|
|
fromname => scalar( $ev->as_email_from_name($u) ),
|
||
|
|
wrap => 1,
|
||
|
|
subject => $email_subject,
|
||
|
|
headers => \%headers,
|
||
|
|
body => $plain_body,
|
||
|
|
logger_mdc => {
|
||
|
|
userid => $u->id,
|
||
|
|
user => $u->user,
|
||
|
|
evt_userid => $ev->u->id,
|
||
|
|
evt_user => $ev->u->user,
|
||
|
|
evt_class => $ev->class,
|
||
|
|
evt_arg1 => $ev->arg1,
|
||
|
|
evt_arg2 => $ev->arg2,
|
||
|
|
},
|
||
|
|
}
|
||
|
|
) or die "unable to send notification email";
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
|
||
|
|
my $html_body = LJ::Hooks::run_hook( "esn_email_html", $ev, $u );
|
||
|
|
unless ($html_body) {
|
||
|
|
$html_body = $ev->as_email_html($u) or next;
|
||
|
|
$html_body =~ s/\n/\n<br\/>/g unless $html_body =~ m!<br!i;
|
||
|
|
|
||
|
|
my $html_footer =
|
||
|
|
LJ::Hooks::run_hook( 'esn_email_html_footer', event => $ev, rcpt_u => $u );
|
||
|
|
unless ($html_footer) {
|
||
|
|
$html_footer = LJ::auto_linkify($footer);
|
||
|
|
$html_footer =~ s/\n/\n<br\/>/g;
|
||
|
|
}
|
||
|
|
|
||
|
|
# convert newlines in HTML mail
|
||
|
|
$html_body =~ s/\n/\n<br\/>/g unless $html_body =~ m!<br!i;
|
||
|
|
|
||
|
|
# only append the footer if we can see this event on the subscription interface
|
||
|
|
$html_body .= $html_footer if $ev->is_visible;
|
||
|
|
|
||
|
|
# run transform hook on html body
|
||
|
|
LJ::Hooks::run_hook(
|
||
|
|
"esn_email_html_transform",
|
||
|
|
event => $ev,
|
||
|
|
rcpt_u => $u,
|
||
|
|
bodyref => \$html_body
|
||
|
|
);
|
||
|
|
}
|
||
|
|
LJ::send_mail(
|
||
|
|
{
|
||
|
|
to => $u->email_raw,
|
||
|
|
from => $LJ::BOGUS_EMAIL,
|
||
|
|
fromname => scalar( $ev->as_email_from_name($u) ),
|
||
|
|
wrap => 1,
|
||
|
|
subject => $email_subject,
|
||
|
|
headers => \%headers,
|
||
|
|
html => $html_body,
|
||
|
|
body => $plain_body,
|
||
|
|
logger_mdc => {
|
||
|
|
userid => $u->id,
|
||
|
|
user => $u->user,
|
||
|
|
evt_userid => $ev->u->id,
|
||
|
|
evt_user => $ev->u->user,
|
||
|
|
evt_class => $ev->class,
|
||
|
|
evt_arg1 => $ev->arg1,
|
||
|
|
evt_arg2 => $ev->arg2,
|
||
|
|
},
|
||
|
|
}
|
||
|
|
) or die "unable to send notification email";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
sub configured {
|
||
|
|
my $class = shift;
|
||
|
|
|
||
|
|
# FIXME: should probably have more checks
|
||
|
|
return $LJ::BOGUS_EMAIL && $LJ::SITENAMESHORT ? 1 : 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
sub configured_for_user {
|
||
|
|
my $class = shift;
|
||
|
|
my $u = shift;
|
||
|
|
|
||
|
|
# override requiring user to have an email specified and be active if testing
|
||
|
|
return 1 if $LJ::_T_EMAIL_NOTIFICATION;
|
||
|
|
|
||
|
|
return 0 unless length $u->email_raw;
|
||
|
|
|
||
|
|
# don't send out emails unless the user's email address is active
|
||
|
|
return $u->{status} eq "A" ? 1 : 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
1;
|