1package Sisimai::Lhost::GoogleGroups; 2use parent 'Sisimai::Lhost'; 3use feature ':5.10'; 4use strict; 5use warnings; 6 7sub description { 'Google Groups: https://groups.google.com' } 8sub make { 9 # Detect an error from Google Groups 10 # @param [Hash] mhead Message headers of a bounce email 11 # @param [String] mbody Message body of a bounce email 12 # @return [Hash] Bounce data list and message/rfc822 part 13 # @return [Undef] failed to parse or the arguments are missing 14 # @since v4.25.6 15 my $class = shift; 16 my $mhead = shift // return undef; 17 my $mbody = shift // return undef; 18 19 return undef unless rindex($mhead->{'from'}, '<mailer-daemon@googlemail.com>') > -1; 20 return undef unless index($mhead->{'subject'}, 'Delivery Status Notification') > -1; 21 return undef unless exists $mhead->{'x-failed-recipients'}; 22 return undef unless index($mhead->{'x-failed-recipients'}, '@googlegroups.com') > -1; 23 24 # Hello kijitora@libsisimai.org, 25 # 26 # We're writing to let you know that the group you tried to contact (group-name) 27 # may not exist, or you may not have permission to post messages to the group. 28 # A few more details on why you weren't able to post: 29 # 30 # * You might have spelled or formatted the group name incorrectly. 31 # * The owner of the group may have removed this group. 32 # * You may need to join the group before receiving permission to post. 33 # * This group may not be open to posting. 34 # 35 # If you have questions related to this or any other Google Group, 36 # visit the Help Center at https://groups.google.com/support/. 37 # 38 # Thanks, 39 # 40 # Google Groups 41 state $indicators = __PACKAGE__->INDICATORS; 42 state $rebackbone = qr/^-----[ ]Original[ ]message[ ]-----$/m; 43 44 my $dscontents = [__PACKAGE__->DELIVERYSTATUS]; 45 my $emailsteak = Sisimai::RFC5322->fillet($mbody, $rebackbone); 46 my $recordwide = { 'rhost' => '', 'reason' => '', 'diagnosis' => '' }; 47 my $recipients = 0; 48 my $v = $dscontents->[-1]; 49 50 # * You might have spelled or formatted the group name incorrectly. 51 # * The owner of the group may have removed this group. 52 # * You may need to join the group before receiving permission to post. 53 # * This group may not be open to posting. 54 my $fewdetails = [$emailsteak->[0] =~ /^[ ]?[*][ ]?/gm] || []; 55 $recordwide->{'reason'} = scalar @$fewdetails == 4 ? 'rejected' : 'onhold'; 56 57 my @entiremesg = split(/\n\n/, $emailsteak->[0], 5); pop @entiremesg; 58 my $diagnostic = join(' ', @entiremesg); $diagnostic =~ y/\n/ /; 59 $recordwide->{'diagnosis'} = Sisimai::String->sweep($diagnostic); 60 61 my $serverlist = Sisimai::RFC5322->received($mhead->{'received'}->[0]); 62 $recordwide->{'rhost'} = shift @$serverlist; 63 64 for my $e ( split(',', $mhead->{'x-failed-recipients'}) ) { 65 # X-Failed-Recipients: neko@example.jp, nyaan@example.org, ... 66 next unless index($e, '@googlegroups.com') > -1; 67 next unless Sisimai::RFC5322->is_emailaddress($e); 68 69 if( $v->{'recipient'} ) { 70 # There are multiple recipient addresses in the message body. 71 push @$dscontents, __PACKAGE__->DELIVERYSTATUS; 72 $v = $dscontents->[-1]; 73 } 74 $v->{'recipient'} = Sisimai::Address->s3s4($e); 75 $recipients++; 76 $v->{ $_ } = $recordwide->{ $_ } for keys %$recordwide; 77 } 78 return undef unless $recipients; 79 return { 'ds' => $dscontents, 'rfc822' => $emailsteak->[1] }; 80} 81 821; 83__END__ 84 85=encoding utf-8 86 87=head1 NAME 88 89Sisimai::Lhost::GoogleGroups - bounce mail parser class for C<Google Groups>. 90 91=head1 SYNOPSIS 92 93 use Sisimai::Lhost::GoogleGroups; 94 95=head1 DESCRIPTION 96 97Sisimai::Lhost::GoogleGroups parses a bounce email which created by C<Gmail>. 98Methods in the module are called from only Sisimai::Message. 99 100=head1 CLASS METHODS 101 102=head2 C<B<description()>> 103 104C<description()> returns description string of this module. 105 106 print Sisimai::Lhost::GoogleGroups->description; 107 108=head2 C<B<make(I<header data>, I<reference to body string>)>> 109 110C<make()> method parses a bounced email and return results as a array reference. 111See Sisimai::Message for more details. 112 113=head1 AUTHOR 114 115azumakuniyuki 116 117=head1 COPYRIGHT 118 119Copyright (C) 2020 azumakuniyuki, All rights reserved. 120 121=head1 LICENSE 122 123This software is distributed under The BSD 2-Clause License. 124 125=cut 126 127