Send sms to phone number using GUPSHUP and nodejs - node.js

I need help in sending sms to user using nodejs and Gupshup.io . I'm facing difficulty understanding their documentation.

Khurram Shahzad
I work as a chatbot developer for Gupshup, please let me know what you don't understand.
Either way, here I'll share the snipet code to send an sms in node.js with our API.
const { default: axios } = require('axios');
/*
Variables to replace
YOUR_API_KEY => The unique identifier for a Gupshup account.
YOUR_APP_ID=> The unique identifier for an app. An app's appid can be found in the cURL request generated on the dashboard.
*/
const sendMessage = (msg, phone, callbackFunc) => {
const params = new URLSearchParams()
params.append('destination', phone);
params.append('message', msg);
params.append('source', 'GSDSMS'); //Required only for india
const config = {
headers: {
'apikey': YOUR_API_KEY,
'Content-Type': 'application/x-www-form-urlencoded'
}
}
axios.post('http://api.gupshup.io/sms/v1/message/:YOUR_APP_ID', params, config)
.then((result) => {
console.log('Message sent');
callbackFunc(result.data);
})
.catch((err) => {
console.log(err);
callbackFunc(err);
})
}
module.exports = {
sendMessage
}

Related

Server-side user verification with AWS Cognito user pool via MFA verification code (without password)

On the server side using NodeJS + NestJS, TS: 4.7.4, "aws-sdk": "^2.1138.0".
Trying to send a request to AWS Cognito, to obtain a verification code on mobile phone.
It's far away from achieving SMS quota.
An example of my method from the service:
async sendVerificationCode(phoneNumber: string) {
const params = {
AuthFlow: 'USER_SRP_AUTH',
ClientId: process.env.AWS_COGNITO_CLIENT_ID,
// UserPoolId: process.env.AWS_COGNITO_USER_POOL,
AuthParameters: {
USERNAME: phoneNumber,
SRP_A: generateSRPA(),
},
};
console.debug('=========== params: ', params);
try {
const result = await this.cognitoIdentityServiceProvider
.initiateAuth(params)
.promise();
console.log('=========== result: ', result);
return result;
} catch (error) {
if (error instanceof Error) {
console.debug('=========== Error: ', error.message);
throw error;
}
}
}
example of generation SRP_A:
const N_HEX ='EEAF0AB9ADB38DD69C33F80AFA...';
export function generateSRPA() {
const random = randomBytes(32);
const randomHex = random.toString('hex');
const srpA = createHash('sha256').update(randomHex).digest('hex');
return createHash('sha256').update(srpA).update(N_HEX).digest('hex');
}
Now requests are successfully sending to AWS and getting response:
=========== result: {
ChallengeName: 'PASSWORD_VERIFIER',
ChallengeParameters: {
SALT: '4e9b...',
SECRET_BLOCK: '4x1k...',
SRP_B: '161d...',
USERNAME: 'b1d9...',
USER_ID_FOR_SRP: 'b1d9...'
}
}
But I'm not receiving verification code on my phone.
In the same time with the same user pool and same mobile phone all the flow works fine on mobile app which is connected to Cognito.

twilio isn't sending sms nodejs

I use twilio to send sms after a order is placed, but it isn't sending any sms and also not console logging anything.
Code: npm i twilio
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = require("twilio")(accountSid, authToken);
exports.createOrder = (req, res) => {
const { orders, status, details } = req.body;
const order = new Order({
orders: orders,
status: status,
details: details,
});
order.save((error, order) => {
if (error) return res.status(400).json(error);
if (order) {
// if (res.status === 201) {
client.messages
.create({
body: "This is the ship that made the Kessel Run in fourteen parsecs?",
from: "+xxxxxxxxx",
to: "+xxxxxxxxxx",
})
.then((message) => console.log(message.sid));
// }
return res.status(201).json({ order });
}
});
};
LINK TO DOC (where I took the code) : https://www.twilio.com/docs/sms/quickstart/node
Twilio developer evangelist here.
There is likely an issue in sending your message, but the code you have is dropping errors, so you can't see what is going on. Try updating it to this:
client.messages
.create({
body: "This is the ship that made the Kessel Run in fourteen parsecs?",
from: "+xxxxxxxxx",
to: "+xxxxxxxxxx",
})
.then((message) => console.log(message.sid))
.catch(error => console.error(error));
Once you see what the error is, you will be able to fix it. My guess is that you have either configured your Account Sid and Auth Token incorrectly, or you are using a trial account and trying to send a message to a number you haven't verified yet, or you are trying to send a message to a country that isn't enabled.

