Skip to content

Commit

Permalink
Merge branch 'main' into devcontainer
Browse files Browse the repository at this point in the history
  • Loading branch information
faucomte97 authored Jan 18, 2024
2 parents 8d3535c + 98bb0f2 commit e59b322
Show file tree
Hide file tree
Showing 27 changed files with 2,204 additions and 57 deletions.
Empty file.
17 changes: 17 additions & 0 deletions .github/actions/email/send/Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
requests = "==2.31.0"

[dev-packages]
black = "==23.1.0"
pytest = "==7.2.1"
mypy = "==1.6.1"
pylint = "==3.0.2"
types-requests = "==2.31.0.10"

[requires]
python_version = "3.11"
374 changes: 374 additions & 0 deletions .github/actions/email/send/Pipfile.lock

Large diffs are not rendered by default.

154 changes: 154 additions & 0 deletions .github/actions/email/send/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
"""
© Ocado Group
Created on 29/12/2023 at 11:30:49(+00:00).
Using DotDigital, send a transactional email using a triggered campaign as its
content.
https://developer.dotdigital.com/reference/send-transactional-email-using-a-triggered-campaign
"""

import json
import os
import typing as t

import requests

JsonBody = t.Dict[str, t.Any]


def get_settings():
"""Gets the general settings from environment variables. Variables are
parsed to the correct type.
Returns:
A tuple with the values (region, auth, timeout).
"""

region = os.getenv("REGION", "")
assert region != "", "Region path parameter not set."

auth = os.getenv("AUTH", "")
assert auth != "", "Authorization header not set."

timeout = int(os.getenv("TIMEOUT", "-1"))
assert timeout != -1, "Request timeout not set."

return region, auth, timeout


def get_json_body() -> JsonBody:
"""Gets the JSON body from environment variables. Variables are parsed to
the correct type.
Returns:
A dictionary containing the request's JSON body.
"""

body: JsonBody = {}

def set_value(
env_key: str,
body_key: str,
required: bool,
json_loads: bool = True,
):
"""Helper to parse environment variables into body parameters.
Args:
env_key: The key of the environment variable.
body_key: The key of the body parameter.
required: If this value is required in the request.
json_loads: If the value should be parsed as a JSON object. Strings
don't need to be parsed as JSON.
"""

raw_value = os.getenv(env_key, "")

if required:
assert raw_value != "", f'"{env_key}" environment variable not set.'

if raw_value != "":
body[body_key] = json.loads(raw_value) if json_loads else raw_value

set_value(
env_key="TO_ADDRESSES",
body_key="toAddresses",
required=True,
)
set_value(
env_key="CC_ADDRESSES",
body_key="ccAddresses",
required=False,
)
set_value(
env_key="BCC_ADDRESSES",
body_key="bccAddresses",
required=False,
)
set_value(
env_key="FROM_ADDRESS",
body_key="fromAddress",
required=False,
json_loads=False,
)
set_value(
env_key="CAMPAIGN_ID",
body_key="campaignId",
required=True,
)
set_value(
env_key="PERSONALIZATION_VALUES",
body_key="personalizationValues",
required=False,
)
set_value(
env_key="METADATA",
body_key="metadata",
required=False,
json_loads=False,
)
set_value(
env_key="ATTACHMENTS",
body_key="attachments",
required=False,
)

return body


def send_email(region: str, auth: str, timeout: int, body: JsonBody):
"""Sends the email.
Args:
region: The API region to use.
auth: The authorization header used to authenticate with the API.
timeout: The number of seconds to wait before the request times out.
body: The request's JSON body.
"""

response = requests.post(
url=f"https://{region}-api.dotdigital.com/v2/email/triggered-campaign",
json=body,
headers={
"accept": "text/plain",
"authorization": auth,
},
timeout=timeout,
)

assert response.ok, response.json()


def main():
"""Entry point."""

region, auth, timeout = get_settings()

body = get_json_body()

send_email(region, auth, timeout, body)


