diff options
| author | Joelle Maslak <jmaslak@antelope.net> | 2019-06-02 09:48:30 -0600 |
|---|---|---|
| committer | Joelle Maslak <jmaslak@antelope.net> | 2019-06-02 09:48:30 -0600 |
| commit | ba97f6cab5d87017cd1f530d656379614fac3e56 (patch) | |
| tree | 810210f4811378c724ae84e837df6f313ef877c5 /challenge-010 | |
| parent | c9039ba2be7bf947bd3a7c686be74740c3d686b9 (diff) | |
| download | perlweeklychallenge-club-ba97f6cab5d87017cd1f530d656379614fac3e56.tar.gz perlweeklychallenge-club-ba97f6cab5d87017cd1f530d656379614fac3e56.tar.bz2 perlweeklychallenge-club-ba97f6cab5d87017cd1f530d656379614fac3e56.zip | |
Solution for week 10, problem 3 in P6 & P5
Diffstat (limited to 'challenge-010')
| -rwxr-xr-x | challenge-010/joelle-maslak/perl5/ch-3.pl | 99 | ||||
| -rw-r--r-- | challenge-010/joelle-maslak/perl5/ch-3.readme | 24 | ||||
| -rwxr-xr-x | challenge-010/joelle-maslak/perl6/ch-3.p6 | 85 | ||||
| -rw-r--r-- | challenge-010/joelle-maslak/perl6/ch-3.readme | 24 |
4 files changed, 232 insertions, 0 deletions
diff --git a/challenge-010/joelle-maslak/perl5/ch-3.pl b/challenge-010/joelle-maslak/perl5/ch-3.pl new file mode 100755 index 0000000000..134c9962c6 --- /dev/null +++ b/challenge-010/joelle-maslak/perl5/ch-3.pl @@ -0,0 +1,99 @@ +#!/usr/bin/env perl +use v5.26; +use strict; +use warnings; + +# Turn on method signatures +use feature 'signatures'; +no warnings 'experimental::signatures'; + +use autodie; +use Getopt::Long; +use Mojo::Util qw(url_escape); +use Mojo::UserAgent; +use Path::Tiny; +use Perl6::Slurp; + +# +# Copyright (C) 2019 Joelle Maslak +# All Rights Reserved - See License +# + +MAIN: { + my $configfile = path( $ENV{HOME} // "", ".sendgrid" )->stringify(); + my ( $from, $to, $subject, $bodytext, $sandbox ); + GetOptions( + "from=s" => \$from, + "to=s" => \$to, + "subject=s" => \$subject, + "body-text=s" => \$bodytext, + "config-file=s" => \$configfile, + ); + + die("Please provide --from") unless defined($from); + die("Please provide --to") unless defined($to); + die("Please provide --subject") unless defined($subject); + die("Please provide --bodytext") unless defined($bodytext); + + my $apikey = get_api_key($configfile); + + send_email( + apikey => $apikey, + from => $from, + to => [ split(';', $to) ], + subject => $subject, + bodytext => $bodytext, + sandbox => $sandbox, + ); +} + +sub get_api_key($configfile) { + my (@lines) = grep { length($_) } slurp($configfile); + die "Config-file ($configfile) must consist of one line" if @lines != 1; + chomp $lines[0]; + return $lines[0]; +} + +# Usage: +# The send_email function takes a hash with the following keys: +# apikey = Your Sendgrid API key +# from = Source email address +# to = *ARRAY REFERENCE* of destination email addresses +# subject = Subject of email +# sandbox = True if we are using the sandbox account +# +sub send_email(%args) { + my $url = 'https://api.sendgrid.com/v3/mail/send'; + + my %json = ( + personalizations => [ { to => [] } ], + from => { email => $args{from} }, + subject => $args{subject}, + content => [ + { + type => 'text/plain', + value => $args{bodytext}, + } + ], + ); + foreach my $email (sort $args{to}->@*) { + push $json{personalizations}->[0]{to}->@*, { email => $email }; + }; + + my $ua = Mojo::UserAgent->new(); + + $ua->once(start => sub ($ua, $tx) { + $tx->req->headers->header('Authorization' => "Bearer $args{apikey}"); + }); + + my $tx = $ua->post($url, json => \%json); + if ( ($tx->result->code >= 200) && ($tx->result->code <= 299) ) { return; } + + my $body = $tx->result->json; + if (exists $body->{errors}[0]{description}) { + die "Error from API endpoint: " . $body->{errors}[0]{description}; + } else { + die "Error from API endpoint: " . $body->{errors}[0]{message}; + } +} + diff --git a/challenge-010/joelle-maslak/perl5/ch-3.readme b/challenge-010/joelle-maslak/perl5/ch-3.readme new file mode 100644 index 0000000000..2208a272e3 --- /dev/null +++ b/challenge-010/joelle-maslak/perl5/ch-3.readme @@ -0,0 +1,24 @@ +This assumes there is a config file ~/.sendgrid which contains ONE line: + api-key (the actual value of the API key, not the string "api-key") + +MODULES REQUIRED: + Mojolicious + +To specify multiple email addresses using command line version of script, use +";" between addresses. + +See the source code for how to use the send-email() API implementation. + +For command line that uses that API implementation, pass the following: + + --from=<from email address> + --subject="<subject of email>" + --body="<body of email>" + +Example: + +perl6 ch-3.pl --from=jmaslak@antelope.net --to=jmaslak@antelope.net \ + --subject=Test --body-text="Test Message" + +No output means things went well. :) + diff --git a/challenge-010/joelle-maslak/perl6/ch-3.p6 b/challenge-010/joelle-maslak/perl6/ch-3.p6 new file mode 100755 index 0000000000..bc0f62c6d1 --- /dev/null +++ b/challenge-010/joelle-maslak/perl6/ch-3.p6 @@ -0,0 +1,85 @@ +#!/usr/bin/env perl6 +use v6; + +# +# Copyright © 2019 Joelle Maslak +# All Rights Reserved - See License +# + +use Cro::HTTP::Client; + +sub MAIN( + Str:D :$from, + Str:D :$to, + Str:D :$subject, + Str:D :$body-text, + Str:D :$config-file? = $*HOME.add(".sendgrid").Str, +) { + my $api-key = get-api-key($config-file); + + send-email(:$api-key, :$from, :to($to.split(';')), :$subject, :$body-text); +} + +sub get-api-key(Str:D $config-file -->Str:D) { + my @lines = $config-file.IO.lines().grep( *.chars > 0 ); + die "Config-file ($config-file) must consist of one line" if @lines.elems ≠ 1; + + return @lines[0]; +} + +# Usage: +# $api-key = Your Sendgrid API key +# $from = Source email address +# @to = Array of destination email addresses +# $subject = Subject of email +# $body-text = Text of email +# +sub send-email( + Str:D :$api-key, + Str:D :$from, + :@to, + Str:D :$subject, + Str:D :$body-text, +) { + my $url = "https://api.sendgrid.com/v3/mail/"; + + my $client = Cro::HTTP::Client.new( + base-uri => $url, + content-type => 'application/json', + headers => [ Authorization => "Bearer $api-key" ], + ); + + my @recipients; + for @to.unique -> $addr { + @recipients.push: %( email => $addr ); + } + + my %json = + personalizations => [ + %( + to => @recipients, + ), + ], + from => %( email => $from ), + subject => $subject, + content => [ + %( type => 'text/plain', value => $body-text ), + ], + ; + + my $resp = await $client.post('send', body => %json); + dd $resp; + return; + + CATCH { + when X::Cro::HTTP::Error { + my $body = await .response.body; + if $body<errors>[0]<description>:exists { + die "Error from API endpoint: $body<errors>[0]<description>"; + } else { + die "Error from API endpoint: $body<errors>[0]<message>"; + } + } + } +} + diff --git a/challenge-010/joelle-maslak/perl6/ch-3.readme b/challenge-010/joelle-maslak/perl6/ch-3.readme new file mode 100644 index 0000000000..74e2573266 --- /dev/null +++ b/challenge-010/joelle-maslak/perl6/ch-3.readme @@ -0,0 +1,24 @@ +This assumes there is a config file ~/.sendgrid which contains ONE line: + api-key (the actual value of the API key, not the string "api-key") + +MODULES REQUIRED: + Cro::HTTP::Client + +To specify multiple email addresses using command line version of script, use +";" between addresses. + +See the source code for how to use the send-email() API implementation. + +For command line that uses that API implementation, pass the following: + + --from=<from email address> + --subject="<subject of email>" + --body="<body of email>" + +Example: + +perl6 ch-3.p6 --from=jmaslak@antelope.net --to=jmaslak@antelope.net \ + --subject=Test --body-text="Test Message" + +No output means things went well. :) + |