How to Authenticate a Service Account for the Gmail API in Node Js?

So I'm using the Node.js Gmail library to send an email to another user. I was thinking of using a Service account to do just that. I've followed their documentation of passing the keyFile property but when I try to run the code, I get a 401 error, Login Required.
Here's what I got so far:
const { gmail } = require("#googleapis/gmail");
function createMessage(from, to, subject, message) {
// logic that returns base64 email
const encodedMail=[...];
return encodedMail;
}
export default function handler(req, res) {
const auth = gmail({
version: "v1",
keyFile: './google_service.json',
scopes: ["https://www.googleapis.com/auth/gmail.send"],
});
const raw = createMessage(
process.env.SERVICE_EMAIL,
"someone#gmail.com",
"Subject",
"This is a test",
);
const post = auth.users.messages.send({
userId: "me",
requestBody: {
raw,
},
});
post
.then((result) => {
console.log(result.data);
})
.catch((err) => {
console.log(err);
});
}
I've already got my Service Account credential json file and placed it at the root of my project. Is there something I'm doing wrong?

register webhooks on nodejs when order created

I have a shopify store mystore and I have an nodejs app myapp. I need to do is when something happens on mystore a webhook will be created/registered in my nodejs app. I have tried https://www.npmjs.com/package/#shopify/koa-shopify-webhooks this package but it is not working for me and I don't think that it is the same thing that I want. I just want that when let suppose order is created in store a webhook is registered.
if you just have to register a webhook you can use this code.
You just have to change the webhook topic and the endpoint.
This is for orders/create webhook registration
add shopify-api-node and request-promise packages and require them
const ShopifyAPIClient = require("shopify-api-node");
const request = require("request-promise");
then
const createOrderWebhook = await registerWebhook(yourShopDomain, yourShopAccessToken, {
topic: "orders/create",
address: "Your node app end point" //www.example.com/webhooks/createOrder,
format: "json",
});
add your registerWebhook function
const registerWebhook = async function (shopDomain, accessToken, webhook) {
const shopify = new ShopifyAPIClient({
shopName: shopDomain,
accessToken: accessToken,
});
const isCreated = await checkWebhookStatus(shopDomain, accessToken, webhook);
if (!isCreated) {
shopify.webhook.create(webhook).then(
(response) => console.log(`webhook '${webhook.topic}' created`),
(err) =>
console.log(
`Error creating webhook '${webhook.topic}'. ${JSON.stringify(
err.response.body
)}`
)
);
}
};
for checking the webhook already not created at Shopify you can use following code
const checkWebhookStatus = async function (shopDomain, accessToken, webhook) {
try {
const shopifyWebhookUrl =
"https://" + shopDomain + "/admin/api/2020-07/webhooks.json";
const webhookListData = {
method: "GET",
url: shopifyWebhookUrl,
json: true,
headers: {
"X-Shopify-Access-Token": accessToken,
"content-type": "application/json",
},
};
let response = await request.get(webhookListData);
if (response) {
let webhookTopics = response.webhooks.map((webhook) => {
return webhook.topic;
});
return webhookTopics.includes(webhook.topic);
} else {
return false;
}
} catch (error) {
console.log("This is the error", error);
return false;
}
};
Happy coding :)
You can not create/register a new webhook when the order created.
Webhooks are a tool for retrieving and storing data from a certain event. They allow you to register an https:// URL where the event data can be stored in JSON or XML formats. Webhooks are commonly used for:
Placing an order
Changing a product's price
Notifying your IM client or your pager when you are offline
Collecting data for data-warehousing
Integrating your accounting software
Filtering the order items and informing various shippers about the order
Removing customer data from your database when they uninstall your app

Authentication Error when Retrieving and Editing Device Configuration on IoT-Core

