Skip to content

Commit

Permalink
Various ics/google event improvements (Fixes #586, #588, and #584) (#595
Browse files Browse the repository at this point in the history
)

* Various ics/google event improvements (Fixes #586, #588, and #584)
* Include meeting link url in the location field
* Auto confirm/accept booked meetings
* Update the confirm email subject to include the name of the person who requested the booking
* Add test for meeting url in ics file
  • Loading branch information
MelissaAutumn authored Jul 31, 2024
1 parent 40412d5 commit ee65b66
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 12 deletions.
12 changes: 7 additions & 5 deletions backend/src/appointment/controller/calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,13 @@ def create_event(
body = {
'iCalUID': event.uuid.hex,
'summary': event.title,
'location': event.location.name,
'location': event.location.url if event.location.url else None,
'description': '\n'.join(description),
'start': {'dateTime': event.start.isoformat()},
'end': {'dateTime': event.end.isoformat()},
'attendees': [
{'displayName': organizer.name, 'email': organizer_email},
{'displayName': attendee.name, 'email': attendee.email},
{'displayName': organizer.name, 'email': organizer_email, 'responseStatus': 'accepted'},
{'displayName': attendee.name, 'email': attendee.email, 'responseStatus': 'accepted'},
],
'organizer': {
'displayName': organizer.name,
Expand Down Expand Up @@ -414,13 +414,14 @@ def create_vevent(
slot.start.replace(tzinfo=timezone.utc) + timedelta(minutes=slot.duration),
)
event.add('dtstamp', datetime.now(UTC))
event.add('status', 'CONFIRMED')
event['description'] = appointment.details
event['organizer'] = org

# Prefer the slot meeting link url over the appointment location url
location_url = slot.meeting_link_url if slot.meeting_link_url is not None else appointment.location_url

if location_url != '' or location_url is not None:
if location_url:
event.add('location', location_url)

cal.add_component(event)
Expand All @@ -435,10 +436,11 @@ def send_vevent(
attendee: schemas.AttendeeBase,
):
"""send a booking confirmation email to attendee with .ics file attached"""
ics = self.create_vevent(appointment, slot, organizer)
invite = Attachment(
mime=('text', 'calendar'),
filename='AppointmentInvite.ics',
data=self.create_vevent(appointment, slot, organizer),
data=ics,
)
background_tasks.add_task(send_invite_email, to=attendee.email, attachment=invite)

Expand Down
2 changes: 1 addition & 1 deletion backend/src/appointment/controller/mailer.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ def __init__(self, confirm_url, deny_url, attendee_name, attendee_email, date, *
self.date = date
self.confirmUrl = confirm_url
self.denyUrl = deny_url
default_kwargs = {'subject': l10n('confirm-mail-subject')}
default_kwargs = {'subject': l10n('confirm-mail-subject', {'attendee_name': self.attendee_name})}
super(ConfirmationMail, self).__init__(*args, **default_kwargs, **kwargs)

def text(self):
Expand Down
4 changes: 3 additions & 1 deletion backend/src/appointment/l10n/en/email.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ invite-mail-html = {-brand-footer}
## Confirm Appointment

confirm-mail-subject = Confirm booking request from {-brand-name}
# Variables
# $attendee_name (String) - Name of the person who requested the appointment
confirm-mail-subject = Action Required: Confirm booking request from { $attendee_name }
# Variables:
# $attendee_name (String) - Name of the person who requested the appointment
# $appointment_email (String) - Email of the person who requested the appointment
Expand Down
5 changes: 2 additions & 3 deletions backend/src/appointment/routes/schedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,15 +484,14 @@ def handle_schedule_availability_decision(
if os.getenv('SENTRY_DSN') != '':
capture_exception(err)


event = schemas.Event(
title=title,
start=slot.start.replace(tzinfo=timezone.utc),
end=slot.start.replace(tzinfo=timezone.utc) + timedelta(minutes=slot.duration),
description=schedule.details or '',
location=schemas.EventLocation(
type=schedule.location_type,
url=location_url,
type=models.LocationType.online,
url=slot.meeting_link_url if slot.meeting_link_url else location_url,
name=None,
),
uuid=slot.appointment.uuid if slot.appointment else None,
Expand Down
3 changes: 2 additions & 1 deletion backend/src/appointment/tasks/emails.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
ZoomMeetingFailedMail,
RejectionMail,
SupportRequestMail,
InviteAccountMail, ConfirmYourEmailMail,
InviteAccountMail,
ConfirmYourEmailMail,
)


Expand Down
2 changes: 1 addition & 1 deletion backend/test/factory/appointment_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def _make_appointment(

if not factory_has_value(slots):
make_appointment_slot(appointment_id=appointment.id)
else:
elif slots is not None:
repo.slot.add_for_appointment(db, slots, appointment.id)

# Refresh our appointment now that is has slot data
Expand Down
14 changes: 14 additions & 0 deletions backend/test/unit/test_calendar_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,17 @@ def test_events_roll_up_difference(self):
assert rolled_up_slots[0].booking_status == models.BookingStatus.booked
assert rolled_up_slots[1].booking_status == models.BookingStatus.requested
assert rolled_up_slots[2].booking_status == models.BookingStatus.booked


class TestVCreate:
def test_meeting_url_in_location(self, with_db, make_google_calendar, make_appointment, make_appointment_slot, make_pro_subscriber):
subscriber = make_pro_subscriber()
calendar = make_google_calendar(subscriber_id=subscriber.id)
appointment = make_appointment(calendar_id=calendar.id)
slot = appointment.slots[0]

slot.meeting_link_url = 'https://thunderbird.net'

ics = Tools().create_vevent(appointment, slot, subscriber)
assert ics
assert ':'.join(['LOCATION', slot.meeting_link_url])

0 comments on commit ee65b66

Please sign in to comment.