I managed to fetch video data from a channel but when it try to add comments to a video, I fail. So at some point I can read data successfully.
I have read that docummentation: https://developers.google.com/youtube/v3/docs/commentThreads/insert
And I'm not sure if I did the parameters correctly.
Besides Node.js and Express I'm using the request-promise package for promises if that's worth to mention.
const optionsComment = {
method: 'POST',
uri: 'https://www.googleapis.com/youtube/v3/commentThreads',
qs: {
part: 'snippet',
'snippet.channelId': 'a channel id',
'snippet.videoId': 'some video id',
'snippet.topLevelComment.snippet.textOriginal': 'a nice message',
key: "my key"
},
json: true
};
rp(optionsComment)
.then(result=>{
console.log("result of adding comment:", result);
})
.catch(function(err){
console.log("error during add comment");
console.log(err);
});
When I run the code I get this error:
error during add comment
{ StatusCodeError: 401 - {"error":{"errors":[{"domain":"global","reason":"required","message":"Login Required","locationType":"header","location":"Authorization"}],"code":401,"message":"Login Required"}}
at new StatusCodeError
Even if I'm logged in and try to comment my own video I get this error.
Maybe someone can give me a hint.
Thank you!
I'd similar issue as yours, sending the access_token in qs fixed it for me.
'use strict';
let request = require('request');
const sourceId = '< youtube video id>';
const comment_id = 'the comment id';
const comment = 'actual comment';
new Promise((resolve, reject) => {
request({
method: 'POST',
url: 'https://www.googleapis.com/youtube/v3/commentThreads',
headers: {
'User-Agent': 'Request-Promise'
},
body: {
"snippet": {
"videoId": sourceId,
"channelId": comment_id,
"topLevelComment": {
"snippet": {
"textOriginal": comment
}
}
}
},
qs: {
part: 'snippet',
access_token: token
},
json: true
}, function (error, response, body) {
if (error) {
console.log('body', body);
console.log('error in when posting comment ', error.stack);
return reject(error);
}
return resolve(body);
});
});
Related
I am receiving a request response in the console.log, however when I try to post to Mastodon (similar site to Twitter), it posts as 'undefined'.
bot.js:
require('dotenv').config();
const Mastodon = require('mastodon-api');
var request = require('request');
console.log("Mastodon Bot starting...");
const M = new Mastodon({
access_token: process.env.ACCESS_TOKEN,
client_key: process.env.CLIENT_KEY,
client_secret: process.env.CLIENT_SECRET,
timeout_ms: 60*1000,
api_url: 'https://botsin.space/api/v1/',
})
const options = {
method: 'GET',
url: 'https://apisite.com/steps',
qs: {count: '3'},
headers: {
'X-RapidAPI-Key': 'secret-api-key',
'X-RapidAPI-Host': 'site-host',
useQueryString: true,
},
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(JSON.parse(body, undefined, 5));
});
const params = {
status: request
}
M.post('/statuses', params, (error, params) => {
if (error) {
console.log(error);
}
else {
console.log(params.request);
}
});
This posts "Mastodon bot is starting...", then the results of the API GET request to the console (the response body).
However, it does not post the response body to /statuses in Mastodon itself, it just posts 'undefined'.
How can I post the response body that I get in the console, to Mastodon?
Scenario
I've had a problem for 4 hours, I'm trying to send an http get request while sending the user ID as a parameter. I try a lot of examples found on the net but I still have this error on the backend side.
GET http://localhost:3000/api/users/getusersbyid/?userId=00c1308a-32ad-48a0-8737-d4682b2b504e 500 (Internal Server Error)
Here is my JS function code:
async function getUserById() {
try {
await $.ajax({
type: "GET",
url: "http://localhost:3000/api/users/getusersbyid",
data: {
userId: "00c1308a-32ad-48a0-8737-d4682b2b504e"
},
contentType: "application/x-www-form-urlencoded"
}).done(function(response) {
console.log(response);
}).fail(function(err) {
console.log(err);
});
} catch (error) {
console.log(error);
}
}
Here is my Backend function code using NodeJs:
getUserById: function(req, res) {
let userId = req.body.userId;
models.User.findOne({
where: {
id: userId
},
include: [{
model: models.TypeUser,
attributes: ['code', 'value']
}]
}).then(function(data) {
if (data) {
res.status(201).json({
'status': 'success',
'code': 201,
'data': data
});
} else {
res.status(404).json({
'status': 'falled',
'code': 404,
'message': 'Unable to find one or more users'
});
}
}).catch(function(err) {
res.status(500).json({
'status': 'falled',
'code': 500,
'message': 'An internal error has occurred',
'data': err
});
});
}
Here is my Backend Error Message image:
Need your help and suggestions
It seems something's going on in your backend. Have you tried using logging, for example after your "let userId = req.body.userId;" line to see if your server is receiving the userId?
console.log("backend received userId="+userId)
I just solved the problem after reading the answers from #AbhishekKumawat and from #Pointy. So using the "GET" method, I should do this:
let userId = req.query.userId;
instead.
let userId = req.body.userId;
So I wrote Slack reporter for my automated tests and wanted to switch from deprecated module 'request' to 'https' module. I changed the request sending a normal message but I don't know how to create a request for sending a file. I can't find any example in node documentation (no POST examples for 'https' there) nor any example of that kind of use on the internet. Can anyone help me with this?
That's the working request:
function sendLogFile() {
console.log("Sending log file to slack...");
return new Promise((resolve, reject) => {
request.post(
{
url: fileUploadUrl,
formData: {
token: token,
method: "POST",
title: "Test Log File",
filename: "testLog.txt",
filetype: "auto",
channels: "***",
file: fs.createReadStream("testLog.txt")
}
},
function(err, response) {
if (response.body.includes("created"))
resolve("File send successfully!");
if (response.body.includes("error")) reject(response.body);
if (err) reject(err);
}
);
});
}
And this is kinda (SEE THE EDIT BELOW) what I want (but it's not working):
function sendLogFile() {
return new Promise((resolve, reject) => {
const requestOptions = {
url: fileUploadUrl,
headers: headers,
formData: {
token: token,
method: "POST",
title: "Test Log File",
filename: "testLog.txt",
filetype: "auto",
channels: "***",
file: fs.createReadStream("testLog.txt")
}
};
const req = https.request(requestOptions, res => {
res.on("data", d => resolve(d));
});
req.on("error", e => {
reject(e);
});
// Probably that's the part where I'm stuck:
req.write('????????')
req.end();
});
}
I know there is slackapi for node but the thing is I need this reporter to be without any additional packages. And I know it's possible with request.promise or xhr but I need this to be 'https'.
EDIT:
Ok, so I was trying to get somewhere and I think it should look more like:
const file = fs.createReadStream("testLog.txt");
const options = {
channels: "***",
hostname: "slack.com",
port: 443,
path: '/api/files.upload',
method: 'POST',
headers: {
'Authorization': "Bearer ***",
'Content-Type': 'application/json; charset=utf-8',
}
}
const req = https.request(options, res => {
console.log(`statusCode: ${res.statusCode}`)
res.on('data', d => {
process.stdout.write(d)
})
})
req.on('error', error => {
console.error(error)
})
req.write(data)
req.end()
But I have no idea how to past file to req.write(data) since 'data' has to be string, Buffer, ArrayBuffer, Array, or Array-like Object.
So, for now, the response I get is:
statusCode: 200 {"ok":false,"error":"no_file_data"}%
And I'm also not sure if it's possible because slack API says the header should be formData but this response suggests this approach is fine I guess.
Anyone, please?
If you refer to https documentation you can see that options object does not accept such property as formData.
Instead, you should try to send the post data like in this answer.
I'm using axios and an API to get a page's HTML, editing the HTML, and putting it back via a POST request to the API. I'm successful in retrieving and editing the HTML but I can't figure out how to put it back/change the webpage's HTML.
I tried using a PUT request instead of a POST request, but I get a 405 error that the PUT method is not allowed for the webpage.
axios.get(url, {
auth: {
username: USERNAME,
password: PASSWORD
},
headers: {
'Content-Type': 'application/json'
}
})
.then( (response) => {
version = response.data.version.number;
body = response.data.body.storage.value;
// takes the body HTML and formats all the links
newBody = middleware.formatLinks(body);
data = {
"type": "page",
'version': {'number': version + 1},
'body': {
'storage': {
'value': newBody,
'representation': 'storage'
}
}
}
// put the body HTML back into the page
axios.post(url, {
data: {
"type": "page",
'version': {'number': version + 1},
'body': {
'storage': {
'value': newBody,
'representation': 'storage'
}
}
}
}, {
auth: {
username: USERNAME,
password: PASSWORD
},
headers: {
'Content-Type': 'application/json'
}
})
.then( (response) => {
console.log(response.data);
})
.catch( (error) => {
console.log(error);
})
})
.catch( (error) => {
console.log(error);
})
I expect the page to now be updated with all the links formatted to my liking. However the page is unchanged. When I console.log(response.data) after making the post request, the output is a string of newBody, when I expect it to be the JSON object
data: {
'type': 'page',
'version': {'number': version + 1},
'body': {
'storage': {
'value': newBody,
'representation': 'storage'
}
}
}
As mentioned in my comment in #Aman Raj's answer, I have the code working in python but translating it to nodejs was giving me issues. So I circumvented my problem by calling my python script in nodejs with the python-shell package.
let {PythonShell} = require('python-shell');
...
const formatLinks = (id) => {
let options = {
mode: 'text',
pythonOptions: ['-u'], // get print results in real-time
scriptPath: './python/', // path to my python scripts
// pass in the page id, username, and password to API request
args: [id, USERNAME, PASSWORD]
};
PythonShell.run('script.py', options, (err, results) => {
if (err) throw err;
// results is an array consisting of messages collected during execution
console.log('results: %j', results);
});
}
Your code seems fine. It may be possible that you are accessing an API which does not support editing it.
The HyperText Transfer Protocol (HTTP) 405 Method Not Allowed response
status code indicates that the request method is known by the server
but is not supported by the target resource.
I get a 403 "You must specify an API key to make request" when trying to get data from a 3rd party API (Klaviyo).
const { id } = req.body
request.get({
url: `https://a.klaviyo.com/api/v1/person/${id}`,
headers: {
api_key: process.env.KLAVIYO_API_KEY
}
}, (error, response, body) => {
const profile = JSON.parse(body)
console.log(profile)
if (response.statusCode === 200) {
res.json({ profile, status: 201 })
} else {
res.json({ error: 'Did not get customer data', status: 500, response: response, err: error })
}
})
I've also tried with:
headers: {"Authorization": [API_KEY]}
data: {api_key: [API_KEY]}
Solution:
const { id } = req.body
request.get({
url: `https://a.klaviyo.com/api/v1/person/${id}`,
qs: {
api_key: process.env.KLAVIYO_API_KEY
}
}, (error, response, body) => {
const profile = JSON.parse(body)
console.log(profile)
if (response.statusCode === 200) {
res.json({ profile, status: 201 })
} else {
res.json({ error: 'Did not get customer data', status: 500, response: response, err: error })
}
})
Short answer: add it under params.api_key (as part of the GET request).
From the klaviyo documentation:
"You authenticate to the People API by providing one of your private API keys as part of each request. (...) Authentication happens via the api_key parameter in each request. It can be sent as part of the GET or POST parameters."
I think you are using GET request with POST header method. In GET you need to put it in URL