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 intoindex.js
. We'll step through the code below.Initialization
Review the following code:
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.
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
PROJECTID="YOUR_project_id"
ACCESSKEY="YOUR_access_key"
ACCESSSECRET="YOUR_access_secret"
app.js
File
const {SinchClient} = require('@sinch/sdk-core');
const sinchClient = new SinchClient({
projectId: process.env.PROJECTID,
keyId: process.env.ACCESSKEY,
keySecret: process.env.ACCESSSECRET
});
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:
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 variableautoReply
. - 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 variableautoReply
. - 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.
autoReply
: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 thestartServer
function beneath fastify.post
. It creates the group and starts the server.async function startServer() {
group = await sinchClient.sms.groups.create({
createGroupRequestBody: { name: "Sinch Pirates" },
});
fastify.listen({ port: portAddr }, () => {
console.log(`Listening at http://localhost:${portAddr}`);
});
}
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:
process.on("SIGINT", async (res, err) => {
console.log(group.id);
await sinchClient.sms.groups.delete({
group_id: group.id,
});
console.log(res);
fastify.close();
});
startServer
function:startServer();
This will be the first function called when we start our Node application.