I create both grpc server and client. But I'm new to Node/TS and don't know how to save the respone in the callback function.
function read(path:string): string {
logger.info(`reading ${path}`);
var request:FileRequest = new FileRequest();
request.setPath(path);
grpc_client.read(request, (error: ServiceError | null, response: FileResponse) => {
if (error !== null)
throw new Error(`reading failed, error message : ${error.message}`);
return response.getContent_asB64();
});
return response.getContent_asB64();
}
If anyone can help me, thanks a lot!
Save the response in the callback function and return it.
Related
I have been trying to convert my existing Node JS code from function callback to Async Await, because a new SDK came out and callbacks are deprecated. These are the related codes. The code is communicating and publishing to a mqtt broker.
First here I call the ToggleX method
super.controlToggleX(channel, value, (err, res) => {
if (err) {
this.log(`Toggle Response: err: ${err}`);
}
this.log(`Toggle Response: res: ${JSON.stringify(res)}`);
});
After that in the controlToggleX method I set the payload for the message and make the publlish to the broker.
controlToggleX(channel, onoff, callback) {
const payload = { togglex: { channel, onoff: onoff ? 1 : 0 } };
return this.publishMessage('SET', 'Appliance.Control.ToggleX', payload, callback);
}
In the publishMessage I compile the message to the broker and publish it. After publishing I waiting for the response and to keep track of the ongoing messages I create the waitingMessageIds array.
publishMessage(method, namespace, payload, callback) {
this.clientResponseTopic = `/app/${this.userId}-${appId}/subscribe`;
const messageId = crypto.createHash('md5').update(generateRandomString(16)).digest('hex');
const timestamp = Math.round(new Date().getTime() / 1000); // int(round(time.time()))
const signature = crypto.createHash('md5').update(messageId + this.key + timestamp).digest('hex');
const data = {
header: {
from: this.clientResponseTopic,
messageId,
method,
namespace,
payloadVersion: 1,
sign: signature,
timestamp,
},
payload,
};
this.client.publish(`/appliance/${this.uuid}/subscribe`, JSON.stringify(data));
if (callback) {
this.waitingMessageIds[messageId] = {};
this.waitingMessageIds[messageId].callback = callback;
this.waitingMessageIds[messageId].timeout = setTimeout(() => {
// this.log('TIMEOUT');
if (this.waitingMessageIds[messageId].callback) {
this.waitingMessageIds[messageId].callback(new Error('Timeout'));
}
delete this.waitingMessageIds[messageId];
}, 20000);
}
this.emit('rawSendData', data);
return messageId;
}
When a new message comes from the broker I check the waitingMessageIds array, the messageId is in the array? If yes I delete the Timer and process the message with the callback coming from the publishing.
this.client.on('message', (topic, message) => {
if (!message) return;
// message is Buffer
try {
message = JSON.parse(message.toString());
} catch (err) {
this.emit('error', `JSON parse error: ${err}`);
return;
}
if (message.header.from && !message.header.from.includes(this.uuid)) return;
if (this.waitingMessageIds[message.header.messageId]) {
if (this.waitingMessageIds[message.header.messageId].timeout) {
clearTimeout(this.waitingMessageIds[message.header.messageId].timeout);
}
this.waitingMessageIds[message.header.messageId].callback(null, message.payload || message);
delete this.waitingMessageIds[message.header.messageId];
} else if (message.header.method === 'PUSH') {
const namespace = message.header ? message.header.namespace : '';
this.log('Found message');
this.emit('data', namespace, message.payload || message);
}
this.emit('rawData', message);
});
mqtt package is working with callback, but the async-mqtt is returning Promise so it is going to be good for me.
I was successfull to publish with it, and after that point I put the messageId to the array and start a timer, but when the reply came i was not been able to proocess the waitingMessageIds and return to the original point (super.controlToggleX).
Could somebody please help me. Thank
Edit:
I tried to rewrite PublishMessage with async-mqtts and it looks like this:
async publishMessage(method, namespace, payload) {
.
.
.
try {
await this.client.publish(`/appliance/${this.uuid}/subscribe`, JSON.stringify(data));
} catch (err) {
return new Error(err);
}
this.waitingMessageIds[messageId] = {};
// this.waitingMessageIds[messageId].callback = callback;
this.waitingMessageIds[messageId].timeout = setTimeout(() => {
// this.log('TIMEOUT');
if (this.waitingMessageIds[messageId].callback) {
this.waitingMessageIds[messageId].callback(new Error('Timeout'));
}
delete this.waitingMessageIds[messageId];
}, 20000);
this.emit('rawSendData', data);
return messageId;
}
Because with the await publish waits for the response I do not need check if it is a callback, i just put the messageId into the waitingmessageIds array.
When I process the incoming message in this.client.on('message' I don not know how to change this -> this.waitingMessageIds[message.header.messageId].callback(null, message.payload || message);
i am writing a program that send multiple request ti retrieve some data from an external api , it works fine , but when i try to add a function "appendFile" that save the data received in a json the server starts to behave strangely and restart every time ,and resend the same request again and again which wasn't thes case before i added the function , if you have any insights abozt this problem please help , thanks :
here is my code to send request and and save the data in a json
const streamActivity = (client) => (activityId) => {
return new Promise((resolve, reject) => {
client.streams.activity(
{
id: activityId,
types:
"time,heartrate,velocity_smooth,altitude,distance,latlng,cadence,watts,temp,moving,grade_smooth,average_speed",
resolution: "high",
},
function (err, payload,next) {
if (!err ) {
//save to json
appendToFile1('activity-streams.json', payload)
} else {
reject(err)
}
}
);
});
// setInterval(streamActivity,5000);
};
and this is the append file function :
function appendToFile1(file, payload) {
fs.appendFile(file, JSON.stringify({payload}), (err) => {
if (err) throw err
console.log('Done writing') // Success
})
}
I am trying to build a Whatsapp chatbot using Node.JS and am running into a bit of trouble in receiving the Whatsapp message from Twilio. On checking the debugger, I get a Bad Gateway error, ie. Error 11200: HTTP Retrieval Failure. The message is getting sent, and ngrok shows the post request, however, dialogflow does not receive the request. On terminal, the error is showing UnhandledPromiseRejectionWarning: Error: 3 INVALID ARGUMENT: Input text not set. I'm not sure if it's because the message is not in JSON format. Please help!
This is the app.post function:
app.post('/api/whatsapp_query', async (req, res) =>{
message = req.body;
chatbot.textQuery(message.body, message.parameters).then(result => {
twilio.sendMessage(message.from, message.to, result.fulfillmentText).then(result => {
console.log(result);
}).catch(error => {
console.error("Error is: ", error);
});
return response.status(200).send("Success");
})
});
And this is the sendMessage function I've imported:
const config = require('./config/keys');
const twilioAccountID = config.twilioAccountID;
const twilioAuthToken = config.twilioAuthToken;
const myPhoneNumber = config.myPhoneNumber;
const client = require('twilio')(twilioAccountID,twilioAuthToken);
module.exports = {
sendMessage: async function(to, from, body) {
return new Promise((resolve, reject) => {
client.messages.create({
to,
from,
body
}).then(message => {
resolve(message.sid);
}).catch(error => {
reject(error);
});
});
}
}
And this is the textQuery function I've imported:
textQuery: async function(text, parameters = {}) {
let self = module.exports;
const request = {
session: sessionPath,
queryInput: {
text: {
text: text,
languageCode: config.dialogFlowSessionLanguageCode
},
},
queryParams: {
payload: {
date: parameters
}
}
};
let responses = await sessionClient.detectIntent(request);
responses = await self.handleAction(responses)
return responses[0].queryResult;
},
Twilio developer evangelist here.
The issue is that you are not passing the correct message body from the incoming WhatsApp message to your textQuery function.
First, you should make sure that you are treating the incoming webhook from Twilio as application/x-www-form-urlencoded. If you are using body-parser, ensure you have urlencoded parsing turned on.
app.use(bodyParser.urlencoded());
Secondly, the parameters that Twilio sends start with a capital letter. So your code currently gets message = req.body and then uses message.body. But it should be message.Body.
Those two points should sort you out.
One final thing though. The Twilio Node.js library will return a Promise if you do not pass a callback function. So you don't need to create a Promise here:
module.exports = {
sendMessage: async function(to, from, body) {
return new Promise((resolve, reject) => {
client.messages.create({
to,
from,
body
}).then(message => {
resolve(message.sid);
}).catch(error => {
reject(error);
});
});
}
}
You can just return the result of the call to client.messages.create
module.exports = {
sendMessage: async function(to, from, body) {
return client.messages.create({ to, from, body });
}
}
Hope this helps.
I am trying to view file in browser in new tab but in service i am not getting any response and it is throwing me in catch handler of my service and in handler
i am not getting any specific error to troubleshoot the problem.
I am sending Authorization token in header because my view document api is protected.
Also there are 2 below calls going on which i dont understand why :
Call1
Call2
Code :
Controller:
viewFile(index) {
this.FileService.view("f819f948-b5dd-4478-ad69-b0e610627375").subscribe((response) => {
if (response.message === "success") {
window.open(this.baseUrl + response.id, '_blank');
}
}),
(error) => {
console.log('error');
}
}
FileService.ts
view(id): Observable<any> {
return this._http.get<any>(this.baseUrl + 'example/document/' + id)
.catch(this.handleError);
}
handleError(error: HttpErrorResponse) { //always throwing here
if (error.error instanceof ErrorEvent) {
console.error('An error occurred:', error.error.message);
} else {
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
console.log(error);
}
return new ErrorObservable(
'Something bad happened; please try again later.');
};
Webapi core: Supporting method
IServiceContext _ctx;
Stream stream = repo.GetFileStream("abc.pdf", filePath);
if (stream.CanSeek)
{
stream.Seek(0, SeekOrigin.Begin);
}
_ctx.req.HttpContext.Response.Headers.Add("Content-Disposition", "inline; filename=" + "abc.pdf");
var provider = new FileExtensionContentTypeProvider().
TryGetContentType("abc.pdf", out string contentType);
_ctx.req.HttpContext.Response.ContentType = contentType;
stream.CopyTo(_ctx.reqobj.HttpContext.Response.Body);
stream.Flush();
I am not getting whats the issue here and most importantly why there are 2 get calls?
When i call my view api document api in postman then i can see the file and also when i go in preview of Develer tool in chrome then i am able to see the image but it is not working with angular js.
Am i missing anything from server end or something is wrong in client side?
I will appreciate any help :)
I am implementing the following code using javascript in browser to create certificate and key pair:
var iot = new AWS.Iot();
function createCert(){
var params = {
setAsActive:false
};
iot.createKeysAndCertificate(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
};
and I am getting the ERROR as :
UnknownOperationException: null
at Object.s [as extractError] (https://sdk.amazonaws.com/js/aws-sdk-2.106.0.min.js:42:24512)
at constructor.o (https://sdk.amazonaws.com/js/aws-sdk-2.106.0.min.js:42:29401)
Please help me in resolving this error.
Thank You
Seems like I had configured AWS for dynamoDB and the endpoint of AWS.Iot was not updated.
Now, it works!!!