Skip to content

Instantly share code, notes, and snippets.

@manchicken
Last active September 29, 2020 15:31
Show Gist options
  • Save manchicken/cb96aa6da476f6f827287021e5f6acad to your computer and use it in GitHub Desktop.
Save manchicken/cb96aa6da476f6f827287021e5f6acad to your computer and use it in GitHub Desktop.
This is a quick-and-dirty script I put together to help me convert SMTP messages to JSON similar to what I would get in a Lambda. The reason I wanted this was because I have some files from S3 in buckets which were forwarded via a Lambda, but they're not in the format that SNS sends to the Lambda. I want to add extra processing to the Lambda bas…
#!/usr/bin/env perl
use Modern::Perl '2020';
use Carp qw/croak/;
use JSON;
use Email::MIME;
use IO::File;
sub get_smtp {
my $filename = shift;
# Grab the file name as the only
my $fh = IO::File->new($filename, 'r')
|| croak "Failed to open file «$filename» for reading: $!";
local $/ = undef
; # This enables slurp mode, so we can read the whole file in a single operation.
my $smtp_content = <$fh>;
my $smtp = Email::MIME->new($smtp_content);
# Since this is for test data generation only, we're simply pretending on some of this.
my $to_return = {
Records => [
{ EventSource => 'aws:sns',
EventVersion => '1.0',
EventSubscriptionArn =>
'arn:aws:sns:AWS_REGION:ACCOUNT_ID:TOPID_NAME:UUID',
Sns => {
Type => 'Notification',
MessageId => 'UUID',
TopicArn => 'arn:aws:sns:AWS_REGION:ACCOUNT_ID:TOPIC_NAME',
Subject => $smtp->header_raw('Subject'),
Timestamp => $smtp->header_raw('Date'),
SignatureVersion => '1',
Signature => $smtp->header_raw('DKIM-Signature')
|| 'SOME SIGNATURE',
SigningCertUrl =>
'https://sns.AWS_REGION.amazonaws.com/SimpleNotificationService-KEY_ID.pem',
UnsubscribeUrl =>
'https://sns.AWS_REGION.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:AWS_REGION:ACCOUNT_ID:TOPIC_NAME:UUID',
MessageAttributes => {},
Message => encode_json(
{
mail => {
headers => [
map {
{ name => $_,
value => join('; ', $smtp->header_raw($_))
}
} $smtp->header_names
],
destination => $smtp->header_raw('To'),
content => $smtp_content,
},
notificationType => 'Received',
'receipt' => {
'timestamp' => $smtp->header_raw('Date'),
'processingTimeMillis' => 536,
'recipients' => [ $smtp->header_raw('To') ],
'spamVerdict' => {
'status' => $smtp->header_raw('X-SES-Spam-Verdict')
|| 'PASS'
},
'virusVerdict' => {
'status' => $smtp->header_raw('X-SES-Virus-Verdict')
|| 'PASS'
},
'spfVerdict' => { 'status' => 'PASS' },
'dkimVerdict' => { 'status' => 'PASS' },
'dmarcVerdict' => { 'status' => 'PASS' },
'action' => {
'type' => 'SNS',
'topicArn' =>
'arn:aws:sns:AWS_REGION:ACCOUNT_ID:TOPIC_NAME',
'encoding' => 'UTF8'
},
},
}
)
}
}
]
};
return $to_return;
}
sub write_json {
my $filename = shift;
my $content_hashref = shift;
my $out_fh = IO::File->new($filename, 'w')
|| croak "Failed to open file «$filename» for writing: $!";
print $out_fh encode_json($content_hashref);
return;
}
my $arg_filename = shift @ARGV || croak 'No file name provided.';
write_json("$arg_filename.json", get_smtp($arg_filename));
say "Wrote «$arg_filename.json».";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment