This use case covers a scenario in which patients can schedule a medical appointment and get an appointment reminder over SMS or email. Similarly, users are asked if they want to receive a reminder to schedule a new follow-up appointment after the recommended time. We’ll do all this using our Infobip API Go SDK.

This project is a small CLI (Command Line Interface) that takes a user through a few menus and prompts them to set up a medical appointment. It then calls the Infobip API to send notifications and reminders.

Prerequisites

Project Overview

The code goes through a series of steps:

  1. Ask a user to choose from a doctor’s available time slots.
  2. Send a reminder before the appointment.
  3. Offer the user a reminder for a follow-up appointment and send it.

Setup

First, clone the repository.

git clone https://github.com/infobip-community/med-appointments.git

Before running the project, you must set a few constants with your account credentials, IB_BASE_URL and IB_API_KEY. You can get your credentials by logging into your Infobip account. Once you configured the variables, you can run this project with the following commands:

cd med-appointments
go get "github.com/infobip-community/infobip-api-go-sdk/v3"
go run main.go prompts.go

This will move the terminal to the cloned folder, install the SDK, and run the project.

Asking a user to choose from a doctor’s available time slots

After greeting a user, they can choose a slot from their doctor’s available dates:

appointment := promptDate("Choose a date for your appointment:", getAvailableDates(N_DATE_OPTS), N_DATE_OPTS)

We use the selected date to determine the scheduled dates to send the reminders.

channel := promptChannel("How would you like to be reminded?\n1) Email\n2) SMS")

Sending a reminder before appointment

We are using Email and SMS in this example, but many channels support scheduling messages.

Now, the interesting part: how to send scheduled messages! We’ll first send a reminder 24 hours before the appointment. First, we need to set up our client.

SMS and Email common set up

To do this, we first need to create an Infobip Client by calling the getInfobipClient() function. Where we create the infobip client to be used by both SMS and Email channels.

func getInfobipClient() infobip.Client {
    client, _ := infobip.NewClient(
        IB_BASE_URL,
        IB_API_KEY,
    )

    return client
}

Email-specific set up

Sending Emails requires you to set up a sender. An email sender should be first registered in the email configuration of your account. Then add your sender address in the EMAIL_FROM constant at the beginning of the code.

const (
    EMAIL_FROM = "<your-email-sender>"
    // ...
)

Calling the sendEmail or sendSMS functions

After this is set up, you can call the sendEmail or sendSMS functions. We’ll first send a reminder 24 hours before the appointment:

func sendAppointmentReminder(client infobip.Client, channel int, patient Patient, appointment time.Time) {
    subject := "Dr. Bip Appointment Reminder"
    text := fmt.Sprintf("%s, you have an appointment with Dr. Bip tomorrow!", patient.Name)
    date := appointment.AddDate(0, 0, -1)

    if channel == CHANNEL_EMAIL {
        sendEmail(client, EMAIL_FROM, patient.Email, subject, text, date)
    } else {
        sendSMS(client, patient.Phone, text, date)
    }
}

We do this by subtracting one day from the appointment date.

Now, to schedule our message, we use the sendAt fields in both Email and SMS models to specify the delivery date.

Scheduling an Email message

These are the details on how to call the Email API with the Go SDK:

func sendEmail(client infobip.Client, from string, to string, subject string, text string, sendAt time.Time) int {
    mail := models.EmailMsg{
        From:    from,
        To:      to,
        Subject: subject,
        Text:    text,
        BulkID:  fmt.Sprintf("appointments-%d", uuid.New()),
        SendAt:  sendAt.Format(time.RFC3339),
    }

    resp, respDetails, _ := client.Email.Send(context.Background(), mail)

    fmt.Printf("%+v\n", resp)
    fmt.Println(respDetails)

    return respDetails.HTTPResponse.StatusCode
}

Note that both Email and SMS require the time.Time object to be converted into RFC339 format in the request fields. Also, in both cases, we are specifying a BulkID which serves as a handle to identify your sent messages, but also to check their status or cancel sending them. We are using a UUID as part of the BulkID to assign every scheduled message a unique handle.

Scheduling an SMS message

And these are the details on how to call the SMS API with the Go SDK:

func sendSMS(client infobip.Client, to string, text string, sendAt time.Time) int {
    sms := models.SMSMsg{
        Destinations: []models.SMSDestination{
            {To: to},
        },
        Text:   text,
        SendAt: sendAt.Format(time.RFC3339),
    }
    request := models.SendSMSRequest{
        BulkID:   fmt.Sprintf("appointments-%d", uuid.New()),
        Messages: []models.SMSMsg{sms},
    }

    resp, respDetails, _ := client.SMS.Send(context.Background(), request)

    fmt.Printf("%+v\n", resp)
    fmt.Println(respDetails)

    return respDetails.HTTPResponse.StatusCode
}

Both the SendAt and BulkID work the same as with Emails. SendAt specifies a sending time in RFC3339 format, while the BulkID specifies a handle to manage the messages. Note that messages can only be scheduled 6 months in advance.

Offering and sending a reminder for a follow-up appointment

Doctors usually recommend a follow-up visit to check whether everything is OK with a treatment. This example assumes that the doctor recommended another visit in 30 days. We’ll ask a user if they’d like to receive a reminder before their next visit:

if promptYesNo("Do you want a reminder for a follow-up after the recommended period? (one month)") {
    sendFollowUpReminder(client, channel, patient, appointment)
}

To schedule this reminder, let’s use the sendAt field again, but this time add 25 days after the first appointment date.

date := appointment.AddDate(0, 0, 25)

And that’s it! I hope this helps you with your next project that needs scheduled communications.

In case you find any errors or you want to know more about response details, please check Infobip Response Status and Error Codes Reference. Go errors can be caught by enabling the anonymous variables _ through code and checking if they are nil or an Error object. To do this, just replace _ with err and check the err variable value after that.

Be sure to check the complete code in the Github Repository as well as the documentation pages for sending Email and sending SMS messages.