if __name__ == "__main__":
main()
62 changes: 62 additions & 0 deletions .github/actions/email/send/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: "Code for Life - Email - Send"
description: "Using DotDigital, send a transactional email using a triggered campaign as its content."
inputs:
region:
description: "The Dotdigital region id your account belongs to e.g. r1, r2 or r3."
required: true
default: "r1"
auth:
description: "The authorization header used to authenticate with the api."
required: true
timeout:
description: "The number of seconds to wait for a response before timing out."
required: true
default: "60"
to-addresses:
description: "The email address(es) to send to."
required: true
cc-addresses:
description: "The CC email address or address to to send to. separate email addresses with a comma. Maximum: 100."
required: false
bcc-addresses:
description: "The BCC email address or address to to send to. separate email addresses with a comma. Maximum: 100."
required: false
from-address:
description: "The From address for your email. Note: The From address must already be added to your account. Otherwise, your account's default From address is used."
required: false
campaign-id:
description: "The ID of the triggered campaign, which needs to be included within the request body."
required: true
personalization-values:
description: "Each personalisation value is a key-value pair; the placeholder name of the personalization value needs to be included in the request body."
required: false
metadata:
description: "The metadata for your email. It can be either a single value or a series of values in a JSON object."
required: false
attachments:
description: "A Base64 encoded string. All attachment types are supported. Maximum file size: 15 MB."
required: false
runs:
using: composite
steps:
- uses: ocadotechnology/codeforlife-workspace/.github/actions/python/setup-environment@main
with:
python-version: 3.11
working-directory: ${{ github.action_path }}

- name: 📧 Send Email
shell: bash
working-directory: ${{ github.action_path }}
run: pipenv run python .
env:
REGION: ${{ inputs.region }}
AUTH: ${{ inputs.auth }}
TIMEOUT: ${{ inputs.timeout }}
TO_ADDRESSES: ${{ inputs.to-addresses }}
CC_ADDRESSES: ${{ inputs.cc-addresses }}
BCC_ADDRESSES: ${{ inputs.bcc-addresses }}
FROM_ADDRESS: ${{ inputs.from-address }}
CAMPAIGN_ID: ${{ inputs.campaign-id }}
PERSONALIZATION_VALUES: ${{ inputs.personalization-values }}
METADATA: ${{ inputs.metadata }}
ATTACHMENTS: ${{ inputs.attachments }}
42 changes: 42 additions & 0 deletions .github/actions/python/setup-environment/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: "Code for Life - Python - Setup Environment"
description: "Set up a python environment."
inputs:
checkout:
description: "A flag to designate if the code should be checked out."
required: true
default: "true"
python-version:
description: "The python version to set up."
required: true
default: "3.8"
working-directory:
description: "The current working directory."
required: true
default: "."
install-args:
description: "Arguments to pass to pipenv install."
required: false
runs:
using: composite
steps:
- name: 🛫 Checkout
if: ${{ inputs.checkout == 'true' }}
uses: actions/checkout@v4

- name: 🐍 Set up Python ${{ inputs.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ inputs.python-version }}

- name: ⬆️ Upgrade pip
shell: bash
run: python -m pip install --upgrade pip

- name: 🛠 Install pipenv
shell: bash
run: python -m pip install pipenv

- name: 🛠 Install Dependencies
shell: bash
working-directory: ${{ inputs.working-directory }}
run: pipenv install ${{ inputs.install-args }}
55 changes: 0 additions & 55 deletions .github/actions/python/test/action.yaml

This file was deleted.

Empty file.
16 changes: 16 additions & 0 deletions .github/scripts/python/validate-existing-contributors/Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]

[dev-packages]
black = "==23.1.0"
pytest = "==7.2.1"
mypy = "==1.6.1"
pylint = "==3.0.2"
types-requests = "==2.31.0.10"

[requires]
python_version = "3.11"
Loading

0 comments on commit e59b322

Please sign in to comment.