Cover Image for Build a meeting conflict autoresponder with ChatGPT

Build a meeting conflict autoresponder with ChatGPT

TLDR;

Use Pipedream as a simple iPaaS

Use ChatGPT to generate a response to a meeting conflict


The Problem

I work at an agency and I also work fully remote, nearly a total asynchronous work environment. I'm also always leading multiple projects at any given time. In order to help my collegues work with me, I have to be very clear about my availability. The best way to do this is to keep my calendar up to date.

Ater being overwhelmed last year, I decided to start using a time blocking system to help me manage my time. My general proceses is to plan my next day and the end of the current day. I will use the afternoon planning session to block out time in the next day for the things that I need to get done.

Along with meetings and time blocks my schedule fills up quickly and I do wind up getting requests for meetings that conflict with time blocks and other meetings. To make responding to these requests easier, I decided to build a simple automation to help me.

Overview

First I setup a workflow in Pipedream to act as a simple iPaaS. Pipedream really excels when you need to connect services together and you also need to write custom code to handle the data that is being passed between the services.

Step 1: Trigger

The workflow is triggered when a new event is added to my Outlook calendar.

Trigger

Step 2: Parse the event

Parse out the event attributes that we are going to use later on in the workflow.

import ical from "node-ical";

// To use previous step data, pass the `steps` object to the run() function
export default defineComponent({
  async run({ steps, $ }) {
    /**
     * Exit if the organizer is yourself.
     * You can not create conflicts with events you have organized
     */
    if (steps.trigger.event.message.organizer.emailAddress.address.toLowerCase() == "[email protected]") {
      return $.flow.exit("Exit early");
    }
    
    let event = { subject: null, organizer: null, start: null, iCalUId: null};
    event.subject = steps.trigger.event.message.subject;
    event.organizer = steps.trigger.event.message.organizer.emailAddress;
    event.start = steps.trigger.event.message.start;
    event.iCalUId = steps.trigger.event.message.iCalUId;

    return event;
  },
})

Step 3: Get events

Get all the events that are scheduled for the same time as the new event.

Get events

Step 4: Check for conflicts

Check to see if any of the events pulled from the calendar in the previous step conflict with the new event.

import dateFormat, { masks } from "dateformat";

export default defineComponent({
  async run({ steps, $ }) {
    let found_events_arr = steps.microsoft_outlook.$return_value.value;
    for (let i=0; i < found_events_arr.length; i++) {
      let eventObj = found_events_arr[i];
      if (
        (steps.parse_event_trigger.$return_value.start.dateTime >= eventObj.start.dateTime &&
        steps.parse_event_trigger.$return_value.start.dateTime < eventObj.end.dateTime) &&
        steps.parse_event_trigger.$return_value.iCalUId != eventObj.iCalUId
      ) {
        const startLocale = new Date(eventObj.start.dateTime);
        let event = {
          start: dateFormat(startLocale.dateTime,"dddd, mmmm dS, yyyy, h:MM TT"),
          end: dateFormat(eventObj.end.dateTime,"dddd, mmmm dS, yyyy, h:MM TT"),
          subject: eventObj.subject,
          organizerName: eventObj.organizer.emailAddress.name,
          organizerEmail: eventObj.organizer.emailAddress.address
        };

        //Calendar conflict found
        return event;
      }
    }

    console.log('No conflicts detected, exit');
    $.flow.exit;
  },
})

Step 5: Generate the prompt

Generate a prompt to use ChatGPT for generating an email response to the organizer.

Ther are two prompts that I use, one for when the new event is conflicting with an existing event and one for when the new event is conflicting with a time block.

import dateFormat from "dateformat";

export default defineComponent({
  async run({ steps, $ }) {
    const start = dateFormat(steps.parse_event_trigger.$return_value.start.dateTime,"dddd, mmmm dS, yyyy, h:MM TT");
    if (steps.detect_conflict.$return_value.organizerEmail.toLowerCase() == "[email protected]") {
      //The conflict is owned by you. Create a prompt explaining that you have booked your time in advance.
      return `My name is Will Wright. ${steps.detect_conflict.$return_value.organizerName} is requesting a meeting with me but I have already blocked the time on my calendar. create a short email explaining to ${steps.detect_conflict.$return_value.organizerName} that I use time blocking for time management and I have already blocked my calendar for ${start} to do the following task: "${steps.detect_conflict.$return_value.subject}". Explain that if the meeting is more important than my task they should contact me via Slack. Sign the response "Will Wright's Digital Assistant". Do not start the response with "Subject"`;
    } else {
      /**
       * The conflict is owned by someone else. Explain that you have a meeting conflict at this
       * time and the organizer should try a different time.
       */
      return `create an email response to ${steps.trigger.event.message.organizer.emailAddress.name} who is trying to create a calendar invite that conflicts with an existing event. The existing event is ${steps.detect_conflict.$return_value.subject}, the organizer of the event is ${steps.detect_conflict.$return_value.organizerName} and the time of the event is ${steps.detect_conflict.$return_value.start}. Sign the response "Will Wright's Digital Assistant". Do not start the response with "Subject"`;
    }
  },
})

Step 6: Generate the response

Use ChatGPT to generate a response to the prompt.

ChatGPT response

An examples of each type of response:

Hi Co-Worker,

Thank you for reaching out and requesting a meeting. I wanted to let you know that I utilize time blocking as part of my time management strategy. I have already blocked my calendar for Monday, February 5th, 2024, from 7:00 PM onwards to complete the task of "Board Review".

If your meeting is urgent or more important than my current task, please feel free to contact me via Slack, and we can explore alternative options for scheduling.

Best regards,

Will Wright's Digital Assistant

Hi Co-Worker,

Thank you for reaching out. I wanted to inform you that the time you have chosen for the calendar invite conflicts with an existing event. The event in question is "Meeting Subject" organized by Co-Worker, and it is scheduled for Saturday, February 3rd, 2024, at 9:06 PM.

To avoid any scheduling conflicts, I would suggest choosing a different time for your calendar invite. Please let me know what other options could work for you, and I'll be happy to assist you further.

Best regards,

Will Wright's Digital Assistant

Step 7: Send a manual email

Instead of sending the email with the autogenerated response, I have the workflow send me an email with the response so that I can review it before sending it.

Manual review

Step 8: Send the email

Clicking the "Send it" link will send the email to the organizer of the conflicting event.

Clicking the "Cancel" link will stop the workflow and the email will not be sent.