Implemented In Nodejs
using node-smpp library and Selenium SMPPSim Simulator
const smpp = require('smpp');
const session = new smpp.Session({host: 'localhost', port: 1234});
session.on('connect', () => {
isConnected = true;
session.bind_transceiver({
system_id: "SYSTEMID",
password: "PASSWORD",
}, (pdu) => {
if (pdu.command_status == 0) {
console.log('smpp connected !')
}
})
})
//**all pdu listener**
session.on('pdu', (pdu)=>{
console.log(pdu)
})
function sendMessage(from, to, text){
from = `+${from}`
to = `+${to}`
session.submit_sm({
source_addr: from,
destination_addr: to,
short_message: text
}, function(pdu) {
console.log(pdu)
if (pdu.command_status == 0) {
console.log(pdu.message_id);
}
});
}
sendMessage("1111", "2222", "Hello World!")
Output when sendMessage() method call:
PDU {
command_length: 18,
command_id: 2147483652,
command_status: 0,
sequence_number: 2,
command: 'submit_sm_resp',
message_id: '3' }
Here i'm using SMPPSim MO Injection Form
Output: when message sent selenium simulator:
PDU {
command_length: 63,
command_id: 5,
command_status: 0,
sequence_number: 8,
command: 'deliver_sm',
service_type: '',
source_addr_ton: 1,
source_addr_npi: 1,
source_addr: '111111',
dest_addr_ton: 1,
dest_addr_npi: 1,
destination_addr: '222222',
esm_class: 0,
protocol_id: 0,
priority_flag: 0,
schedule_delivery_time: '',
validity_period: '',
registered_delivery: 0,
replace_if_present_flag: 0,
data_coding: 0,
sm_default_msg_id: 0,
short_message: { message: 'Hello from SMPPSim' } }
confused between both result, if message sent using sendMessage() method then why its returning only submit_sm_resp, is it because of local machine ?? or something else ??
need help to understaning this behaviour.
I am not familiar with node-smpp or Selenium SMPPSim Simulator but they still use the SMPP protocol.
Your first output, from "sendMessage()", is the submit_sm_resp which is expected when one calls submit_sm.
However the second response you provided seems to be uncommon. As per the SMPP protocol found here I don't see any response types that natively return all the fields you have listed.
It might be possible that Selenium sends some of the parameters as TLV (Tagged Length Value) parameters or they just return you some extended data set built up on their side. Their documentation or source code might shed more light, if available.
On a side note, don't expect consistency of the SMPP protocol by 3rd party providers (ESMEs) or Short Message Service Center (SMSC). Even when I directly integrated into 4 cell service providers there were small discrepancies between them that required bespoke development.
You are talking about 2 different commands.
Your sendMessage() method sends an SMPP submit_sm ... for which you receive a submit_sm_resp from the simulator.
Injecting an MO from the simulator translates into a deliver_sm sent from the simulator to your app.
submit_sm is sent only from a smpp client(you) to a server(smsc/simulator)
deliver_sm is sent only from a smpp server(smsc/simulator) to a client(you)
It's perfectly normal for the sumbit_sm_resp to contain only those parameters. It is only an ACK/NACK for your submit_sm.
Similar, when the SMSC sents you a deliver_sm, you will respond with a deliver_sm_resp.
Related
I have a c# application that can open a cash drawer with the Windows Driver Installed. Pretty simple as the driver makes the USB device appears as a serial port:
SerialPort rsPort = new SerialPort(textBox1.Text);
byte[] openCmd = new byte[5];
openCmd[0] = 27;
openCmd[1] = 112;
openCmd[2] = 0;
openCmd[3] = 60;
openCmd[4] = 255;
rsPort.Open();
Thread.Sleep(100);
rsPort.Write(openCmd, 0, 5);
Thread.Sleep(100);
rsPort.Close();
I'm now trying to open the same USB cash Drawer via WebUSB. I've used ZaDig to install a generic USB drive and Chrome can see the USB device; can open the device; however, i'm struggling to send the correct commands.
Here is an image of the config:
Here is my current code:
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript WebUSB</h2>
<button id="myBtn">Try it</button>
<script>
document.getElementById("myBtn").addEventListener("click", talkToDrawer);
async function talkToDrawer() {
try {
let device = await navigator.usb.requestDevice({ filters: [{ vendorId: 1659 }] });
console.log(device);
await device.open(); // Begin a session.
await device.selectConfiguration(1); // Select configuration #1 for the device.
await device.claimInterface(0); // Request exclusive control over interface #2.
result = await device.controlTransferOut({
requestType: 'standard', // tried all combinations: standard / class / vendor
recipient: 'endpoint', // tried all combinations: device / interface / endpoint / other
request: 0x27,
value: 0,
index: 1
});
result = await device.controlTransferOut({
requestType: 'standard', // tried all combinations: standard / class / vendor
recipient: 'endpoint', // tried all combinations: device / interface / endpoint / other
request: 0x112,
value: 0,
index: 1
});
result = await device.controlTransferOut({
requestType: 'standard', // tried all combinations: standard / class / vendor
recipient: 'endpoint', // tried all combinations: device / interface / endpoint / other
request: 0x0,
value: 0,
index: 1
});
result = await device.controlTransferOut({
requestType: 'standard', // tried all combinations: standard / class / vendor
recipient: 'endpoint', // tried all combinations: device / interface / endpoint / other
request: 0x60,
value: 0,
index: 1
});
result = await device.controlTransferOut({
requestType: 'standard', // tried all combinations: standard / class / vendor
recipient: 'endpoint', // tried all combinations: device / interface / endpoint / other
request: 0x255,
value: 0,
index: 1
});
} catch (error) {
console.log(error);
}
}
</script>
</body>
</html>
Without knowing more about the device there are two errors I see in the code,
In the C# example the command is [27, 112, 0, 60, 255] with the values given in decimal while in the Javascript example the values are given as hexadecimal constants. The appropriate code for constructing the command buffer in Javascript is,
const cmd = new Uint8Array([27, 112, 0, 60, 255]);
Rather than using controlTransferOut() to send the data it is most likely correct to use transferOut() and select endpoint number 3. The Prolific USB-to-serial converter chips implement a protocol similar to the standard USB serial class, which uses a pair of bulk IN and OUT endpoints for the serial data stream,
result = await device.transferOut(3, cmd);
The remaining open question is whether you need to perform any control transfers before you can send this command. Control transfers are used to configure the device and for a USB-to-serial chip this usually involves things like setting baud rate or setting the DCE bit high. When reverse-engineering how to communicate with a USB device I recommend using Wireshark to view the USB traffic from a working driver.
Note, that if you are working with a serial device you should take a the Serial API. There is an experimental implementation available in Chrome behind the chrome://flags/#enable-experimental-web-platform-features flag. This API is designed for applications specifically targeting serial devices and avoids having to re-implement the driver for the USB-to-serial chip.
I have a list of about 470 numbers with different messaging I would like to send SMS to. I'm currently using Firebase Cloud Functions as my backend. Everything seemed to work perfectly locally without sending duplicate SMS to about 5 different test numbers.
By using the code below with the 470 numbers, each number got the same SMS 3-4 times each. I don't know if the issue is with Firebase Cloud Functions or not.
The concept is to send a SMS with Twilio and if it's a success. I use Firebase Firestore to store the message in a database. I'm trying to prevent Twilio from sending duplicate SMS to the same number with the same message.
Sample Code from Client:
textMessages[
{phoneNumber: "1111111111", message: "Test message 1 ", campaign: "Test Campaign"},
{phoneNumber: "2222222222", message: "Test message 2", campaign: "Test Campaign"},
{phoneNumber: "3333333333", message: "Test message 3", campaign: "Test Campaign"}]
exports.bulkTextWeb = functions.https.onCall(async (data) => {
const records = data.textMessages;
for (let i = 0, j = records.length; i < j; i++) {
const { phoneNumber, message, campaign } = records[i];
var msgFrom = twilio_number;
var msgTo = phoneNumber;
var msgBody = message;
await client.messages.create({
to: '1' + phoneNumber,
from: twilio_number,
body: message
})
.then(async message => {
if (message.status === 'queued' || message.status === 'sent' || message.status === 'delivered') {
// Check if campaign already exist
let docRef = await db.collection('campaigns')
.where('campaigns', 'array-contains', campaign).get()
.then(snapshot => {
// If there no campaign, add it to Firestore.
if (snapshot.empty) {
addCampaign(campaign);
}
// Add new message to Firestore
addNewMessage(msgFrom, msgTo, msgBody, campaign);
})
}
})
if (i === (j - 1)) {
// Return back to the client when all messages are sent
return { messages: 'Sent' }
}
}
})
In my opinion the amount of code provided in the question is just fine, in fact it let me remember having the same problem some time ago with a Node.js application.
The problem is not at Twilio.
You send one message via Twilio with one call of client.messages.create(). Since the same message is sent multiple times it's clear that client.messages.create() is called multiple times and it's called multiple times because of async/await.
I solved the problem by getting rid of async/await and using recursion to send the messages one after another.
You can see some code using recursion in answers I gave
here:
twillio multiple numbers whatsaap
and here: Twilio Functions Error 20429 - Too many requests multiple sms messages
(I suggest to also read the question and Phil's answer too).
I am using boto3 and in some cases I need to send silent notifications. I can do it by setting "SilentPush": True. Example:
response = client.send_messages(
ApplicationId='string',
MessageRequest={
'Addresses': {
'string': {
'ChannelType': 'APNS'
}
},
'MessageConfiguration': {
'DefaultPushNotificationMessage': {
'SilentPush': True,
}
}
)
In this case on the device I get push notification with 'content-available': 1, that tells me this is silent notification. The problem is, if I change SilentPush to False, I still get 'content-available': 1. Even if I send notification through aws console, I get the same result.
Please help me.
I used the nodejs upwork api via npm package (node-upwork) to create an hourly job with Upwork.offers.makeOffer api call which works fine. However, while creating a 'fixed-price' job it is requried to create a milestone object and set job_type to 'fixed-price'. Doing this on the same request gives an error => 'signature verification error'.
What could be the issue?
Here is an example of the Object that I am creating for the request
var Offers = require('upwork-api/lib/routers/hr/clients/offers.js').Offers;
var offers = new Offers(api);
var params = {
title: 'RM 1',
job_type: 'fixed-price',
charge_rate: 15,
message_to_contractor: 'Please accept this test job from Task Router',
contractor_key: '~01be12345c1234534b',
'context[job_posting_ref]': '~12345d3348af3dc'
};
var milestone = {
milestone_description : "complete the job",
deposit_amount : 1,
due_date : '01-17-2017'
};
params.milestones = [milestone];
offers.makeOffer(params, function (err, data) {
if (err) {
console.log(err);
}
else {
console.log("offer has been made");
}
});
It appears upwork requires a flat JSON object. Their API docs notes that all data must be sent as RAW post data. So you would have to provide the milestone information like this.
var params = {
title: 'RM 1',
job_type: 'fixed-price',
charge_rate: 15,
message_to_contractor: 'Please accept this test job from Task Router',
contractor_key: '~01be12345c1234534b',
'context[job_posting_ref]': '~12345d3348af3dc',
'milestones[0][milestone_description]': 'complete the job 1',
'milestones[0][deposit_amount]': 15.0,
'milestones[0][due_date]': '01-10-2017'
};
I have some problems with my project, i hope you will help me!
Description:
I use library from https://github.com/ToothlessGear/node-gcm to build server push notification for some devices.
I have configured API key from Google Cloud Message to SenderId.
My code:
var message2 = new gcm.Message();
**// ... or some given values
var message2 = new gcm.Message({
collapseKey: 'demo',
delayWhileIdle: true,
timeToLive: 3,
data: {
key1: 'message1',
key2: 'message2'
}
});
// Change the message data
// ... as key-value
message2.addData('key1','message1');
message2.addData('key2','message2');
// ... or as a data object (overwrites previous data object)
message2.addData({
key1: 'message1',
key2: 'message2'
});
// Change the message variables
message2.collapseKey = 'demo';
message2.delayWhileIdle = true;
message2.timeToLive = 3;
message2.dryRun = true;
// Set up the sender with you API key
var sender = new gcm.Sender('AIzaSyBzb1PsEBEiAjagslkEANqyxxxxxxxxx');
// Add the registration IDs of the devices you want to send to
var registrationIds = [];
registrationIds.push('APA91bHAbFJYpHsSN-uz1Hkh8XjBw4xU87VIz5hZYOtobVv6I2pUZM67pWUGbb5zcP2HxXrooYiIOhzhIV7TuRDbVOlRDak-.xxxxxxxxxx');
sender.send(message2, registrationIds, 4, function(err, result) {
console.log(result);
});**
Then, I ran and recevied message as picture!
According to the documentation, MismatchSenderId means that the sender (API key) does not have access to send notifications to the registration ID:
A registration ID is tied to a certain group of senders. When a client app registers for GCM, it must specify which senders are allowed to send messages. You should use one of those sender IDs when sending messages to the client app. If you switch to a different sender, the existing registration IDs won't work.
You should make sure that your registration ID allows notification from the sender.