I'm trying to use a backend nodeJS server to access (and edit) the device configuration on IoT-Core referring to this API docs
However, I keep getting error:
code 401 with error message "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"status": "UNAUTHENTICATED".
I created a service account and a key from Google IAM, and gave it Cloud IoT Device Controller permissions, which could update device configurations but not create or delete. Subsequently, I changed it to Cloud IoT Admin and even Project Editor permissions, but still saw the same error message. Am I getting the keys all wrong, or not doing something else I should be doing?
Code below was how I invoked the request
function createJwt (projectId, privateKeyFile, algorithm) {
// Create a JWT to authenticate this device. The device will be disconnected
// after the token expires, and will have to reconnect with a new token. The
// audience field should always be set to the GCP project ID.
const token = {
'iat': parseInt(Date.now() / 1000),
'exp': parseInt(Date.now() / 1000) + 20 * 60, // 20 minutes
'aud': projectId
};
const privateKey = fs.readFileSync(privateKeyFile);
return jwt.sign(token, privateKey, { algorithm: algorithm });
}
app.get('/', function(req, res){
let authToken = createJwt('test-project', './keys/device-config.pem', 'RS256');
const options = {
url: 'https://cloudiot.googleapis.com/v1/projects/test-project/locations/us-central1/registries/dev-registry/devices/test-device',
headers: {
'authorization': 'Bearer ' + authToken,
'content-type': 'application/json',
'cache-control': 'no-cache'
},
json: true
}
request.get(options, function(error, response){
if(error) res.json(error);
else res.json(response);
})
});
For backend servers to interact with IoT-Core, the authentication method is not the same as for device MQTT or HTTP connections. Reference: https://cloud.google.com/iot/docs/samples/device-manager-samples#get_a_device
I was able to retrieve and update device configurations using the code below
function getClient (serviceAccountJson, cb) {
const serviceAccount = JSON.parse(fs.readFileSync(serviceAccountJson));
const jwtAccess = new google.auth.JWT();
jwtAccess.fromJSON(serviceAccount);
// Note that if you require additional scopes, they should be specified as a
// string, separated by spaces.
jwtAccess.scopes = 'https://www.googleapis.com/auth/cloud-platform';
// Set the default authentication to the above JWT access.
google.options({ auth: jwtAccess });
const DISCOVERY_API = 'https://cloudiot.googleapis.com/$discovery/rest';
const API_VERSION = 'v1';
const discoveryUrl = `${DISCOVERY_API}?version=${API_VERSION}`;
google.discoverAPI(discoveryUrl, {}, (err, client) => {
if (err) {
console.log('Error during API discovery', err);
return undefined;
}
cb(client);
});
}
function getDevice (client, deviceId, registryId, projectId, cloudRegion) {
const parentName = `projects/${process.env.GCP_PROJECT_ID}/locations/${cloudRegion}`;
const registryName = `${parentName}/registries/${registryId}`;
const request = {
name: `${registryName}/devices/${deviceId}`
};
const promise = new Promise(function(resolve, reject){
client.projects.locations.registries.devices.get(request, (err, data) => {
if (err) {
console.log('Could not find device:', deviceId);
console.log(err);
reject(err);
} else {
console.log(data.config.binaryData);
resolve(data);
}
});
});
return promise;
}
app.get('/', function(req, res){
const cb = function(client){
getDevice(client, 'test-device', 'dev-registry', process.env.GCP_PROJECT_ID, 'us-central1')
.then(function(response){
let decoded = new Buffer(response.config.binaryData, 'base64').toString();
res.json(decoded);
})
.catch(function(error){
res.json(error);
})
}
getClient(serviceAccountJson, cb);
});
I think what you're looking to do is best accomplished using the client library for NodeJS.
First, retrieve an API client object as done in the sample. This will take in the service account credentials you used and will authenticate against Google API Core servers.
At the point in the referenced code where cb(client); is invoked, you'll have your client object and are ready to update your device. Add the imports and API constants from the sample and replace the code where you have a client object with the following code and you should be set.
Use some strings for your device identifiers:
const projectId = 'my-project';
const cloudRegion = 'us-central1';
const registryId = 'my-registry';
const deviceId = 'my-device;
const config = '{fan: 800}';
Next, form your device String:
const deviceId = `projects/${projectId}/locations/${cloudRegion}/registries/${registryId}/devices/${deviceId}`;
const binaryData = Buffer.from(config).toString('base64');
Now you form your request object and execute:
const request = {
name: `${registryName}`,
versionToUpdate: 0,
binaryData: binaryData
};
console.log(request);
client.projects.locations.registries.devices
.modifyCloudToDeviceConfig(
request,
(err, data) => {
if (err) {
console.log('Could not update config:', deviceId);
console.log('Message: ', err);
} else {
console.log('Success :', data);
}
});
Your configuration is updated. If your device is subscribed to the config topic on MQTT it will receive the latest configuration, otherwise, you can poll for the configuration with HTTP from your device.
Just to confirm, when you created the SSL key pair, and when you registered the device with the Cloud IoT Core registry, did you match the type of key created with the radio button you registered it with?
Also to confirm, you put the Google root certificate on the device in the same directory as the private key: ./keys/device-config.pem ? If not you can fetch it with: wget https://pki.google.com/roots.pem.

Resources