Skip to content

Commit 3d85419

Browse files
feat: Add session state change emails (#7196)
1 parent 8612d91 commit 3d85419

File tree

14 files changed

+193
-78
lines changed

14 files changed

+193
-78
lines changed

app/api/helpers/mail.py

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
MONTHLY_PAYMENT_EMAIL,
2020
MONTHLY_PAYMENT_FOLLOWUP_EMAIL,
2121
NEW_SESSION,
22-
SESSION_ACCEPT_REJECT,
22+
SESSION_STATE_CHANGE,
2323
TEST_MAIL,
2424
TICKET_CANCELLED,
2525
TICKET_PURCHASED,
@@ -32,6 +32,9 @@
3232
from app.models.user import User
3333
from app.settings import get_settings
3434

35+
logger = logging.getLogger(__name__)
36+
# pytype: disable=attribute-error
37+
3538

3639
def check_smtp_config(smtp_encryption):
3740
"""
@@ -168,22 +171,39 @@ def send_email_new_session(email, event_name, link):
168171
)
169172

170173

171-
def send_email_session_accept_reject(email, session, link):
174+
def send_email_session_state_change(email, session):
172175
"""email for new session"""
173-
session_name = session.title
174-
session_acceptance = session.state
176+
event = session.event
177+
178+
settings = get_settings()
179+
app_name = settings['app_name']
180+
frontend_url = settings['frontend_url']
181+
session_link = "{}/events/{}/sessions/{}".format(
182+
frontend_url, event.identifier, session.id
183+
)
184+
event_link = f"{frontend_url}/e/{event.identifier}"
185+
186+
context = {
187+
'session_name': session.title,
188+
'session_link': session_link,
189+
'session_state': session.state,
190+
'event_name': event.name,
191+
'event_link': event_link,
192+
'app_name': app_name,
193+
'frontend_link': frontend_url,
194+
}
195+
196+
try:
197+
mail = MAILS[SESSION_STATE_CHANGE][session.state]
198+
except KeyError:
199+
logger.error('No mail found for session state change: ' + session.state)
200+
return
201+
175202
send_email(
176203
to=email,
177-
action=SESSION_ACCEPT_REJECT,
178-
subject=MAILS[SESSION_ACCEPT_REJECT]['subject'].format(
179-
session_name=session_name, acceptance=session_acceptance
180-
),
181-
html=MAILS[SESSION_ACCEPT_REJECT]['message'].format(
182-
email=email,
183-
session_name=session_name,
184-
acceptance=session_acceptance,
185-
link=link,
186-
),
204+
action=SESSION_STATE_CHANGE,
205+
subject=mail['subject'].format(**context),
206+
html=mail['message'].format(**context),
187207
)
188208

189209

app/api/helpers/notification.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
get_monthly_payment_follow_up_notification_actions,
1212
get_monthly_payment_notification_actions,
1313
get_new_session_notification_actions,
14-
get_session_accept_reject_notification_actions,
14+
get_session_state_change_notification_actions,
1515
get_ticket_purchased_attendee_notification_actions,
1616
get_ticket_purchased_notification_actions,
1717
get_ticket_purchased_organizer_notification_actions,
@@ -27,7 +27,7 @@
2727
MONTHLY_PAYMENT_FOLLOWUP_NOTIF,
2828
MONTHLY_PAYMENT_NOTIF,
2929
NEW_SESSION,
30-
SESSION_ACCEPT_REJECT,
30+
SESSION_STATE_CHANGE,
3131
TICKET_CANCELLED,
3232
TICKET_CANCELLED_ORGANIZER,
3333
TICKET_PURCHASED,
@@ -73,9 +73,9 @@ def send_notif_new_session_organizer(user, event_name, link, session_id):
7373
send_notification(user, title, message, actions)
7474

7575

76-
def send_notif_session_accept_reject(user, session_name, acceptance, link, session_id):
76+
def send_notif_session_state_change(user, session_name, acceptance, link, session_id):
7777
"""
78-
Send notification to the session creator about a session being accepted or rejected.
78+
Send notification to the session creator about a session status being changed.
7979
:param user:
8080
:param session_name:
8181
:param acceptance:
@@ -84,11 +84,11 @@ def send_notif_session_accept_reject(user, session_name, acceptance, link, sessi
8484
:return:
8585
"""
8686
message_settings = MessageSettings.query.filter_by(
87-
action=SESSION_ACCEPT_REJECT
87+
action=SESSION_STATE_CHANGE
8888
).first()
8989
if not message_settings or message_settings.notification_status == 1:
90-
actions = get_session_accept_reject_notification_actions(session_id, link)
91-
notification = NOTIFS[SESSION_ACCEPT_REJECT]
90+
actions = get_session_state_change_notification_actions(session_id, link)
91+
notification = NOTIFS[SESSION_STATE_CHANGE]
9292
title = notification['title'].format(
9393
session_name=session_name, acceptance=acceptance
9494
)
@@ -156,7 +156,7 @@ def send_notif_monthly_fee_payment(
156156
:return:
157157
"""
158158
message_settings = MessageSettings.query.filter_by(
159-
action=SESSION_ACCEPT_REJECT
159+
action=SESSION_STATE_CHANGE
160160
).first()
161161
if not message_settings or message_settings.notification_status == 1:
162162
actions = get_monthly_payment_notification_actions(event_id, link)
@@ -184,7 +184,7 @@ def send_followup_notif_monthly_fee_payment(
184184
:return:
185185
"""
186186
message_settings = MessageSettings.query.filter_by(
187-
action=SESSION_ACCEPT_REJECT
187+
action=SESSION_STATE_CHANGE
188188
).first()
189189
if not message_settings or message_settings.notification_status == 1:
190190
actions = get_monthly_payment_follow_up_notification_actions(event_id, link)

app/api/helpers/system_mails.py

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
PASSWORD_CHANGE,
2020
PASSWORD_RESET,
2121
PASSWORD_RESET_AND_VERIFY,
22-
SESSION_ACCEPT_REJECT,
2322
SESSION_SCHEDULE,
23+
SESSION_STATE_CHANGE,
2424
TEST_MAIL,
2525
TICKET_CANCELLED,
2626
TICKET_PURCHASED,
@@ -52,14 +52,74 @@
5252
+ u"<br/> Visit this link to fill up details: {link}"
5353
),
5454
},
55-
SESSION_ACCEPT_REJECT: {
55+
SESSION_STATE_CHANGE: {
5656
'recipient': 'Speaker',
57-
'subject': u'Session {session_name} has been {acceptance}',
58-
'message': (
59-
u"Hi {email},<br/>"
60-
+ u"The session <strong>{session_name}</strong> has been <strong>{acceptance}</strong> by the organizer. "
61-
+ u"<br/> Visit this link to view the session: {link}"
62-
),
57+
'pending': {
58+
'subject': 'Your speaker submission for {event_name} titled {session_name}',
59+
'message': "Hello,<br/><br/>"
60+
"This is an automatic message from {app_name}.<br/><br/>"
61+
"We have received your submission {session_name} for {event_name}<br/><br/>"
62+
"Your proposal will be reviewed by the event organizers and review team. The current status of your session is now \"Pending\".<br/><br/>"
63+
"You can also check the status and details of your submission on the session page {session_link}. You need to be logged in to view it.<br/><br/>"
64+
"More details about the event are on the event page at {event_link}.<br/><br/>"
65+
"Thank you.<br/>"
66+
"<a href='{frontend_link}'>{app_name}</a>",
67+
},
68+
'accepted': {
69+
'subject': 'Accepted! Congratulations Your submission for {event_name} titled {session_name} has been Accepted',
70+
'message': "Hello,<br/><br/>"
71+
"This is an automatic message from {app_name}.<br/><br/>"
72+
"Your session status for the submission {session_name} for {event_name} was changed to \"Accepted\". Congratulations!<br/><br/>"
73+
"Your proposal will be scheduled by the event organizers and review team. Please (re)confirm your participation with the organizers of the event, if required.<br/><br/>"
74+
"You can also check the status and details of your submission on the session page {session_link}. You need to be logged in to view it.<br/><br/>"
75+
"More details about the event are on the event page at {event_link}.<br/><br/>"
76+
"Thank you.<br/>"
77+
"<a href='{frontend_link}'>{app_name}</a>",
78+
},
79+
'confirmed': {
80+
'subject': 'Confirmed! Congratulations Your submission for {event_name} titled {session_name} has been Confirmed',
81+
'message': "Hello,<br/><br/>"
82+
"This is an automatic message from {app_name}.<br/><br/>"
83+
"Your session status for the submission {session_name} for {event_name} was changed to \"Confirmed\". Congratulations!<br/><br/>"
84+
"Your proposal will be scheduled by the event organizers and review team. Please inform the event organizers in case there are any changes to your participation.<br/><br/>"
85+
"You can also check the status and details of your submission on the session page {session_link}. You need to be logged in to view it.<br/><br/>"
86+
"More details about the event are on the event page at {event_link}.<br/><br/>"
87+
"Thank you.<br/>"
88+
"<a href='{frontend_link}'>{app_name}</a>",
89+
},
90+
'rejected': {
91+
'subject': 'Not Accepted. Your submission for {event_name} titled {session_name} was not accepted',
92+
'message': "Hello,<br/><br/>"
93+
"This is an automatic message from {app_name}.<br/><br/>"
94+
"Unfortunately your submission {session_name} for {event_name} was not accepted. Your session status was changed to \"Rejected\".<br/><br/>"
95+
"The status change was done by event organizers. If there are questions about this change please contact the organizers.<br/><br/>"
96+
"You can also check the status and details of your submission on the session page {session_link}. You need to be logged in to view it.<br/><br/>"
97+
"More details about the event are on the event page at {event_link}.<br/><br/>"
98+
"Thank you.<br/>"
99+
"<a href='{frontend_link}'>{app_name}</a>",
100+
},
101+
'canceled': {
102+
'subject': 'Canceled! Your submission for {event_name} titled {session_name} has been Canceled',
103+
'message': "Hello,<br/><br/>"
104+
"This is an automatic message from {app_name}.<br/><br/>"
105+
"Your session status for the submission {session_name} for {event_name} was changed to \"Canceled\".<br/><br/>"
106+
"The status change was done by event organizers. If there are questions about this change please contact the organizers.<br/><br/>"
107+
"You can also check the status and details of your submission on the session page {session_link}. You need to be logged in to view it.<br/><br/>"
108+
"More details about the event are on the event page at {event_link}.<br/><br/>"
109+
"Thank you.<br/>"
110+
"<a href='{frontend_link}'>{app_name}</a>",
111+
},
112+
'withdrawn': {
113+
'subject': 'Withdrawn! Your submission for {event_name} titled {session_name} has been Withdrawn',
114+
'message': "Hello,<br/><br/>"
115+
"This is an automatic message from {app_name}.<br/><br/>"
116+
"Your session status for the submission {session_name} for {event_name} was changed to \"Withdrawn\".<br/><br/>"
117+
"The status change was done by event organizers. If there are questions about this change please contact the organizers.<br/><br/>"
118+
"You can also check the status and details of your submission on the session page {session_link}. You need to be logged in to view it.<br/><br/>"
119+
"More details about the event are on the event page at {event_link}.<br/><br/>"
120+
"Thank you.<br/>"
121+
"<a href='{frontend_link}'>{app_name}</a>",
122+
},
63123
},
64124
SESSION_SCHEDULE: {
65125
'recipient': 'Owner, Organizer, Speaker',

app/api/helpers/system_notifications.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
NEW_SESSION,
1717
NEXT_EVENT,
1818
PASSWORD_CHANGE,
19-
SESSION_ACCEPT_REJECT,
2019
SESSION_SCHEDULE,
20+
SESSION_STATE_CHANGE,
2121
TICKET_CANCELLED,
2222
TICKET_CANCELLED_ORGANIZER,
2323
TICKET_PURCHASED,
@@ -201,9 +201,9 @@ def get_next_event_notification_actions(event_id, link):
201201
return [view_event_action]
202202

203203

204-
def get_session_accept_reject_notification_actions(session_id, link):
204+
def get_session_state_change_notification_actions(session_id, link):
205205
"""
206-
Get the actions associated with a notification of a session getting accepted/rejected.
206+
Get the actions associated with a notification of a session status being changed.
207207
:param session_id: id of the session.
208208
:param link: link to view the session.
209209
:return: actions
@@ -363,7 +363,7 @@ def get_invite_papers_notification_actions(cfs_link, submit_link):
363363
'message': u"Here are upcoming events: {up_coming_events}.",
364364
'recipient': 'Owner, Organizer, Speaker',
365365
},
366-
SESSION_ACCEPT_REJECT: {
366+
SESSION_STATE_CHANGE: {
367367
'title': u'Session {session_name} has been {acceptance}',
368368
'message': u"The session <strong>{session_name}</strong> has been"
369369
+ u" <strong>{acceptance}</strong> by the Organizer.",

app/api/helpers/tasks.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ def send_email_task_sendgrid(payload, headers, smtp_config):
100100
message.add_attachment(attachment)
101101
sendgrid_client = SendGridAPIClient(get_settings()['sendgrid_key'])
102102
logging.info(
103-
'Sending an email regarding {} on behalf of {}'.format(
104-
payload["subject"], payload["from"]
103+
'Sending an email to {} regarding "{}" on behalf of {}'.format(
104+
payload['to'], payload["subject"], payload["from"]
105105
)
106106
)
107107
try:

app/api/schema/message_settings.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
PASSWORD_RESET = 'Reset Password'
1515
PASSWORD_CHANGE = 'Change Password'
1616
EVENT_ROLE = 'Event Role Invitation'
17-
SESSION_ACCEPT_REJECT = 'Session Accept or Reject'
17+
SESSION_STATE_CHANGE = 'Session State Change'
1818
SESSION_SCHEDULE = 'Session Schedule Change'
1919
EVENT_PUBLISH = 'Event Published'
2020
AFTER_EVENT = 'After Event'
@@ -60,7 +60,7 @@ class Meta:
6060
USER_REGISTER,
6161
PASSWORD_RESET,
6262
EVENT_ROLE,
63-
SESSION_ACCEPT_REJECT,
63+
SESSION_STATE_CHANGE,
6464
SESSION_SCHEDULE,
6565
NEXT_EVENT,
6666
EVENT_PUBLISH,

app/api/sessions.py

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
from app.api.helpers.db import get_count, safe_query, safe_query_kwargs, save_to_db
1010
from app.api.helpers.errors import ForbiddenError
1111
from app.api.helpers.files import make_frontend_url
12-
from app.api.helpers.mail import send_email_new_session, send_email_session_accept_reject
12+
from app.api.helpers.mail import send_email_new_session, send_email_session_state_change
1313
from app.api.helpers.notification import (
1414
send_notif_new_session_organizer,
15-
send_notif_session_accept_reject,
15+
send_notif_session_state_change,
1616
)
1717
from app.api.helpers.permission_manager import has_access
1818
from app.api.helpers.query import event_query
@@ -259,7 +259,14 @@ def before_update_object(self, session, data, view_kwargs):
259259

260260
if new_state and new_state != session.state:
261261
# State change detected. Verify that state change is allowed
262-
g.send_email = new_state == 'accepted' or new_state == 'rejected'
262+
g.send_email = new_state in [
263+
'accepted',
264+
'rejected',
265+
'confirmed',
266+
'rejected',
267+
'canceled',
268+
'withdrawn',
269+
]
263270
key = 'speaker'
264271
if is_organizer:
265272
key = 'organizer'
@@ -294,32 +301,8 @@ def after_update_object(self, session, data, view_kwargs):
294301
""" Send email if session accepted or rejected """
295302

296303
if data.get('send_email', None) and g.get('send_email'):
297-
event = session.event
298-
# Email for speaker
299-
speakers = session.speakers
300-
for speaker in speakers:
301-
frontend_url = get_settings()['frontend_url']
302-
link = "{}/events/{}/sessions/{}".format(
303-
frontend_url, event.identifier, session.id
304-
)
305-
if not speaker.is_email_overridden:
306-
send_email_session_accept_reject(speaker.email, session, link)
307-
send_notif_session_accept_reject(
308-
speaker, session.title, session.state, link, session.id
309-
)
304+
notify_for_session(session)
310305

311-
# Email for owner
312-
if session.event.get_owner():
313-
owner = session.event.get_owner()
314-
owner_email = owner.email
315-
frontend_url = get_settings()['frontend_url']
316-
link = "{}/events/{}/sessions/{}".format(
317-
frontend_url, event.identifier, session.id
318-
)
319-
send_email_session_accept_reject(owner_email, session, link)
320-
send_notif_session_accept_reject(
321-
owner, session.title, session.state, link, session.id
322-
)
323306
if 'state' in data:
324307
entry_count = SessionsSpeakersLink.query.filter_by(session_id=session.id)
325308
if entry_count.count() == 0:
@@ -355,6 +338,28 @@ def after_update_object(self, session, data, view_kwargs):
355338
}
356339

357340

341+
def notify_for_session(session):
342+
event = session.event
343+
frontend_url = get_settings()['frontend_url']
344+
link = "{}/events/{}/sessions/{}".format(frontend_url, event.identifier, session.id)
345+
# Email for speaker
346+
speakers = session.speakers
347+
for speaker in speakers:
348+
if not speaker.is_email_overridden:
349+
send_email_session_state_change(speaker.email, session)
350+
send_notif_session_state_change(
351+
speaker.user, session.title, session.state, link, session.id
352+
)
353+
354+
# Email for owner
355+
if session.event.get_owner():
356+
owner = session.event.get_owner()
357+
send_email_session_state_change(owner.email, session)
358+
send_notif_session_state_change(
359+
owner, session.title, session.state, link, session.id
360+
)
361+
362+
358363
class SessionRelationshipRequired(ResourceRelationship):
359364
"""
360365
Session Relationship

app/models/mail.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
PASSWORD_CHANGE = 'Change Password'
1414
EVENT_ROLE = 'Event Role Invitation'
1515
USER_EVENT_ROLE = 'User Event Role Invitation'
16-
SESSION_ACCEPT_REJECT = 'Session Accept or Reject'
16+
SESSION_STATE_CHANGE = 'Session State Change'
1717
SESSION_SCHEDULE = 'Session Schedule Change'
1818
EVENT_PUBLISH = 'Event Published'
1919
AFTER_EVENT = 'After Event'

0 commit comments

Comments
 (0)