aboutsummaryrefslogtreecommitdiff
path: root/challenge-010
diff options
context:
space:
mode:
authorJoelle Maslak <jmaslak@antelope.net>2019-06-02 09:48:30 -0600
committerJoelle Maslak <jmaslak@antelope.net>2019-06-02 09:48:30 -0600
commitba97f6cab5d87017cd1f530d656379614fac3e56 (patch)
tree810210f4811378c724ae84e837df6f313ef877c5 /challenge-010
parentc9039ba2be7bf947bd3a7c686be74740c3d686b9 (diff)
downloadperlweeklychallenge-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-xchallenge-010/joelle-maslak/perl5/ch-3.pl99
-rw-r--r--challenge-010/joelle-maslak/perl5/ch-3.readme24
-rwxr-xr-xchallenge-010/joelle-maslak/perl6/ch-3.p685
-rw-r--r--challenge-010/joelle-maslak/perl6/ch-3.readme24
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. :)
+