Automate Email Aggregation, Sending

by PMARINA312 in Circuits > Computers

132 Views, 0 Favorites, 0 Comments

Automate Email Aggregation, Sending

ed97d002f64232110d8a6db03528-1442549.jpg

Introduction - What is this?

If you do any amount of secretarial work for a club, this will likely help you save time. It downloads form responses from Google Drive, parses out emails, and even drafts/sends emails for you in gmail, allowing you to create clean, templated emails. No more "Did I put everyone in the bcc address? Did I remove the 'fw' from the subject? etc."

Setup

  1. Download Python 3
  2. This will install all the packages I used. I might be missing a couple so please ping me in the comments if you have any trouble:
    python -m pip install google-api-core google-api-python-client google-auth google-auth-httplib2 google-pasta googleapis-common-protos inflect oauthlib requests loguru tqdm
  3. Follow instructions from this StackOverflow answer to install the dns library. It will be important for email validation.
  4. Clone my repo: git clone https://github.com/PMARINA/Email-Aggregator.git
  5. Check out the main branch for my latest work git checkout main
  6. Download geckodriver from here, extract the executable and put it in the same directory as the code.

This should get the setup done. If you are interested in modifying my code (forking my repo), I highly recommend the following:

python -m pip install black pre-commit && pre-commit install

This will install formatters and a static analyzer to help you develop/debug.

Supplies

  • A computer
    • I built this on a Windows computer, but given that it's in python, it should be cross-platform compatible.

Configure Variables.py

Don't change the variable names, but rather just the strings. Some of the more important/relevant variables

  • INPUT_FILE: the file containing your events to include in emails
  • WEEKLY_*: Variables for weekly reminders I.
  • DATETIME_OUTPUT_FORMAT: Will determine what the dates and times look like in your emails
  • *LINK, *URL: These are specific to my organization. You will need to modify these to match your organization's marketing materials.
  • G_CLOUD_SECRETS_FILE: You will have to download the credentials.json from google cloud. This will let Google keep track of everyone using their APIs and shut down any DDOS attempts.
    • Navigate to your Google Cloud console.
    • Click "Create Credentials" at the top of the page
    • Select OAuth Client ID
    • Download the json file, move to the working directory, and put its name in this variable (ie "credentials.json").
  • TO, FROM, BCC_TO: use as you need. See code for how they are used

If you are looking to demo this, skip this step, except for the credentials step, as I'm not uploading mine since it can be abused.

Configure Event_Reminder.py, Weekly_Reminder.py

These are the various reminder types I am currently using. You can also create new reminder types. If you create a new Reminder type, look through the existing for guidance. Vitally:

  • Extend the base Reminder class
  • Generate your html and set the self.html variable to the string containing the html for the email you wish to send
  • Set self.recipients to the list or string of recipients.
  • Set self.subject as necessary.

This will be very different between organizations as we likely have differing content in our emails. If you were to add email tracking, you would likely want to do it at the bottom of the create_html method and integrate with google analytics.

Note: If you want to see how this works, just skip this step as my code works (and will create emails that look like my organization's)

Write Input.txt

This is a pretty fault-tolerant input format. It will ignore most whitespace. Any commented out lines (using #) will be ignored.

Each event must have the following structure (as defined in Event.py)

  • Event Name
  • Event Description (must be a single line)
  • The link to sign up (must redirect to a google form)
  • The date and time in the format "yyyy.mm.dd time", where time is in military format (no :, 24h)

There may be multiple datetime lines (ie if you run the same workshop twice in a week). As a result, every event in the file must be separated by at least one empty line.

Note that the sign up link is how the recipients are pulled for the event reminder. If you have multiple forms with the same name, it can pick any of the forms.

Run It!

  • You can run the main_weekly.py or main_reminder.py files to create drafts. You can also create new main files based on the existing ones.
  • To change the files to send emails instead of just saving them as drafts, change wk.create_draft to wk.send_email. However, I highly recommend not doing this because if you have any misconfigurations in your html, Variables.py, or input file, it will be sent out to your mailing list. Saving emails as drafts allows you a final chance to look things over.

Future Improvements

If you're interested in contributing to this repository, I will be accepting pull requests. My priorities for this project are:

  1. Clean up the code
    1. Add typing everywhere to help static analysis and promote clean, understandable code
    2. Condense some of my larger methods into more individual components (especially Drive.py)
  2. Pull my original email parsing code (which downloaded all CSVs and pulled emails) into the main branch and make more functional/clean. Likely into Mail.py
  3. Use less obtrusive scopes -- I don't need to read your email, but I am not aware of a way to request permission to create drafts without using such an inclusive scope.

Privacy Considerations

You can read the code, it's fully open-sourced. I don't take any information from you. Your information stays on your machine except for anything you put into email (created drafts/sent emails).

Your Drive files are examined only for matching forms and that too, locally, and nothing is done with that information except what you see happening in the Reminder files (getting recipients).

Your email is only used to create drafts and send email. Your mailbox is otherwise untouched.

Most importantly, I do not receive any usage data or other info from your use of my code.

Important waiver stuff: I think Instructables has something that protects itself and me to some extent, but just to be clear. You use my code at your risk. If anything goes wrong, i.e. you email something unintended, you accidentally spam/ddos anything/anyone; you assume full responsibility for it even if you use my code unmodified.