diff --git a/infrastructure/api/lambda.tf b/infrastructure/api/lambda.tf index 34952a8..b7a6c18 100644 --- a/infrastructure/api/lambda.tf +++ b/infrastructure/api/lambda.tf @@ -7,6 +7,13 @@ resource "aws_lambda_function" "api" { memory_size = 512 role = aws_iam_role.api.arn + + environment { + variables = { + GMAIL_SENDER_ADDRESS = var.gmail_sender_address + GMAIL_SENDER_PASSWORD = var.gmail_sender_password + } + } } resource "aws_iam_role" "api" { diff --git a/infrastructure/api/vars.tf b/infrastructure/api/vars.tf index 72dca1d..fee06b4 100644 --- a/infrastructure/api/vars.tf +++ b/infrastructure/api/vars.tf @@ -4,4 +4,12 @@ variable "dynamodb_email_arn" { variable "dynamodb_polls_arn" { type = string +} + +variable "gmail_sender_address" { + type = string +} + +variable "gmail_sender_password" { + type = string } \ No newline at end of file diff --git a/infrastructure/modules.tf b/infrastructure/modules.tf index 684a70e..69cb94f 100644 --- a/infrastructure/modules.tf +++ b/infrastructure/modules.tf @@ -11,4 +11,6 @@ module "api" { source = "./api" dynamodb_email_arn = aws_dynamodb_table.emails.arn dynamodb_polls_arn = aws_dynamodb_table.polls.arn + gmail_sender_address = jsondecode(data.aws_secretsmanager_secret_version.gmail_credentials.secret_string)["GMAIL_SENDER_ADDRESS"] + gmail_sender_password = jsondecode(data.aws_secretsmanager_secret_version.gmail_credentials.secret_string)["GMAIL_SENDER_PASSWORD"] } \ No newline at end of file diff --git a/schafkopf/api/api.py b/schafkopf/api/api.py index 2aaa8a4..64e0a1e 100644 --- a/schafkopf/api/api.py +++ b/schafkopf/api/api.py @@ -3,6 +3,7 @@ from fastapi import FastAPI from schafkopf.api.models import SubscribeRequest, SubscribeResponse, PollResponse, SubscribeCountResponse +from schafkopf.core import gmail, bitpoll from schafkopf.core.dynamodb import email_table, poll_table app = FastAPI( @@ -17,6 +18,22 @@ def subscribe_to_schafkopf_rounds(req: SubscribeRequest) -> SubscribeResponse: import boto3 dynamodb = boto3.resource("dynamodb") email_table.add(dynamodb, req.to_email_item()) + + poll = poll_table.load(dynamodb) + poll_id = bitpoll.get_website_from_poll_id(poll.running_poll_id) + if poll.poll_is_running(): + print("Send invite email with poll link") + gmail.send_welcome_with_running_bitpoll( + receiver=req.email, + bitpoll_link=poll_id, + ) + else: + print('Send invite email with next date') + gmail.send_welcome_with_meeting_invitation( + receiver=req.email, + start=poll.next_schafkopf_event, + bitpoll_link=poll_id + ) return SubscribeResponse(email=req.email) diff --git a/schafkopf/core/gmail.py b/schafkopf/core/gmail.py index 827f5f1..69669fb 100644 --- a/schafkopf/core/gmail.py +++ b/schafkopf/core/gmail.py @@ -21,6 +21,16 @@ def send_bitpoll_invitation(receivers: List[str], bitpoll_link: str): ) +def send_welcome_with_running_bitpoll(receiver: str, bitpoll_link: str): + html = load_html_template(f"{env.BASE_PATH}/templates/welcome_with_poll_running.html") + html = html.replace("YOUR_BITPOLL_LINK_HERE", bitpoll_link) + + send( + receivers=[receiver], + subject="Welcome to our Schafkopf Round", + body=html + ) + def send_schafkopf_meeting_invitation(receivers: List[str], start: datetime, bitpoll_link: str): html = load_html_template(f"{env.BASE_PATH}/templates/schafkopf_scheduled.html") html = html.replace("SCHEDULED_DATE_PLACEHOLDER", format_datetime(start)) @@ -32,7 +42,22 @@ def send_schafkopf_meeting_invitation(receivers: List[str], start: datetime, bit body=html, attachment=create_calendar_entry( summary="[at] Schafkopfen", - start=start, end=start.replace(hour=23, minute=0), + start=start, + ) + ) + +def send_welcome_with_meeting_invitation(receiver: str, start: datetime, bitpoll_link: str): + html = load_html_template(f"{env.BASE_PATH}/templates/welcome_with_event_scheduled.html") + html = html.replace("SCHEDULED_DATE_PLACEHOLDER", format_datetime(start)) + html = html.replace("YOUR_BITPOLL_LINK_HERE", bitpoll_link) + + send( + receivers=[receiver], + subject="Welcome to our Schafkopf Round", + body=html, + attachment=create_calendar_entry( + summary="[at] Schafkopfen", + start=start ) ) @@ -67,7 +92,7 @@ def send( smtpserver.close() -def create_calendar_entry(start: datetime, end: datetime, summary: str) -> MIMEBase: +def create_calendar_entry(start: datetime, summary: str) -> MIMEBase: ics_content = f"""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//Schafkopf Scheduler//[at] Schafkopf @@ -75,7 +100,7 @@ def create_calendar_entry(start: datetime, end: datetime, summary: str) -> MIMEB UID:{env.get_gmail_sender_address()} DTSTAMP:{datetime.now().strftime('%Y%m%dT%H%M%SZ')} DTSTART:{start.strftime('%Y%m%dT%H%M%SZ')} -DTEND:{end.strftime('%Y%m%dT%H%M%SZ')} +DTEND:{start.replace(hour=23, minute=0).strftime('%Y%m%dT%H%M%SZ')} SUMMARY:[at] Schafkopfen DESCRIPTION:{summary} END:VEVENT diff --git a/templates/welcome_with_event_scheduled.html b/templates/welcome_with_event_scheduled.html new file mode 100644 index 0000000..1b00415 --- /dev/null +++ b/templates/welcome_with_event_scheduled.html @@ -0,0 +1,55 @@ + + + + + + Welcome to our Schafkopf-Round! + + + +

🃏Welcome to our round🃏

+

We are very happy to have you

+

Our bot will create new polls every two weeks and monitor it.

+

Once a day with the most participants (minimum 4) has been found, it will send out an invitation to everyone

+

Keep in mind that the bot is currently not able to find and book a restaurant, so please take care of it yourself

+
+

You can always look up the current state on our website

+

https://schafkopf.lukas-bernhard.de/

+
+

Feel free to join our next scheduled event at

+

SCHEDULED_DATE_PLACEHOLDER!

+
+

Cheers,

+

Your Favorite Schafkopf Organizer

+
+ + + \ No newline at end of file diff --git a/templates/welcome_with_poll_running.html b/templates/welcome_with_poll_running.html new file mode 100644 index 0000000..294731d --- /dev/null +++ b/templates/welcome_with_poll_running.html @@ -0,0 +1,55 @@ + + + + + + Welcome to our Schafkopf-Round! + + + +

🃏Welcome to our round🃏

+

We are very happy to have you

+

Our bot will create new polls every two weeks and monitor it.

+

Once a day with the most participants (minimum 4) has been found, it will send out an invitation to everyone

+

Keep in mind that the bot is currently not able to find and book a restaurant, so please take care of it yourself

+
+

You can always look up the current state on our website

+

https://schafkopf.lukas-bernhard.de/

+
+

Currently, we have a poll running, so

+

Vote Now!

+
+

Cheers,

+

Your Favorite Schafkopf Organizer

+
+ + + \ No newline at end of file