# 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/g unless $html_body =~ m! $ev, rcpt_u => $u ); unless ($html_footer) { $html_footer = LJ::auto_linkify($footer); $html_footer =~ s/\n/\n/g; } # convert newlines in HTML mail $html_body =~ s/\n/\n/g unless $html_body =~ m!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;