package Local::SendGrid; use v5.34; use Moo; use IO::All; use Data::Printer; use Types::Standard qw(HashRef); # Str ArrayRef Object # for Email::Sendgrid::V3 ------------------------------------------------------ use Email::SendGrid::V3; # for HTTP::Request/LWP::UserAgent --------------------------------------------- use HTML::Make; use LWP::UserAgent; use HTTP::Request (); use JSON::MaybeXS qw(encode_json); # ------------------------------------------------------------------------------ has msg => ( is => 'ro', isa => HashRef, required => 1 ); # ZBOX Ubuntu 22.04 key: my $api_key = io('/home/raj/.local/sendgrid_api_key')->slurp || die 'no api key'; # say $api_key; # default e-mail to/from (requires separate 'chomp' - wtf???): my $self_addr = io('/home/raj/.local/email_address')->slurp || die 'no default email addess'; chomp($self_addr); # say $self_addr; exit; # uses Email::SendGrid::V3 send() method, which uses HTTP::Tiny (https api url) # does not output very useful errors sub send { my $msg = shift->msg; # p $msg; $msg->{from} ||= $self_addr; $msg->{to} ||= $self_addr; $msg->{subject} or die "missing subject line"; grep $msg->{$_}, qw/html text/ or die "require text or html message"; my $sg = Email::SendGrid::V3->new( api_key => $api_key ) ->from( $msg->{from} ) ->subject( $msg->{subject} ) ->add_content( 'text/plain', $msg->{text} ) ->add_envelope( to => [ $msg->{to} ] ); # optional functions; sandbox tests message for compliance, does not send $sg->sandbox_mode(1) if $msg->{test_only}; $sg->footer(1, %{ $msg->{footer} }) if $msg->{footer}; # p $sg; return 0; my $result = $sg->send; # p $result; return $result->{success} ? "Email success" : "Email failure: " . $result->{reason}; } # manual message construction; uses HTTP::Request & LWP::UserAgent; constructs # same message data structure as Email::SendGrid::V3; outputs more userful errors sub _send { my $msg = shift->msg; # p $msg; $msg->{from} ||= $self_addr; $msg->{to} ||= $self_addr; my $ua = LWP::UserAgent->new(); # sendgrid api url: my $url = 'https://api.sendgrid.com/v3/mail/send'; my $header = [ 'Content-Type' => 'application/json; charset=UTF-8', 'Authorization' => "Bearer $api_key", ]; my %data = ( from => { email => $msg->{from} }, subject => $msg->{subject}, content => [ { type => 'text/plain', value => $msg->{text}, }, ], personalizations => [ { to => [ { email => $msg->{to} }, ], }, ], ); # p %data; exit; # test_only mode ? $data{mail_settings}{sandbox_mode} = { enable => JSON::true } if $msg->{test_only}; # optional footer: if ( my $footer = $msg->{footer} ) { $data{mail_settings} ||= {}; # not strictly necessary $data{mail_settings}{footer} = { enable => JSON::true, text => $footer->{text} || undef, html => _format_html_footer( $footer->{html} ) || undef, }; # p $data{mail_settings}; } p %data; my $encoded_data = encode_json(\%data); my $req = HTTP::Request->new('POST', $url, $header, $encoded_data); # p $req; exit; my $res = $ua->request($req); p $res; return $res->is_success ? 'Email success' : 'Email failure: ' . $res->status_line; } sub _format_html_footer { my $txt = shift || return; # optional my $obj = HTML::Make->new('footer'); # $obj->add_attr(class => 'beano'); $obj->add_text( $txt ); # say $obj->text; return $obj->text; }