send-mail/send_mail.py

159 lines
5.5 KiB
Python

# send_mail.py
# @author: Abner Coimbre <abner@handmadecities.com>
# Copyright (c) 2023 Handmade Cities
# ============================ Contributors =========================
# Bug & warning fixes
# Jacob Bell (@MysteriousJ)
# Asaf Gartner
#
# Emotional Support
# Cucui Ganon Rosario
# =========================================================================
# WARNING: send_mail.py requires a companion app.ini file provided by Abner. Without it the script will crash!
# QUICK NOTES:
#
# 1. This script is for Handmade meetup hosts. You can email a meetup invite to your group like so:
#
# > python3 send_mail.py --subject SUBJECT --body BODY
#
# where SUBJECT is the subject of your email and BODY is the file containing its contents. Plain text or HTML is supported
#
# 2. Your emails automatically include fancy Handmade Cities branding with unsubscribe links
#
# 3. You can dump the mailing list of your meetup group so far:
#
# > python3 send_mail.py --dump
#
# This list grows automatically as more people sign up for your city (at handmadecities.com/meetups)
import argparse
import configparser
import requests
import json
def dump_emails():
headers = {
"Content-Type": "application/json",
"Authorization": HMC_SHARED_SECRET
}
target = {
"city": HMC_CITY
}
# Request mailing list from Handmade Cities
payload = json.dumps(target)
response = requests.post(HMC_API_URL, headers=headers, data=payload)
emails = []
# Check if the request was successful (HTTP status code 200)
if response.status_code == 200:
# Parse the JSON response
response_json = response.json()
# Check if the 'emails' key exists in the response
if 'emails' in response_json:
# Extract the 'emails' JSON array
emails = response_json['emails']
return emails
def sendPostmarkMessage(subject, body, to):
headers = {
"Accept": "application/json",
"Content-Type": "application/json",
"X-Postmark-Server-Token": POSTMARK_SERVER_TOKEN
}
messages = []
# Postmark supports 500 messages per API call.
# Split the 'to' list into chunks of 500 or fewer email addresses
for i in range(0, len(to), 500):
to_chunk = to[i:i+500]
for email in to_chunk:
message = {
"From": POSTMARK_SENDER_EMAIL,
"To": email,
"TemplateId": POSTMARK_TEMPLATE_ID,
"TemplateModel": {
"name": SENDER_NAME,
"email": POSTMARK_SENDER_EMAIL,
"body": body,
"subject": subject
},
"MessageStream": POSTMARK_MESSAGE_STREAM
}
messages.append(message)
payload = {
"Messages": messages
}
# Debug:
# print(json.dumps(payload, indent=4))
result = requests.post(POSTMARK_API_URL, headers=headers, json=payload)
print(result.text)
# Clear the messages list for the next chunk
messages.clear()
if __name__ == '__main__':
# Create a ConfigParser object and read the INI file
config = configparser.ConfigParser()
config.read('app.ini')
# Read the values and store them in Python variables
LIVE = config.getboolean('DEFAULT', 'LIVE')
TEST_EMAIL = config.get('DEFAULT', 'TEST_EMAIL')
SENDER_NAME = config.get('DEFAULT', 'SENDER_NAME')
postmark_section = config['postmark']
POSTMARK_SERVER_TOKEN = postmark_section.get('SERVER_TOKEN')
POSTMARK_API_URL = postmark_section.get('API_URL')
POSTMARK_TEMPLATE_ID = int(postmark_section.get('TEMPLATE_ID'))
POSTMARK_SENDER_EMAIL = postmark_section.get('SENDER_EMAIL')
POSTMARK_MESSAGE_STREAM = postmark_section.get('MESSAGE_STREAM')
hmc_section = config['hmc']
HMC_API_URL = hmc_section.get('API_URL')
HMC_SHARED_SECRET = hmc_section.get('SHARED_SECRET')
HMC_CITY = hmc_section.get('CITY')
# Parse command-line arguments
parser = argparse.ArgumentParser(description="Handmade Meetups v0.1 (handmadecities.com/meetups)")
parser.add_argument("--dump", action="store_true", help="print the emails of your meetup group")
parser.add_argument("--subject", help="subject of the email you're about to send")
parser.add_argument("--body", help="path to the email body content file. HTML or plain text is supported")
args = parser.parse_args()
# Main:
meetup_group = []
if args.dump:
meetup_group = dump_emails()
print(f"Handmade Meetups - \033[1m{HMC_CITY}\033[0m\n")
max_index_width = len(str(len(meetup_group)))
for index, email in enumerate(meetup_group, start=1):
index_str = str(index).rjust(max_index_width) # Right-align the index
print(f"{index_str}. \033[1m{email}\033[0m")
print("\nMailing list grows automatically as more subscribe at \033[1mhandmadecities.com/meetups\033[0m")
elif args.subject and args.body:
subject = args.subject
body = ''
with open(args.body, 'r') as file:
body = file.read()
if LIVE:
meetup_group = dump_emails()
sendPostmarkMessage(subject, body, meetup_group)
else:
meetup_group.append(TEST_EMAIL) # Send a single email to whichever address is in TEST_EMAIL
sendPostmarkMessage(subject, body, meetup_group)
else:
parser.print_help()