Skip to content

Commit

Permalink
Merge pull request #228 from cal-itp/feature/hubspot-update
Browse files Browse the repository at this point in the history
replacement of postmark with hubspot email API
  • Loading branch information
charlie-costanzo authored Mar 9, 2023
2 parents 6c3d1e4 + 7bf20df commit 6cf3ac7
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 110 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 3 additions & 6 deletions reports/config-example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,18 @@ month = 12
; month must be two digits (i.e 02) ensure leading zero
month_name = December
email_from = [email protected]
email_subject = GTFS Quality Reports from Cal-ITP
email_template = ../templates/email/report.mjml
is_development = True
track_links = HtmlAndText
track_opens = True
cc_email =
email_id=EMAIL_TEMPLATE_ID_FROM_HUBSPOT

[development]
email_csv_path = test_emails.csv
show_prompt = True
postmark_server_token = YOUR_SANDBOX_SERVER_TOKEN
hubspot_server_token = YOUR_SANDBOX_SERVER_TOKEN

[production]
is_development = False
email_csv_path = https://docs.google.com/spreadsheets/d/1AHFa5SKcEn7im374mPwULFCj7VlFchQr/export?gid=289636985&format=csv
show_prompt = True
email_csv_path = test_emails.csv
postmark_server_token = YOUR_PRODUCTION_SERVER_TOKEN
hubspot_server_token = YOUR_PRODUCTION_SERVER_TOKEN
81 changes: 33 additions & 48 deletions reports/generate_report_emails.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
# +
import configparser
import os
import sys

import hubspot
import pandas as pd
from hubspot.marketing.transactional import ApiException, PublicSingleSendRequestEgg

# This script generates a email body using mjml. The result itself has templated variables
# (TODO: update this section to remove outdated info) This script generates a email body using mjml. The result itself has templated variables
# of form {{SOME_VARIABLE_NAME}}, so we will use jinja to complete these email bodies
from jinja2 import Environment, StrictUndefined
from postmarker.core import PostmarkClient
from siuba import _, collect, mutate

jinja_env = Environment(undefined=StrictUndefined)
Expand All @@ -32,14 +31,13 @@
# Generate the report and dev link base to create report url

# +
SERVER_TOKEN = config["postmark_server_token"]
postmark = PostmarkClient(server_token=SERVER_TOKEN)
SERVER_TOKEN = config["hubspot_server_token"]
hubspot_client = hubspot.Client.create(access_token=SERVER_TOKEN)
PUBLISH_DATE_YEAR = config["year"]
PUBLISH_DATE_MONTH = config["month"]
PUBLISH_DATE_MONTH_NAME = config["month_name"]
PUBLISH_DATE_MONTH_INT = config["month"]

REPORT_LINK_BASE = (
f"https://reports.calitp.org/gtfs_schedule/{PUBLISH_DATE_YEAR}/{PUBLISH_DATE_MONTH}"
)
REPORT_LINK_BASE = f"https://reports.calitp.org/gtfs_schedule/{PUBLISH_DATE_YEAR}/{PUBLISH_DATE_MONTH_INT}"
# -
# TODO: need to ensure that the test_emails.csv and production email sheet use the
# same column names
Expand All @@ -56,57 +54,44 @@
)
report_emails


# +
# generate mjml template
stream = os.popen("npx mjml ../templates/email/report.mjml -s")
mjml_template = stream.read()


# for each row in report_emails, populate template
def _generate_template(report_url):
# render variables in template which use e.g. {{ month_name }} by passing in config
completed = jinja_env.from_string(mjml_template).render(**config, url=report_url)
return completed


html_messages = report_emails.report_url.apply(_generate_template)
all_emails = report_emails.main_email
all_emails_list = list(zip(all_emails, html_messages))

print("Using server token (Sandbox is f38...): " + config["postmark_server_token"])
# +
# Double check if we're on development that it is going to the sandbox ----
if config.getboolean("is_development"):
server = postmark.server.get()
assert server.DeliveryType == "Sandbox"
print("In sandbox environment")
print("Using development values from config.ini")
else:
print("In production environment")
print("Using production values from config.ini")

# Prompt user on whether to continue (if show_prompt specified) ----
if config.getboolean("show_prompt"):
result = input(
f"""
You are about to email the following {all_emails.count()} addresses: {", ".join(all_emails)}
You are about to email the following {report_emails["main_email"].count()} addresses: {", ".join(report_emails.main_email)}
To continue, type yes."""
)
if result != "yes":
raise Exception("Need yes to continue")


for emails, html_messages in all_emails_list:
email = postmark.emails.Email(
From=config["email_from"],
To=emails,
Cc=config["cc_email"],
Subject=config["email_subject"],
HtmlBody=html_messages,
TrackOpens=config["track_opens"],
TrackLinks=config["track_links"],
for index, email in report_emails.iterrows():
message = {
"from": config["email_from"],
"to": email["main_email"],
"replyTo": [config["email_from"]],
}
custom_properties = {
"month_name": PUBLISH_DATE_MONTH_NAME,
"url": email["report_url"],
}
public_single_send_request_egg = PublicSingleSendRequestEgg(
email_id=config["email_id"],
message=message,
custom_properties=custom_properties,
)
print(f"sending to emails: {emails}")
try:
email.send()
except BaseException as err:
print(f"failure to print to {emails}: {err}")
api_response = (
hubspot_client.marketing.transactional.single_send_api.send_email(
public_single_send_request_egg=public_single_send_request_egg
)
)
print(api_response)
except ApiException as e:
print("Exception when calling single_send_api->send_email: %s\n" % e)
6 changes: 6 additions & 0 deletions reports/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ MarkupSafe==2.1.1
postmarker==0.18.2
pre-commit==3.0.4
tomli==2.0.1
hubspot-api-client==7.5.0
16 changes: 12 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#
# This file is autogenerated by pip-compile with Python 3.8
# This file is autogenerated by pip-compile with Python 3.9
# by the following command:
#
# pip-compile
# pip-compile requirements.in
#
aiohttp==3.8.4
# via gcsfs
Expand All @@ -21,7 +21,9 @@ cachetools==5.3.0
calitp==2023.2.1
# via -r requirements.in
certifi==2022.12.7
# via requests
# via
# hubspot-api-client
# requests
cfgv==3.3.1
# via pre-commit
charset-normalizer==3.0.1
Expand Down Expand Up @@ -112,6 +114,8 @@ grpcio-status==1.48.2
# via google-api-core
gtfs-realtime-bindings==0.0.7
# via calitp
hubspot-api-client==7.5.0
# via -r requirements.in
humanize==4.6.0
# via calitp
identify==2.5.18
Expand Down Expand Up @@ -209,6 +213,7 @@ pyrsistent==0.19.3
python-dateutil==2.8.2
# via
# google-cloud-bigquery
# hubspot-api-client
# pandas
# pendulum
pytz==2022.7.1
Expand Down Expand Up @@ -236,6 +241,7 @@ siuba==0.4.2
six==1.16.0
# via
# google-auth
# hubspot-api-client
# jsonschema
# python-dateutil
sqlalchemy==1.4.46
Expand All @@ -253,7 +259,9 @@ typing-extensions==3.10.0.2
# calitp
# pydantic
urllib3==1.26.14
# via requests
# via
# hubspot-api-client
# requests
virtualenv==20.19.0
# via pre-commit
yarl==1.8.2
Expand Down
51 changes: 0 additions & 51 deletions templates/email/report.mjml

This file was deleted.

0 comments on commit 6cf3ac7

Please sign in to comment.