Here is the current code (subscription to a single item)
podio.authenticate('password', {
'username': podioUser.username,
'password': podioUser.password
}, function (response, body) {
const item_id = 1234567;
podio.get('/item/' + item_id, {}, function (response, body) {
push.addSubscription(body.push);
});
});
Here is the complete code,
// Initialize faye client
var fayeClient = new faye.Client('https://push.podio.com/faye');
// Extend faye client with signature and timestamp used for authentication
fayeClient.addExtension({
'outgoing': function (message, callback) {
message.ext = message.ext || {};
message.ext = {private_pub_signature: push.channel.signature, private_pub_timestamp: push.channel.timestamp};
callback(message);
}
});
const push = {
subscription: null,
channel: null,
addSubscription: function (channel) {
this.channel = channel;
this.subscription = fayeClient.subscribe(this.channel.channel).withChannel(function (channel, message) {
var client = new faye.Client('http://localhost:8000/');
client.publish('/messages', {
text: message
});
});
this.subscription.then(function () {
console.log('Subscription is now active');
}, function (error) {
console.error('Subscription failed: ', error.message, error);
});
}
};
podio.authenticate('password', {
'username': podioUser.username,
'password': podioUser.password
}, function (response, body) {
const item_id = 1234567;
podio.get('/item/' + item_id, {}, function (response, body) {
push.addSubscription(body.push);
});
});
bayeux.attach(server);
server.listen(8002);
Is it possible to subscribe multiple items? I tried item id loop through and subscribe, it doesn't work.
Related
I am creating a REST API service using Azure Function in nodeJs. The function is reading some data from Azure SQL and I want it to be returned. I am using tedious package to connect to Azure SQL Database.
const { Connection, Request } = require("tedious");
var data = [];
console.log("0." + data);
const config = {
authentication: {
options: {
userName: "------", // update me
password: "--------" // update me
},
type: "default"
},
server: "----.database.windows.net", // update me
options: {
database: "---", //update me
encrypt: true
}
};
module.exports = async function (context, req, resp) {
const connection = new Connection(config);
context.bindings.response = { status: 201, body: {"time": new Date().getUTCMinutes(), "data": data} };
connection.on("connect", err => {
if (err) {
console.error(err.message);
} else {
queryDatabase(context);
}
});
connection.connect();
//context.bindings.response = { status: 201, body: JSON.stringify(data) };
function queryDatabase(context) {
console.log("Reading rows from the Table...");
// Read all rows from table
const request = new Request(
`SELECT FirstName, LastName FROM Persons`,
(err, rowCount, data) => {
if (err ) {
console.error(err.message);
} else {
console.log(`${rowCount} row(s) returned`);
}
}
);
request.on("row", columns => {
var row = {};
columns.forEach(column => {
row[column.metadata.colName] = column.value;
console.log("%s\t%s", column.metadata.colName, column.value);
data.push(row);
});
});
connection.execSql(request);
}
}
I can read data from Azure SQL Database and the console.log is printing data in the console.
console.log("%s\t%s", column.metadata.colName, column.value);
But while I am trying to bind the data to response, it always shows blank.
{
"time": 52,
"data": []
}
How and where to bind the context.bindings.response?
If I’ve understood you correctly, try this approach ...
// Construct response
const responseJSON = {
"name": "Some name",
"sport": "Some sport",
"message": "Some message",
"success": true
}
context.res = {
// status: 200, /* Defaults to 200 */
body: responseJSON,
contentType: 'application/json'
};
I am trying to write an async lambda function which is calling a function for sign up a user in cognito.
my problem is that in my lambda function, it is not waiting for the result and finish the execution. would you mind check what is my issue? I am new to rxjs. please help me.
mylambda function
exports.handler = async (event, context) => {
//poolData and params will fetch from event
let source = await signup(poolData, params);
console.log(source);
});
my signup function
function signup(poolData, body) {
const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
const { username, password, attributes } = body;
const attributesList = [];
if (Array.isArray(attributes)) {
attributesList.push(
...attributes.map(item => new AmazonCognitoIdentity.CognitoUserAttribute(item))
);
}
let source = Observable.create(observer => {
let output = (err, res) => {
if (err)
{
observer.error(err);
}
else
{
const cognitoUser = res.user;
const data = {
username: cognitoUser.getUsername(),
};
observer.next(data);
}
observer.complete();
}
userPool.signUp(username, password, attributesList, null, output);
});
let respond;
let subscriber = {
next(value) {
console.log('Subscriber - next: ', value);
respond = {
'statusCode': 200,
'body': JSON.stringify({
"username": value.username,
})
}
}, error(err) {
console.log('Subscriber - err: ', err);
respond = err;
},
complete() {
console.log('Subscriber - complete');
return response;
}
};
source.subscribe(subscriber);
}
module.exports = signup;
This behavior is totally normal.
So first thing first, an observable is not a promise which means you are not able to await a response with the await keyword, also I don't see anything to be returned from the signup function, which will probably lead to undefined to be logged anyways.
So how to fix that, one way to fix this issue is to use toPromise() which will turn your observable into a promise which then can be awaited wherever needed.
The other way (which is the rxjs way) will be to return from the signup function the observable and inside your handler function to subscribe for the response.
let subscriber = {
next(value) {
console.log('Subscriber - next: ', value);
respond = {
'statusCode': 200,
'body': JSON.stringify({
"username": value.username,
})
}
}, error(err) {
console.log('Subscriber - err: ', err);
respond = err;
},
complete() {
console.log('Subscriber - complete');
return response;
}
};
exports.handler = (event, context) => {
//poolData and params will fetch from event
signup(poolData, params).subscribe(subscriber);
})
I've never used Socket.IO before so this is very new for me.
I have a taxi app in react which will send a new order as an event through Socket.IO but I don't see any error or response.
Server Side it looks like this:
client.on('newOrder', function(data){
socketController.newOrder(data, io, client);
});
newOrder: function(data, io, client) {
order.create(data, io, client, function(response){});
}
Order.prototype.create = function (data, io, client, callback) {
console.log("ORDER DATA = " + JSON.stringify(data));
let luggage = 0;
if (typeof data.luggage !== 'undefined')
luggage = data.luggage;
let insertData = {
client_id: data.id_client,
start_address: data.origin.name,
start_lat: data.origin.latitude,
start_lng: data.origin.longitude,
end_address: data.destination.name,
end_lat: data.destination.latitude,
end_lng: data.destination.longitude,
options: JSON.stringify(data.options),
car_options: JSON.stringify(data.car_options),
car_type: data.car_type,
passengers: data.passengers,
luggage: luggage,
payment_method: data.payment_method,
profile_id: data.profile,
profile_type: data.profile_type
};
if (data.schedule_time != null && data.schedule_time.length > 0) {
insertData.schedule_time = data.schedule_time
}
db.query("INSERT INTO orders SET ?", insertData,
function (err, results, fields) {
if (err) {
console.log("Order.create [ERROR: " + err + "]");
return callback({ error: true, message: err });
}
data.id_order = results.insertId;
const timeInsert = {
order_id: data.id_order,
new: new Date().toISOString().slice(0, 19).replace('T', ' ')
};
db.query("INSERT INTO orders_timestamps SET ?", timeInsert, function (err, results, fields) { });
client.emit("orderSaved", { "id_order": data.id_order });
getOrder(data.id_order, function (order) {
sendOrdersToDriver(data, order, io, function (data) {
console.log("Order.create [SUCCESS]");
return callback(data);
});
});
}
);
};
Client Side it looks like this
const data = {
id_client: user.id,
car_type: "executive",
car_options: [],
passengers: 1,
luggage: 2,
payment_method: "cash",
options: [],
origin: { name: pickUp, latitude: pickUpCoordinates.lat, longitude: pickUpCoordinates.lng },
destination: { name: dropOff, latitude: dropOffCoordinates.lat, longitude: dropOffCoordinates.lng },
schedule_time: new Date(),
profile: "",
profile_type: "owner"
}
socket.emit("newOrder", data, function (response) {
console.log('emit response', response);
});
Edit 1:
Let me try to explain how does this callback stuff working,
// here we are at the client-side
// so here from client side i'm sending a data and a callback
// socket.emit('event-name', data, callback); signature
socket.emit('some-event', { a: true }, function(dataFromServer) {
console.log(dataFromServer);
});
// here we are at server-side
socket.on('some-event', function(data, callback) {
// we are getting the data first argument and callback second
// let's say we are testing if data has a === true;
if(data.a) { // same as data.a === true
// here we are gonna send 'hi' to callback
return callback('hi the data was valid for me');
}
// otherwise we are assuming that data wasn't valid
return callback('your data is not okey mate!');
});
So from client-side if you send a data contains { a: true } as prop you should see that callback consoling 'hi the data was valid for me' this.
Otherwise if it doesn't contain a or a: false then you should see 'your data is not okey mate!' from your client's callback.
Consedering this senario; go for your code and check =)
First please check if you socket.connected === true on your frontend.
Second here you are sending data and a callback through your emit
socket.emit("newOrder", data, /*this is your callback*/function (response) {
console.log('emit response', response);
});
And here on your server you are only getting data from client.
// needs to be like this
client.on('newOrder', function(data, callback) {
socketController.newOrder(data, callback, io, client);
});
// same with
newOrder: function(data, callback, io, client) {
// you probably dont need to send this empty callback cause actualy callback
// coming after `data`, `callback`
order.create(data, callback, io, client); //function(response){});
}
// same with
Order.prototype.create = function (data callback, io, client) {
...
sendOrdersToDriver(data, order, io, function (data) {
console.log("Order.create [SUCCESS]");
// here you are calling it so it needs to work if
// your `sendOrdersToDriver` function actually calls it's
// own callback?
return callback(data);
});
}
My Angular app sends some data to a node server (app.js) via a POST request, the request body is then returned in the response.
I am now trying to send an email that contains this data sent in the request body.
Currently, I can read a HTML file to populate the email body, & then send the email but I need to replace that HTML file with the data sent in my req.body.
Here is what I have so far in app.js:
const express = require('express')
const app = express()
const bodyParser = require('body-parser')
app.post('/postData', bodyParser.json(), (req, res) => {
res.json(req.body)
readFile();
sendEmail();
})
app.listen(3000, () => console.log('Example app listening on port 3000!'))
var AWS = require('aws-sdk');
const fs = require('fs');
var params;
var htmlFileName = '/Users/myName/Desktop/test.html'
AWS.config.loadFromPath('config-aig.json');
const fromEmail = 'myName';
const toEmail = 'myName'
const subject = 'Test Email' + Date()
function sendEmail() {
// Create the promise and SES service object
var sendPromise = new AWS.SES({ apiVersion: '2010-12-01'}).sendEmail(params).promise();
sendPromise.then(
function (data) {
console.log('send email success');
}).catch(
function (err) {
console.error('error --> ', err, err.stack);
});
}
function readFile(callback) {
return new Promise(
function (resolve, reject) {
fs.readFile(htmlFileName, 'utf8',
function read(err, data) {
if (err) {
return reject(err)
}
else {
console.log('file read success');
return resolve(data);
}
})
}
)
}
readFile()
.then((res) => {
// Create sendEmail params
params = {
Destination: { /* required */
ToAddresses: [
toEmail,
]
},
Message: { /* required */
Body: { /* required */
Html: {
Charset: "UTF-8",
Data: res
}
},
Subject: {
Charset: 'UTF-8',
Data: subject
}
},
Source: fromEmail, /* required */
}
sendEmail();
})
.catch((err) => {
console.log('File Read Error : ', err)
}
)
Can someone please show me how I can replace my htmlFileName with the req.body?
I use ejs to template my email here is a code i frenquently use to send email !
If you have questions i would be glade to answer
const ejs = require('ejs');
const AWS = require('aws-sdk');
const mailcomposer = require('mailcomposer');
const config_aws = {
accessKeyId: '',
secretAccessKey: '',
region: 'eu-west-1',
expeditor: '',
limitExpeditor: 50
};
AWS.config.update(config_aws);
const ses = new AWS.SES();
async function sendAnEmail(
expeditor,
subject,
destinator,
body,
destinator_name = null,
bcc = null,
callback
) {
ejs.renderFile(
`${__dirname}/templates/template.ejs`,
{
destinator,
destinator_name,
subject,
body
},
(err, html) => {
if (err) return console.error(err);
const sesEmailProps = {
Source: config_aws.expeditor,
Destination: {
ToAddresses: [`${destinator}`]
},
Message: {
Body: {
Html: {
Charset: 'UTF-8',
Data: html
},
Text: {
Charset: 'UTF-8',
Data: html ? html.replace(/<(?:.|\n)*?>/gm, '') : ''
}
},
Subject: {
Charset: 'UTF-8',
Data: subject
}
}
};
if (bcc) {
sesEmailProps.Destination = {
ToAddresses: [`${destinator}`],
BccAddresses: bcc // ARRAY LIMIT OF 49
};
}
ses.sendEmail(sesEmailProps, (error, data) => {
if (error) console.error(error);
callback(error, data);
});
}
);
}
I'm new to NodeJS and I'm supposed to write a serverless rest API for a online store (school project). The team I'm in is responsible of the orders customers place. To be able to place the order there has to be enough quantity in inventory (another API), so we need to check quantity in inventory using GET before we store the order in a database using POST. How should we go about this? This is what I have tried, but I end up getting timeout. The code below is based on this example: aws-node-rest-api-with-dynamodb for me to get the hang of NodeJS and serverless.
.yml file
functions:
create:
handler: todos/test.f
events:
- http:
path: todos
method: post
cors: true
test.js
const create = require("./create.js");
exports.f = function() {
const https = require('https');
https.get('url goes here', (resp) => {
let data = '';
// A chunk of data has been recieved.
resp.on('data', (chunk) => {
data += chunk;
});
// The whole response has been received. Print out the result.
resp.on('end', () => {
console.log(data);
var str = String(data);
console.log("Check: " + (str.trim() == "OK"))
create.c(); //also tried create.create();
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
}
create.js
'use strict';
const uuid = require('uuid');
const dynamodb = require('./dynamodb');
exports.c = function (){
console.log("Fire!");
}
module.exports.create = (event, context, callback) => {
const timestamp = new Date().getTime();
const data = JSON.parse(event.body);
if (typeof data.text !== 'string') {
console.error('Validation Failed');
callback(null, {
statusCode: 400,
headers: { 'Content-Type': 'text/plain' },
body: 'Couldn\'t create the todo item.',
});
return;
}
const params = {
TableName: 'todos',
Item: {
id: uuid.v1(),
text: data.text,
checked: false,
createdAt: timestamp,
updatedAt: timestamp,
},
};
// write the todo to the database
dynamodb.put(params, (error) => {
// handle potential errors
if (error) {
console.error(error);
callback(null, {
statusCode: error.statusCode || 501,
headers: { 'Content-Type': 'text/plain' },
body: 'Couldn\'t create the todo item.',
});
return;
}
// create a response
const response = {
statusCode: 200,
body: JSON.stringify(params.Item),
};
callback(null, response);
});
};
Any thoughts on how to get this to work?