159 lines
5.5 KiB
Python
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()
|