I started this yesterday and stayed up until 2am working on it, just "finished" it now. The boss wanted a system that would allow her to invite people to book available times with her, ala Calendly.
I was like, buy another SaaS? No! I must build it!
Booking Buddy takes an email address and sends it a message containing buttons. Each button is an available time slot on the sender's calendar between two date ranges. When the recipient selects a date, Booking Buddy checks the sender's calendar *again* and makes sure that there is a match with the selected date. If there's no match, the recipient receives another email with an apology and an updated set of buttons to select from.
There are two versions:
- Booking Buddy Simple
- Can live in the Default Environment and can be shared purely with Run Only permissions (I submitted it as a template)
- Can only invite one email address per run.
- Booking Buddy Full
- Can invite multiple email addresses at once with a concurrency limit of 25
- Depends on Child Workflows, so it must live in a Solution
- Because Child Workflows cannot inherit connections, each user must have his/her own Child Workflow with the user's connections.
- Because Child Workflows must be created in a Solution, and can't be imported or added into it, my PowerApps System Administrator account just creates copies of the child workflow and adds connections for those users.
All of the problems with Booking Buddy Full would be solved if Power Automate would let us edit objects within arrays, so please check out that idea. Or let me know if there's a more popular equivalent out there.
For in this case let me showcase Booking Buddy Simple.
Link to PDF of the above.
Here's the "recipe":
- Manually trigger a flow with the following inputs
- Recipient - email address (1 only)
- Meeting Topic (text)
- Email Message (text)
- Meeting Duration (number) - in minutes
- Earliest Day (date)
- Latest Day (date)
- Configure settings
- Compose - Time Zone for Formulas (use Microsoft standard time zones)
- Compose - Time Zone for Outlook Calendar (use text value from dropdown list in Outlook Calendar steps)
- Compose - What Outlook calls the Default Calendar in Your Language (Calendar)
- Initialize variables
- DefaultCalendar (string, empty)
- AvailableTimes (string, empty)
- Scheduled (boolean, false)
- Attempts (integer, 0)
- Match (boolean, false)
- EmailBody (string, empty)
- Do Until Scheduled = true
- Get Available Times
- Clear AvailableTimes
- Outlook - Find meeting times (V2)
- Required attendees = Trigger -> User email
- Meeting duration = Trigger -> Meeting Duration
- Start time = converttoutc(concat(triggerBody()['date'],' 12:00 AM'),outputs('Time_Zone_for_Formulas'))
- End time = converttoutc(concat(triggerBody()['date_1'],' 11:59 PM'),outputs('Time_Zone_for_Formulas'))
- Max Candidates = 1000
- Activity Domain = Work
- For Each (outputs('Find_meeting_times_(V2)')?['body/meetingTimeSuggestions'])
- Append to AvailableTimes:
- replace(convertfromutc(concat(items('Populate_AvailableTimes_Variable')?['meetingTimeSlot']?['start']?['dateTime'],'z'),outputs('Time_Zone_for_Formulas'),'f'), ',', '')
- ,
- Compose - Add None of These option: concat(variables('AvailableTimes'),'None of these')
- Determine Email Body Text
- If Attempts = 0, Set EmailBody to Trigger -> EmailText
- Otherwise Set EmailBody to 'Sorry, it appears that time has already been booked. Please choose another.'
- Send email with options (Timeout: P7D)
- To: Trigger -> Recipient
- Subject: Select a Meeting Time for: Trigger -> Meeting Topic
- User Options: outputs('Add_None_of_These_option')
- Header Text: Let's meet
- Selection Text: Please select one of the following appointment times.
- Body: EmailBody
- If User Responded with a Time (Selected Option not equal to 'None of these' AND not equal to '')
- If True
- Get Available Times (copy of above steps)
- Compose: Split AvailableTimes
- For Each AvailableTime item
- If it matches user selected time
- Set Match to true
- Otherwise do nothing
- If Match is true
- Outlook: Get calendars (V2)
- For each calendar
- If name = outputs('What_Outlook_calls_the_Default_Calendar_in_Your_Language')
- Set DefaultCalendar to calendar
- Otherwise do nothing
- Outlook: Create event (V4)
- Calendar id: DefaultCalendar
- Subject: Meeting Topic
- Start Time: SelectedOption
- End Time: addMinutes(outputs('Send_email_with_options')?['body/SelectedOption'], triggerBody()['number'])
- Time Zone: outputs('Time_Zone_for_Outlook_Calendar')
- Required attendees: Trigger -> User email; Trigger -> Recipient
- Body: Trigger: Email Message
- Set Schedule = true
- Set Match = false
- OTHERWISE
- Increment Attempts by 1
- OTHERWISE
- Set Scheduled to TRUE