Creating a user consent application using the Node SDK

Creating the application

It's time to get the code for your application. Copy and paste the code from the right panel into index.js. We'll step through the code below.

Initialization

Review the following code:

Copy
Copied
const { SinchClient, SmsRegion } = require("@sinch/sdk-core");
const fastify = require("fastify")();
const portAddr = 3000;

const sinchClient = new SinchClient({
  projectId: "YOUR_project_id",
  keyId: "YOUR_access_key",
  keySecret: "YOUR_access_secret",
  region: "us/eu",
});

let group;
let autoReply;

This code sets up everything your application needs to function. First the Sinch SDK and Fastify web server are imported and a port number is initialized. Then an SDK client is created and initialized with your credentials.

To start using the SDK, you need to initialize the main client class with your credentials from your Sinch dashboard.

Copy
Copied
const {SinchClient} = require('@sinch/sdk-core');

const sinchClient = new SinchClient({
    projectId: "YOUR_project_id",
    keyId: "YOUR_access_key",
    keySecret: "YOUR_access_secret"
});
Note:

For testing purposes on your local environment it's fine to use hardcoded values, but before deploying to production we strongly recommend using environment variables to store the credentials, as in the following example:

.env File

Copy
Copied
PROJECTID="YOUR_project_id"
ACCESSKEY="YOUR_access_key"
ACCESSSECRET="YOUR_access_secret" 

app.js File

Copy
Copied
const {SinchClient} = require('@sinch/sdk-core');

const sinchClient = new SinchClient({
    projectId: process.env.PROJECTID,
    keyId: process.env.ACCESSKEY,
    keySecret: process.env.ACCESSSECRET
});
The region parameter has been included in this tutorial but it can be omitted, in which case the SDK will default to the US region. Finally a couple of variables are declared, which will store key information for your application to do its job.

Receiving incoming messages

Now we'll review the code that allows your app to recieve incoming messages:

Copy
Copied
fastify.post("/", async (request, reply) => {
  let message = request.body;
  let groupMembers = await sinchClient.sms.groups.listMembers({
    group_id: group.id,
  });
  if (message.body === "SUBSCRIBE" && !groupMembers.includes(message.from)) {
    await sinchClient.sms.groups.update({
      group_id: group.id,
      updateGroupRequestBody: { add: [message.from] },
    });

    autoReply =
      "Congratulations! You are now subscribed to " +
      group.name +
      ". Text STOP to leave this group.";
  } else if (message.body === "STOP" && groupMembers.includes(message.from)) {
    await sinchClient.sms.groups.update({
      group_id: group.id,
      updateGroupRequestBody: { remove: [message.from] },
    });
    autoReply =
      "We're sorry to see you go. You can always rejoin " +
      group.name +
      ' by texting SUBSCRIBE to ' +
      message.to;
  } else {
    autoReply =
      'Thanks for your interest. If you want to subscribe to this group, text SUBSCRIBE  to ' +
      message.to;
  }

});

This is similar to the application in the Receive an SMS Message guide. Its basic job is to listen for an inbound message and respond with an action. However, where the Receive Message app simply returned a reply containing the inbound message, this application contains relatively complex business logic to handle incoming requests appropriately.

Note:

While we need to create and delete a group for this demonstrative tutorial, it's worth noting that in production, recipients would probably be subscribing to, or unsubscribing from, a prexisting group.

The logic is designed to cover the following basic contingencies:

  • If a user is not already a group member and wants to join, the app looks for the SUBSCRIBE keyword. It then uses the SDK update method to add them to the group and assigns a confirmation message to the variable autoReply.
  • When a user is already a group member and wants to leave, the app looks for the STOP keyword. It then uses the SDK update method to remove them from the group and assigns a confirmation message to the variable autoReply.
  • If a user is not a group member but doesn't know the keyword to join, the application sends a message thanking them and telling them the right keyword.
The final code is for sending the confirmation messages assigned to autoReply:
Copy
Copied
let response = await sinchClient.sms.batches.send({
  sendSMSRequestBody: {
    to: [message.from],
    from: message.to,
    body: autoReply,
  },
});
console.log(JSON.stringify(response));
reply.type("application/json").code(200);

Starting the server

Now let's review the startServer function beneath fastify.post. It creates the group and starts the server.
Copy
Copied
async function startServer() {
  group = await sinchClient.sms.groups.create({
    createGroupRequestBody: { name: "Sinch Pirates" },
  });

  fastify.listen({ port: portAddr }, () => {
    console.log(`Listening at http://localhost:${portAddr}`);
  });
}
Fastify's listen method starts the server on the port number specified by portAddr. In this tutorial, startServer creates the group as well as starting the server. This is done for convenience, but in a real application, it would be much more efficacious to use a preexisting group. That way, you don't have to make a new one every time you start the app!

We don't want our Sinch Pirates group hanging around in the database. This callback will ensure our group is deleted as soon as we hit Ctrl+C:

Copy
Copied
process.on("SIGINT", async (res, err) => {
  console.log(group.id);
  await sinchClient.sms.groups.delete({
    group_id: group.id,
  });
  console.log(res);
  fastify.close();
});
Let's finish by adding a call to the startServer function:
Copy
Copied
startServer();

This will be the first function called when we start our Node application.


We'd love to hear from you!
Rate this content:
Still have a question?
 
Ask the community.