I'm trying to make a node slack bot. When I hit the route from Slack,
app.get('/testbot', testbot);
I call testbot:
testbot.js:
postToSlack(botPayload, function (error, status, body) {
console.log('successfully posted to slack');
});
I'm posting my payload object to the Webhook URL specified in their Slack API: "https://hooks.slack.com/services/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"
function postToSlack (payload, callback) {
var val = JSON.stringify(payload);
request({
uri: 'https://hooks.slack.com/services/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&payload=val',
method: 'POST'
}, function (error, response, body) {
if (error) {
return callback(error);
}
console.log('RESPONSE', body); //takes forever, then eventually comes back as { }
callback(null, response.statusCode, body);
});
}
console.log('RESPONSE', body) doesn't return anything.
My test botPayload object looks like:
var botPayload = {};
botPayload.text = 'This should be working';
botPayload.username = 'my_new_bot';
botPayload.channel = '#mychannel';
botPayload.icon_url = 'http://i.imgur.com/IciaiJt.png';
What am I doing wrong here?
How can I remove the BOT label from the post?
Related
The goal is to have users enter in some information into a form and spit that out into a PDF. I'm using JSPDF to parse and create the PDF. I've successfully gotten my code to make a printable PDF, but in an effort to not have paper floating around the office, I made a cloud function to instead email that PDF to the customer.
Here is my code on the front end. maildoc is the pdf that I've made, it hasn't been printed or anything. So it only exists in memory.
mailDoc = mailDoc.output('datauri');
mailFunction += "&?data=" + mailDoc;
//axios request to the cloud function
axios.get(mailFunction).then( function (response) {
console.log(response);
}).catch(function (error) {
console.log(error)
})
And here is my code on the cloud function
exports.sendMail = functions.https.onRequest((req, res) => {
cors(req, res, () => {
// getting dest email by query string
//?dest= DestinationEmail
const dest = req.query.dest;
const data = req.query.data;
const mailOptions = {
from: 'whatever <whatever#hoobashaka.com>',
to: dest,
subject: "You're Equipment Return to HBCI", // email subject
attachments :[
{
filename: 'return.pdf',
contentType: 'application/pdf',
path: data,
}
],
};
return transporter.sendMail(mailOptions, (erro, info) => {
if(erro){
return res.send(erro.toString());
}
return res.send('Sended');
});
});
If I try and send the data via URI, I get a 413 error, probably because that URI is enormous. But I can't think of another way of sending that generated PDF to the function.
On your client, instead of uploading the file as a datauri, I'd instead use POST and send the PDF inside the request body (just as if you had submitted a file using a form).
mailDocBlob = mailDoc.output('blob');
const data = new FormData();
data.set('dest', someEmail);
data.append('file', mailDocBlob, 'return.pdf');
axios({
method: 'post',
url: 'https://your-cloud-function.here/sendMail',
data: data,
headers: {
'Content-Type': `multipart/form-data; boundary=${data._boundary}`,
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
On the server you would handle the multipart form data using the busboy package.
const BusBoy = require('busboy');
exports.sendMail = functions.https.onRequest((req, res) => {
cors(req, res, (err) => {
if (err) {
// CORS failed. Abort.
console.log("CORS failed/rejected");
res.sendStatus(403); // 403 FORBIDDEN
return;
}
if (req.method !== 'POST') {
res.set('Allow', 'POST, OPTIONS').sendStatus(405); // 405 METHOD_NOT_ALLOWED
return;
}
let busboy = new BusBoy({headers: req.headers, limits: {files: 1}}); // limited to only a single file
const mailOptions = {
from: 'whatever <whatever#hoobashaka.com>',
to: dest,
subject: "Your Equipment Return to HBCI", // email subject - fixed typo
attachments: []
};
busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
// add new file attachment
mailOptions.attachments.push({
filename: 'return.pdf',
contentType: 'application/pdf',
content: file, // file is a stream
});
})
.on('finish', () => {
if (mailOptions.attachments.length == 0) {
// not enough attachments
res.status(400).send('Error: not enough attachments');
return;
}
return transporter.sendMail(mailOptions, (erro, info) => {
if (erro) {
return res.status(500).send('Error: ' + erro.toString());
}
return res.send('Sent');
})
})
.on('error', (err) => {
console.error(err);
res.status(500).send('Error: ' + err.code);
});
req.pipe(busboy);
});
My problem is, My project's server is restarted After an axios request with express.
I can see http://localhost:3000/__webpack_hmr 200 OK in console of chrome.
when I add vocabulary to data or remove that, server is restarted.
This is the vue client code. (github link to file)
methods: {
addVocabulary () {
var vm = this
this.$validator.validateAll().then((result) => {
if (result) {
axios.post('/api/vc/add', {
vocabulary: this.vocabulary
}).then(function (response) {
vm.vocabularies = response.data
}).catch(function (error) {
console.log(error)
})
this.vocabulary = ''
} else {
console.log('Not valid')
}
})
},
remove (id) {
var vm = this
axios({
method: 'delete',
url: '/api/vc/remove',
data: {id: id},
headers: {'Content-Type': 'application/json'}
}).then(function (response) {
vm.vocabularies = response.data
}).catch(function (error) {
console.log(error)
})
}
}
And this is the server side code.link to file
router.post('/vc/add', function (req, res, next) {
if (!req.body) return res.sendStatus(400)
let vocabulary = req.body.vocabulary
let objVocabulary = {}
objVocabulary.id = 10
objVocabulary.content = vocabulary
vocabularies.push(objVocabulary)
fse.outputJson(file, vocabularies, err=>{
console.log(err);
fse.readJson(file, (err, data) =>{
res.json(data);
})
})
})
/* DELETE remove voca */
router.delete('/vc/remove', (req, res, next) =>{
if (!req.body) return res.sendStatus(400)
let id = req.body.id
var index = vocabularies.findIndex(voca => voca.id === id);
vocabularies.splice(index,1);
fse.outputJson(file, vocabularies, err=>{
console.log(err);
fse.readJson(file, (err, data) =>{
res.json(data);
})
})
})
Here's my project link to github,
I don't know why..
I see that you are using backpack.
Their documentation quotes: Live reload (on saves, add/delete file, etc.)
So, if you the JSON file you are manipulating in your server code is in a folder watched by backpack, hot module reload will kick in and restart the server.
Solution: Move the json to some other directory --> your database shouldn't be part of your source code anyways.
I met similar issue several times.
Below is success call
var createAdset_params = {
method: "post"
}
var url = "https://graph.facebook.com/v2.12/act_"+req.body.ADACCOUNT_ID+"/adsets?access_token="+req.body.access_token +
"&name=My+Reach+Ad+Set"+
"&optimization_goal=REACH"+
"&billing_event=IMPRESSIONS"+
"&bid_amount=2"+
"&daily_budget=1000"+
"&campaign_id="+req.body.CAMPAIGN_ID+
"&targeting=%7B%22geo_locations%22%3A%7B%22countries%22%3A%5B%22US%22%5D%7D%7D"+
"&status=PAUSED"+
"&promoted_object%3A%20%7B"+
"page_id%3A%20%"+req.body.PAGE_ID+"%22%7D";
request({url:url, qs: createAdset_params}, function(err, response, body) {
if(err) {
console.log(err); return;
}
console.log("create adset result", body);
res.send(body);
});
Create ad set and return id of adset.
Below is not success call.
var createAdset_params = {
method: "post"
name:"My Reach Ad Set",
promoted_object: {page_id: req.body.PAGE_ID},
optimization_goal: "REACH",
billing_event:"IMPRESSIONS",
bid_amount:2,
daily_budget:1000,
campaign_id:req.body.CAMPAIGN_ID,
status: "PAUSED",
targeting:{
geo_locations: {countries:["US"]}
}
}
var url = "https://graph.facebook.com/v2.12/act_"+req.body.ADACCOUNT_ID+"/adsets?access_token="+req.body.access_token;
request({url:url, qs: createAdset_params}, function(err, response, body) {
if(err) {
console.log(err); return;
}
console.log("create adset result", body);
res.send(body);
});
Showing admin permission error, even if the access_token is admin's access_token which is success with on first call.
Is there someone success with the format of below one(regular post request format)?
Any kind of hint will greatly appreciate!
If you are checking facebook marketing api doc, to create an adset all parameters are posted as form, instead of query string.
var createAdset_params = {
name:"My Reach Ad Set",
promoted_object: {page_id: req.body.PAGE_ID},
optimization_goal: "REACH",
billing_event:"IMPRESSIONS",
bid_amount:2,
daily_budget:1000,
campaign_id:req.body.CAMPAIGN_ID,
status: "PAUSED",
targeting:{
geo_locations: {countries:["US"]}
},
access_token: req.body.access_token
};
var url = "https://graph.facebook.com/v2.12/act_"+req.body.ADACCOUNT_ID+"/adsets";
request({
url : url,
method: 'POST',
form: createAdset_params
}, function(err, response, body) {
if(err) {
console.log(err); return;
}
console.log("create adset result", body);
res.send(body);
});
I'm using tcp-ping to ping a server, and then I want to make a callback function that will POST the data to my database via the request library. I'm having trouble figuring out how to get the callback to send data to the second function.
The problem is that there is no error, but the form data for Min, Max, and Avg are not being recorded in mongodb. I don't know how to retrieve the data, or know if the data is even being sent.
tcpp.ping({ address: 'www.google.com' }, function(err, data) {
postPingData(function(err, data){
if(err){
console.log(500, { error: 'something blew up' });
} else {
console.log(data); // I understand this is incorrect, but I don't know how else I'm supposed to send data.
}
});
console.log(data);
});
var postPingData = function(callback){
console.log(callback);
request.post({
headers: {'content-type' : 'application/x-www-form-urlencoded'},
url: 'http://localhost:8080/api/pingdata',
form: {
ping_id: "5852fd1976ba7111cd9b78aa",
min: callback.min,
max: callback.max,
avg: callback.avg
}
}, function(error, response, body){
if (!error && response.statusCode == 200) {
status = "succeeded";
callback(null, {status : status});
} else {
callback(error);
}
})
};
Essentially it seems you would want to inject the data argument passed to the callback to tcpp.ping - which will be the result of the ping operation if successful - to your postPingData function:
tcpp.ping({ address: 'www.google.com' }, function(err, data) {
postPingData(data, function(err, data){
...
var postPingData = function(data, callback){
...
form: {
ping_id: "5852fd1976ba7111cd9b78aa",
min: data.min,
max: data.max,
avg: data.avg
}
var Attendance = require('../../../collections/attendance').Attendance;
var moment = require('moment');
module.exports = function(app) {
app.get('/api/trackmyclass/attendance', function(req, res) {
var data = req.body;
data['user'] = req.user;
Attendance.getByUser(data, function(err, d) {
if (err) {
console.log('This is the err' + err.message);
res.json(err, 400);
} else {
var job = d['attendance'];
if (typeof job != undefined) {
res.json(job);
console.log('This is it' + job['status']);
} else
res.json('No data Present', 200);
}
});
});
app.post('/api/trackmyclass/attendance', function(req, res) {
var data = req.body;
data['user'] = req.user;
Attendance.create(data, function(err, d) {
if (err) {
console.log('This is the err' + err.message);
res.json(err, 400);
} else {
var attendance = d['attendance'];
if (typeof job != undefined) {
console.log('Attendance record created' + attendance);
res.json(attendance);
} else
res.json('No data Present', 200);
}
});
});
}
This is the api code I to which I need to make the GET and POST request. But I have no idea how to do it.
It looks like your code is using express which would normally be good for building and API for your app. However to make a simple request to a third party api and staying in node.js why not try the request module which is great. https://www.npmjs.org/package/request
Your example does not show what the path of the request is or if you need any additinal headers etc but here is a simple example of a GET request using request.
var request = require('request');
function makeCall (callback) {
// here we make a call using request module
request.get(
{ uri: 'THEPATHAND ENDPOINT YOU REQUEST,
json: true,
headers: {
'Content-Type' : 'application/x-www-form-urlencoded',
}
},
function (error, res, object) {
if (error) { return callback(error); }
if (res.statusCode != 200 ) {
return callback('statusCode');
}
callback(null, object);
}
);
}
or jquery .ajax from a front end client direcct to your path
$.ajax({
url: "pathtoyourdata",
type: "GET",
})
.done(function (data) {
//stuff with your data
});