Send SMS Messages with Cloud Functions For Firebase Gen 2

Amanda Cavallaro - Apr 11 - - Dev Community

Overview

We have a tutorial on How to Send and Receive SMS With Firebase Functions; this blog post tackles the same use case. However, we will create and deploy a second-generation HTTP function using the Google Cloud console and the Vonage Messages API instead of the SMS API.

Setup

You will need a few items to get going:

Firebase Setup

Create a Firebase project in the Firebase console.

Give your project a name that will generate a project ID that you will later choose from the terminal/ command prompt.

project creation

If you use Google Analytics, I will not do this project.

Google Analytics

Wait for project creation

Note: Remember to choose the pay-as-you-go billing plan; otherwise, you might get an error similar to "Error: Your project must be on the Blaze (pay-as-you-go) plan to complete this command. Required API artifactregistry.googleapis.com can't be enabled until the upgrade is complete."

Install the Firebase CLI from the command prompt/ terminal:

npm install -g firebase-tools
Enter fullscreen mode Exit fullscreen mode

Login and initialize your project from the command prompt/ terminal:

firebase login
firebase init
Enter fullscreen mode Exit fullscreen mode

You will be prompted to select diverse options, as seen below.

? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confirm your choices. Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision default instance, Functions: Configure a Cloud Functions directory and its files

? Please select an option: Use an existing project ? Select a default Firebase project for this directory: vonage-sms-project (vonage-sms-project) (Select here the name of the project you have created. In my case, it is vonage-sms-project (vonage-sms-project)

? It seems like you haven’t initialized Realtime Database in your project yet. Do you want to set it up? (Y/n) Choose Y

? Please choose the location for your default Realtime Database instance:

us-central1

❯ europe-west1

asia-southeast1

In my case Europe-west1 is the closest to me; choose the one that makes more sense to you.

? What file should be used for Realtime Database Security Rules? (database.rules.json)

? What language would you like to use to write Cloud Functions? (Use arrow keys)

❯ JavaScript (Choose JavaScript)

TypeScript

Python

? Do you want to use ESLint to catch probable bugs and enforce style? (y/N)

? Do you want to install dependencies with npm now? (Y/n) ChooseYes. And wait for the dependencies to be installed.

This will set up the required folders and files to get started.

Enable Google Cloud APIs

From the Google Cloud Console, enable the Cloud Functions, Cloud Build, Artifact Registry, Cloud Run, Logging, and Pub/Sub APIs.

First Function: InboundSMS

I’ll show you how to create and deploy the function from the IDE/ code editor. Alternatively, you can create functions from the Google Cloud Functions dashboard.

Open functions/index.js, delete all the code you can see and add the following code to capture incoming SMS messages and log them to the Firebase Realtime Database.

const { onRequest } = require("firebase-functions/v2/https");

const admin = require("firebase-admin");

admin.initializeApp();

exports.inboundSMS = onRequest(async (request, response) => {
  params = request.body;
  await admin.database().ref("/msgq").push(params);
  response.sendStatus(200);
});
Enter fullscreen mode Exit fullscreen mode

Deploy the function from the functions folder.

firebase deploy --only functions
Enter fullscreen mode Exit fullscreen mode

After the function is deployed, you will be given an HTTP URL needed to add to our webhook in the Vonage setup in the next session. It should look like something along the lines of https://us-central1-vonage-project.cloudfunctions.net/inboundSMS; or https://inboundsms-njjebckulq-uc.a.run.app.

Note: Note it because we will need it soon. In case you didn’t make a note of it, you can go to the Google Cloud Functions Overview page, click on the inboundSMS function, and you can find the URL right at the top.

You can find the URL right at the top

Vonage Setup

From the Vonage Dashboard, set the webhook URL for your number to the function endpoint URL from deployment. It should look like something along the lines of https://us-central1-vonage-project.cloudfunctions.net/inboundSMS or https://inboundsms-njjebckulq-uc.a.run.app.

Inbound SMS URL added to inbound and status

Install the Vonage Server SDK for Node.js (@vonage/server-sdk).

npm install @vonage/server-sdk
Enter fullscreen mode Exit fullscreen mode

Next, add dotenv to the dependency list.

npm install dotenv --save
Enter fullscreen mode Exit fullscreen mode

Add a file named .env with your Vonage credentials, which can be found in the Vonage Dashboard, and add the following environment variables:

Vonage Dashboard, red arrows showing where to find the API Key and the API Secret

VONAGE_API_KEY=
VONAGE_API_SECRET=
VONAGE_APPLICATION_ID=
VONAGE_PRIVATE_KEY=
Enter fullscreen mode Exit fullscreen mode

Add Vonage to your functions/index.js file.

const { Vonage } = require("@vonage/server-sdk");

const vonage = new Vonage({
  apiKey: VONAGE_API_KEY,
  apiSecret: VONAGE_API_SECRET,
  applicationId: VONAGE_APPLICATION_ID,
  privateKey: VONAGE_PRIVATE_KEY
});
Enter fullscreen mode Exit fullscreen mode

Make sure there's a phone number linked to this application.

Send an SMS to the virtual phone number you purchased and linked to this application.

If you head for your Firebase Realtime database on the dashboard, you can see the msgq node has been updated with the message you sent from your phone.

Second Function: SendSMS

Add the send function that will allow us to send the SMS Message Using the Vonage Messages API that will be logged in the Firebase Realtime database.

const { SMS } = require("@vonage/messages");

const { onValueCreated } = require("firebase-functions/v2/database"); 

exports.sendSMS = onValueCreated("/msgq/{pushId}", async (message) => {
  const { from, text } = message.data.val();

  vonage.messages
    .send(
      new SMS({
        text: text,
        to: from,
        from: "Vonage APIs",
      })
    )
    .then((resp) => console.log(resp))
    .catch((err) => console.error(err));
});
Enter fullscreen mode Exit fullscreen mode

Deploy the functions again from the functions folder.

firebase deploy --only functions
Enter fullscreen mode Exit fullscreen mode

Send an SMS to the virtual phone number you purchased and linked to this application.

If you head for your Firebase Realtime database on the dashboard, you can see the msgq node has been updated with the message you sent from your phone.

When a new message is added to /msgq, this function will be triggered. It will use the Vonage Messages API to respond to the user. The messages sent and submitted will be logged in our Firebase Realtime database.

Note: If you get an error message “Error: secretOrPrivateKey must be an asymmetric key when using ES256” make sure your private key is valid and correct and being imported correctly.

Test it Out

After it is deployed, test it out by sending an SMS message to the number linked to the Vonage application, and you will see the message added to the Firebase Realtime database.

Realtime database containing three nodes under msgq

Conclusion

Now, you can send and receive SMS messages using Firebase Cloud Functions Gen 2 and the Vonage Messages API! You have now completed all the steps for this tutorial. You can see the full code on GitHub.

Do you have any questions about this blog post? Join our Vonage Community Slack or message us on X.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .