Inspire your Friends using Go and Twilio Messaging

January 31, 2023
Written by
Dotun Jolaoso
Contributor
Opinions expressed by Twilio contributors are their own
Reviewed by

Inspire your Friends using Go and Twilio Messaging

In today’s fast-paced world, staying connected with friends can be a challenge. To help you stay in touch, in this tutorial, you’ll build a Go application that sends inspiring messages via SMS using Twilio Messaging Service to a list of your friends. As well as staying connected with friends, you'll also inspire them when going about their daily activities.

Prerequisites

To follow along, you’ll need the following:

Getting started

First, create a directory where the project will reside. From the terminal, run the following command:

mkdir twilio_inspire_friends
cd twilio_inspire_friends

Run the following command to create a new Go module in the root of your project directory.

go mod init twilio_inspire_friends

Next, install all the dependencies the project will need. These are:

  • godotenv: A library for importing environment variables from a .env file.
  • twilio-go: The Twilio Go helper library for interacting with Twilio’s REST APIs.

Run the following command to install all of the dependencies at once:

go get github.com/joho/godotenv github.com/twilio/twilio-go

Retrieve your Twilio credentials

You will need to obtain the Account SID, Auth Token and phone number associated with your Twilio account. These details can be obtained from the Keys & Credentials section on your Twilio Dashboard.

Twilio Keys & Credentials

After you've retrieved them, head back to the project’s directory and create a file named .env. Then, add the following details to the file:

TWILIO_ACCOUNT_SID=xxxx
TWILIO_AUTH_TOKEN=xxxx
RECIPIENTS=xxxx
TWILIO_MESSAGING_SERVICE_SID=xxxx

With the exception of the TWILIO_MESSAGING_SERVICE_ID field, replace the placeholders (“xxxx”) with their respective values. The RECIPIENTS field is a comma-separated list of phone numbers of the friends you will send the messages to. Each phone number must be in E.164 format.

Create a Messaging Service

The next step is to create a new Messaging Service tied to your Twilio account. To do that, in your Twilio Console, navigate to Explore Products > Messaging > Services and click Create Messaging Service.

Step 1. Create Messaging Service

Enter a name for the service in the “Messaging Service friendly name” field, and then click Create Messaging Service.

Step 2. Add Senders

Here, click Add Senders to start adding senders to the service. For the purpose of this tutorial, leave the Sender Type dropdown as “Phone Number”  and click Continue.

Next, check a Sender from the list with SMS capabilities and click Step 3: Set up integration. In this step, leave the options as they are and click Step 4: Add compliance info. In this step, leave the options as they are and click Complete Messaging Service Setup, and click View my new Messaging Service in the modal dialogue that appears.

Messaging Service Properties

Take note of the Messaging Service SID value and add it to the .env file in place of the (“xxxx”) placeholder.

Build the app

In the root of your project’s directory, create a new file named main.go and paste the following code in the file:

package main

import (
        "encoding/json"
        "fmt"
        "io"
        "log"
        "net/http"
        "os"
        "strings"
        "time"

        "github.com/joho/godotenv"
        "github.com/twilio/twilio-go"
        twilioApi "github.com/twilio/twilio-go/rest/api/v2010"
)

type Response struct {
        Status     string
        StatusCode int
        Method     string
        Body       []byte
}

type ZenQuotes struct {
        Quote  string `json:"q"`
        Author string `json:"a"`
}

func main() {
        err := godotenv.Load()
        if err != nil {
                log.Fatal(err)
        }

        response, err := sendRequest()
        if err != nil {
                log.Fatal(err)
        }

        var message ZenQuotes
        msg := []ZenQuotes{{
                message.Author,
                message.Quote,
        }}

        err = json.Unmarshal(response.Body, &msg)
        if err != nil {
                log.Fatal(err)
        }

        err = sendSms(msg[0].Quote)
        if err != nil {
                log.Fatal(err)
        }

        os.Exit(0)
}

func sendSms(message string) error {
        accountSid := os.Getenv("TWILIO_ACCOUNT_SID")
        authToken := os.Getenv("TWILIO_AUTH_TOKEN")
        messagingServiceSid := os.Getenv("TWILIO_MESSAGING_SERVICE_SID")

        client := twilio.NewRestClientWithParams(twilio.ClientParams{
                Username: accountSid,
                Password: authToken,
        })

        recipients := strings.Split(os.Getenv("RECIPIENTS"), ",")

        var failedRequests int
        var successRequests int

        for _, recipient := range recipients {
                params := &twilioApi.CreateMessageParams{}
                params.SetTo(recipient)
                params.SetMessagingServiceSid(messagingServiceSid)
                params.SetBody(message)

                _, err := client.Api.CreateMessage(params)
                if err != nil {
                        fmt.Println(err.Error())
                        failedRequests++
                        continue
                }

                successRequests++
        }

        var output string
        if failedRequests > 0 {
                output = fmt.Sprintf("%v messages could not be sent. Please check your Twilio logs for more information", failedRequests)
        } else {
                output = fmt.Sprintf("%v messages successfully sent", successRequests)
        }

        fmt.Println(output)

        return nil

}

func sendRequest() (*Response, error) {
        r := &Response{}

        httpClient := &http.Client{Timeout: 20 * time.Second}
        zenQuotesUrl := "https://zenquotes.io/api/random"

        req, err := http.NewRequest(http.MethodGet, zenQuotesUrl, nil)
        if err != nil {
                return nil, err
        }

        response, err := httpClient.Do(req)
        if err != nil {
                return nil, err
        }

        defer response.Body.Close()

        body, err := io.ReadAll(response.Body)
        if err != nil {
                return nil, err
        }

        r.Status = response.Status
        r.StatusCode = response.StatusCode
        r.Body = body

        return r, nil
}

Let’s go over what’s happening within the code you just pasted. The sendRequest() function is responsible for making a call to ZenQuotes to generate a random inspiring quote using the https://zenquotes.io/api/random endpoint.

The sendSms() function initializes a new Twilio Client object, by setting the Account SID, Auth token, and Messaging Service SID you defined as environment variables, earlier.

The list of recipients is then split and iterated over. For each recipient, it creates a message with the retrieved quote and sends it using the Twilio Client. The number of successful and failed requests is tracked and the result is printed at the end of the application's output to the terminal.

The main() function loads the environment variables and calls the sendRequest() and sendSms() functions respectively.

Testing

Run the application by using the following command

go run main.go

The people in the recipients list should have each received an inspiring quote, such as in the example below.

What's more, you should see output, similar to the example below, in your terminal.

1 messages successfully sent

In the event of an error, the error message will be displayed in your terminal. If the error is related to Twilio, it will be accompanied by a URL with an error code that can be clicked on. This will take you to Twilio’s Error and Warning Dictionary, which will help to facilitate further debugging.

Conclusion

In this tutorial, you’ve seen how you can inspire and stay connected with your friends and loved ones, by using Twilio Messaging and Go. This tutorial can serve as a great starting point for building communication tools that will allow you to stay connected to family, friends and loved ones using Twilio.

Dotun is a backend software engineer who enjoys building awesome tools and products. He also enjoys technical writing in his spare time. Some of his favorite programming languages and frameworks include Go, PHP, Laravel, NestJS, and Node.

Website: https://dotunj.dev/
GitHub: https://github.com/Dotunj
Twitter: https://twitter.com/Dotunj_

 

"Inspire :-)", by chattygd, licensed under CC BY 2.0.