I'm trying to access my WordPress site from a NodeJS program. Specifically, I'm trying to create a draft post from within a NodeJS program. I've never done this before, and I can't get it work.
I've tried a few ways of doing this. First I used WPAPI and went through the documentation for that. It seemed to connect and get a response from my site but no post was created.
WPAPI method and response log
I've gotten an application password through the Wordpress control panel and I'm using it in the program. The username is from the same page on my panel.
I had installed the JSON Basic Authentication plugin while working with WPAPI, but I deactivated it when I switched to another method.
(Following the documentation on GitHub for WPAPI, I thought I would need to install the superagent bundle so I could use create() I tried installing superagent, requiring wpapi/superagent, and changing the type to module in the package, but when I tried to run it I got an error message saying the module "wpapi/superagent" could not be found. After that I just went back to the general import.)
import WPAPI from "wpapi"
const wp = new WPAPI({
endpoint: 'https://www.example.com/wp-json',
username: 'username',
password: 'application_password'
})
wp.posts().create({
title: 'test post',
content: 'will this work?'
}).then((res) => {
console.log(res)
})
The log:
[
{
id: 1,
date: '2022-09-11T22:33:39',
date_gmt: '2022-09-11T22:33:39',
guid: { rendered: 'https://example.com/?p=1' },
modified: '2022-09-11T22:33:39',
modified_gmt: '2022-09-11T22:33:39',
slug: 'hello-world',
status: 'publish',
type: 'post',
link: 'https://example.com/2022/09/11/hello-world/',
title: { rendered: 'Hello world!' },
content: {
rendered: '\n' +
'<p>Welcome to WordPress. This is your first post. Edit or delete it, then start writing!</p>\n',
protected: false
},
excerpt: {
rendered: '<p>Welcome to WordPress. This is your first post. Edit or delete it, then start writing!</p>\n',
protected: false
},
author: 1,
featured_media: 0,
comment_status: 'open',
ping_status: 'open',
sticky: false,
template: '',
format: 'standard',
meta: {
bgseo_title: '',
bgseo_description: '',
bgseo_robots_index: '',
bgseo_robots_follow: ''
},
categories: [ 1 ],
tags: [],
aioseo_notices: [],
_links: {
self: [Array],
collection: [Array],
about: [Array],
author: [Array],
replies: [Array],
'version-history': [Array],
'wp:attachment': [Array],
'wp:term': [Array],
curies: [Array]
}
},
_paging: {
total: 1,
totalPages: 1,
links: { 'https://api.w.org/': 'https://example.com/wp-json/' }
}
]
Using Fetch to send the post
Now I'm trying code from a guide I found on Medium, and I'm having pretty much the same problem.
I receive a response that I believe means the connection was successful, but no posts have been created on my site, draft or otherwise.
Here's the code:
import fetch from "node-fetch"
const createdPost = await fetch(`https://www.example.com/wp-json/wp/v2/posts`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Basic ${Buffer.from("username:application_password", "utf-8").toString("base64")}`
},
body: JSON.stringify({
title: 'New post title',
content: 'New content'
})
})
console.log(createdPost)
And this is what is logged:
Response {
size: 0,
[Symbol(Body internals)]: {
body: PassThrough {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 6,
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: true,
[Symbol(kCapture)]: false,
[Symbol(kCallback)]: null
},
stream: PassThrough {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 6,
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: true,
[Symbol(kCapture)]: false,
[Symbol(kCallback)]: null
},
boundary: null,
disturbed: false,
error: null
},
[Symbol(Response internals)]: {
type: 'default',
url: 'https://example.com/wp-json/wp/v2/posts',
status: 200,
statusText: 'OK',
headers: {
'access-control-allow-headers': 'Authorization, X-WP-Nonce, Content-Disposition, Content-MD5, Content-Type',
'access-control-expose-headers': 'X-WP-Total, X-WP-TotalPages, Link',
allow: 'GET',
'cache-control': 'max-age=172800',
connection: 'Upgrade, close',
'content-type': 'application/json; charset=UTF-8',
date: 'Mon, 03 Oct 2022 14:43:35 GMT',
expires: 'Wed, 05 Oct 2022 14:43:35 GMT',
link: '<https://example.com/wp-json/>; rel="https://api.w.org/"',
server: 'Apache',
'transfer-encoding': 'chunked',
upgrade: 'h2',
vary: 'Accept-Encoding,Cookie,Origin,User-Agent',
'x-content-type-options': 'nosniff',
'x-robots-tag': 'noindex',
'x-wp-total': '1',
'x-wp-totalpages': '1'
},
counter: 1,
highWaterMark: 16384
}
}
Summary
Both methods seem to connect but no post is created on my site. Can anyone help? I'm stuck and would really appreciate it.
Related
i am sending a file from my front end to custom strapi backend, where i proccess the request and then send to another server.
However code doesnt seems to work, i recieve file but unable to send it with response 400 all the time.
module.exports = {
index: async ({ request }) => {
const form = new FormData();
form.append(
"files",
fs.readFileSync(request.files.files.path),
request.files.files.name
);
const { data } = await axios.post(
url,
form.getBuffer(),
{
headers: {
accept: request.headers["accept"],
"content-length": request.headers["content-length"],
...form.getHeaders(),
},
}
);
return data;
},
};
There is my console.log(request.files)
{
files: File {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
size: 7677,
path: '/var/folders/h7/lsr9qcb9377gfgqn6rqhld6w0yg716/T/upload_32c7d794053db8d99c7c5d234f94f7d8',
name: 'stažený soubor.jpeg',
type: 'image/jpeg',
hash: null,
lastModifiedDate: 2022-10-05T11:30:08.325Z,
_writeStream: WriteStream {
fd: null,
path: '/var/folders/h7/lsr9qcb9377gfgqn6rqhld6w0yg716/T/upload_32c7d794053db8d99c7c5d234f94f7d8',
flags: 'w',
mode: 438,
start: undefined,
pos: undefined,
bytesWritten: 7677,
closed: true,
_writableState: [WritableState],
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
[Symbol(kFs)]: [Object],
[Symbol(kIsPerformingIO)]: false,
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false
}
}
This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
Closed 1 year ago.
I'm a novice programmer so please bear with me. I am running an user update API which returns a response object like this:
response: {
config: {
url: 'https://admin.googleapis.com/admin/directory/v1/users/xxxxxxxx#xxxxx.solutions',
method: 'PUT',
userAgentDirectives: [Array],
paramsSerializer: [Function (anonymous)],
data: [Object],
headers: [Object],
params: {},
validateStatus: [Function (anonymous)],
retry: true,
body: '{"password":"XXXXXXXXXX"}',
responseType: 'json',
retryConfig: [Object]
},
data: { error: [Object] },
headers: {
'alt-svc': 'h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"',
'cache-control': 'private',
connection: 'close',
'content-encoding': 'gzip',
'content-type': 'application/json; charset=UTF-8',
date: 'Thu, 15 Apr 2021 20:00:00 GMT',
server: 'ESF',
'transfer-encoding': 'chunked',
vary: 'Origin, X-Origin, Referer',
'x-content-type-options': 'nosniff',
'x-frame-options': 'SAMEORIGIN',
'x-xss-protection': '0'
},
status: 400,
statusText: 'Bad Request',
request: {
responseURL: 'https://admin.googleapis.com/admin/directory/v1/users/xxxxxxxx#xxxxx.solutions'
}
},
config: {
url: 'https://admin.googleapis.com/admin/directory/v1/users/xxxxxxxx#xxxxx.solutions',
method: 'PUT',
userAgentDirectives: [ [Object] ],
paramsSerializer: [Function (anonymous)],
data: { password: '12345678' },
headers: {
'x-goog-api-client': 'gdcl/5.0.2 gl-node/14.15.1 auth/7.0.3',
'Accept-Encoding': 'gzip',
'User-Agent': 'google-api-nodejs-client/5.0.2 (gzip)',
Authorization: 'Bearer ya29.a0AfH6SMDxjWFzlvhDY1SHM_DKtDyfl5L7PLqMf1i1GP1MdFNX3-OorIzjqdfvGmIZWgf0sexxLanQZXtQRGyiMtct_ecH3l3hZGK7fHtmSzxedfUyczdrSG49eezMm8NmoAXm4iFA7JK_4HmGNpgxrhclObPfKIbhrtJoyiIMk3C56Gx9G7aZ4-OycGJfV6trYLRLzr927CnZhO95',
'Content-Type': 'application/json',
Accept: 'application/json'
},
params: {},
validateStatus: [Function (anonymous)],
retry: true,
body: '{"password":"xxxxxxxx#xxxxx"}',
responseType: 'json',
retryConfig: {
currentRetryAttempt: 0,
retry: 3,
httpMethodsToRetry: [Array],
noResponseRetries: 2,
statusCodesToRetry: [Array]
}
},
code: 400,
errors: [
{
message: 'Invalid Password',
domain: 'global',
reason: 'invalid'
}
]
}
I am trying to extract the message inside the errors to display in a later page. How would I able to do that?
Please post your code.
But you can try something like this.
response.data.error.forEach(error => {
console.log(error.message);
})
Trying to send an image through GupShup. I'm using their sandbox. My backend is node.js with feathersjs.
But it's returning me this error:
Response {
size: 0,
timeout: 0,
[Symbol(Body internals)]: {
body: PassThrough {
_readableState: [ReadableState],
readable: true,
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_writableState: [WritableState],
writable: false,
allowHalfOpen: true,
_transformState: [Object],
[Symbol(kCapture)]: false
},
disturbed: false,
error: null
},
[Symbol(Response internals)]: {
url: 'https://api.gupshup.io/sm/api/v1/msg',
status: 400,
statusText: 'Bad Request',
headers: Headers { [Symbol(map)]: [Object: null prototype] },
counter: 0
}
}
This is the code to send the image
const form = new URLSearchParams();
form.append('channel', 'whatsapp');
form.append('destination', destination);
form.append('source', app.get('GUPSHUP_NUMBER'));
form.append('message.payload', JSON.stringify(message));
form.append('src.name', 'OneAccess');
console.log(form);
try {
const res = await fetch('https://api.gupshup.io/sm/api/v1/msg', {
method: 'POST',
body: form,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
apikey: app.get('GUPSHUP_API'),
},
});
console.log('result message', res);
} catch (err) {
console.log('errro sending msg', err);
}
This is the message that I'm trying to send
message: {
type: 'image',
originalUrl:
'https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg',
previewUrl:
'https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg',
caption: 'Sample image',
},
Can anyone help me?
Change message.payload to message. You can check the correct signature at https://www.gupshup.io/developer/docs/bot-platform/guide/whatsapp-api-documentation#SendImage
I am trying to authorise my server for calling the youtube analytics api via the module "googleapis" (https://www.npmjs.com/package/googleapis). I want to use the JWT to authorise. As you can see I get a forbidden error back from the api.
I read a ton of posts and tinkered around for a whole while, but I can't figure out what is wrong.
Is my code ok? Otherwise it as to be a google cloud related issue. (E.g. I did not set up the roles properly there.)
import fs from 'fs';
import { google } from 'googleapis';
// read credentials from file
const credentialsFromFile = fs.readFileSync(`${__dirname}/../credentials.json`);
const credentials = JSON.parse(credentialsFromFile.toString());
const scopes = [
'https://www.googleapis.com/auth/youtube.readonly',
'https://www.googleapis.com/auth/yt-analytics-monetary.readonly',
'https://www.googleapis.com/auth/youtubepartner',
];
// get an authorized client
const jwtClient = new google.auth.JWT(
credentials.client_email,
null,
credentials.private_key,
scopes
);
const youtubeAnalyticsClient = google.youtubeAnalytics({
version: 'v1',
auth: jwtClient,
});
function runQuery(callback) {
youtubeAnalyticsClient.reports.query(
{
auth: jwtClient,
ids: 'channel==MINE',
'start-date': '2018-01-01',
'end-date': '2018-02-01',
metrics: 'views',
},
(error, result) => {
if (error) console.log(error.errors);
else {
console.log(result);
callback(result);
}
}
);
}
jwtClient.authorize((error, result) => {
if (error) console.log(error);
else {
/*
{ access_token: '{THE ACCESS TOKEN}',
token_type: 'Bearer',
expiry_date: 1522070090000,
refresh_token: 'jwt-placeholder' } */
console.log(result);
runQuery(() => {
// worked :)
});
}
});
The response object may be helpful:
response:
{ status: 403,
statusText: 'Forbidden',
headers:
{ vary: 'X-Origin, Origin,Accept-Encoding',
'content-type': 'application/json; charset=UTF-8',
date: 'Mon, 26 Mar 2018 10:39:33 GMT',
expires: 'Mon, 26 Mar 2018 10:39:33 GMT',
'cache-control': 'private, max-age=0',
'x-content-type-options': 'nosniff',
'x-frame-options': 'SAMEORIGIN',
'x-xss-protection': '1; mode=block',
server: 'GSE',
'alt-svc': 'hq=":443"; ma=2592000; quic=51303432; quic=51303431; quic=51303339; quic=51303335,quic=":443"; ma=2592000; v="42,41,39,35"',
'accept-ranges': 'none',
connection: 'close' },
config:
{ adapter: [Function: httpAdapter],
transformRequest: [Object],
transformResponse: [Object],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: 2147483648,
validateStatus: [Function],
headers: [Object],
method: 'get',
url: 'https://www.googleapis.com/youtube/analytics/v1/reports',
paramsSerializer: [Function],
data: undefined,
params: [Object] },
request:
ClientRequest {
domain: null,
_events: [Object],
_eventsCount: 6,
_maxListeners: undefined,
output: [],
outputEncodings: [],
outputCallbacks: [],
outputSize: 0,
writable: false,
_last: true,
upgrading: false,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [Object],
connection: [Object],
_header: 'GET /youtube/analytics/v1/reports?ids=channel%3D%3DMINE&start-date=2018-01-01&end-date=2018-02-01&metrics=views HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nAuthorization: Bearer ya29.c.El6KBUokXWf8yjN1LXk04b3FTGa1jadNEmvbyLBQfVmK9KIbxwxA6e88m_OujuTcyrJW60ojwnKiNfH-9E2iegmwlDOdKI8VxORrniGIt9gc_FGp2tvi2GLabzTri74b\r\nUser-Agent: google-api-nodejs-client/1.3.2\r\nHost: www.googleapis.com\r\nConnection: close\r\n\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: [Object],
socketPath: undefined,
timeout: undefined,
method: 'GET',
path: '/youtube/analytics/v1/reports?ids=channel%3D%3DMINE&start-date=2018-01-01&end-date=2018-02-01&metrics=views',
_ended: true,
res: [Object],
aborted: undefined,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
_redirectable: [Object],
[Symbol(outHeadersKey)]: [Object] },
data: { error: [Object] } },
code: 403,
errors: [ { domain: 'global', reason: 'forbidden', message: 'Forbidden' } ] }
Update 1
I updated the code a little, so that is analog to this example implementation: https://github.com/google/google-api-nodejs-client/blob/HEAD/samples/jwt.js
I get an authorised client as seen in the code, but the same error occurs. I am pretty sure I messed up the settings in the google cloud settings. Is it necessary to do the domain verification at google cloud when developing locally?
Update 2
Even with OAuth2 Authentication (passing a code as cli arg after allowing scopes in the browser) I get the forbidden-error. Seems like I need to enable it in the cloud dev console, but how do I do that?
In my react-native application on the login screen I'm working on providing the user with nice error messaging after entering in the incorrect username / password combination. To interact with the API I'm using the library Axios. However when I get an error in the catch statement, I get this ugly error message saying that I have an "unhandled promise rejection" and I cannot do things such as set the components state or navigate to a new page.
I can't see what I'm doing wrong, it looks exactly like examples I've seen in the docs.
In my form submission function I have:
axios.post('http://192.168.1.11:1337/login', {
email: this.state.username,
password: this.state.password
}).then(function (response) {
// This stuff all seems to work great
console.log("The response we got: ", response);
if (response.status == 200) {
console.log("Status code equals 200");
Actions.homepage();
}
}).catch(function (err) {
// Run into big problems when I get an error
console.log("Got an error logging in, here's the message: ", err);
});
Can anyone see what I'm doing wrong here?
P.S. Here is the error message I'm getting back from the server, which get's logged from that console.log("Got an error logging in, here's the message: ", err);:
"Got an error logging in, here's the message:"
{ [Error: Request failed with status code 401]
config:
{ transformRequest: { '0': [Function: transformRequest] },
transformResponse: { '0': [Function: transformResponse] },
headers:
{ Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/json;charset=utf-8' },
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
method: 'post',
url: 'http://192.168.1.11:1337/login',
data: '{"email":"zach#homies.io","password":"dddddd"}' },
response:
{ data: { message: 'Invalid password', user: false },
status: 401,
statusText: undefined,
headers:
{ map:
{ connection: [ 'keep-alive' ],
date: [ 'Thu, 31 Aug 2017 23:30:21 GMT' ],
'x-powered-by': [ 'Sails <sailsjs.org>' ],
vary: [ 'X-HTTP-Method-Override' ],
'content-length': [ '52' ],
'access-control-allow-credentials': [ '' ],
'access-control-allow-origin': [ '' ],
etag: [ 'W/"34-Ymi4isRxuJ6jE1EIS+AQag"' ],
'access-control-allow-methods': [ '' ],
'access-control-allow-headers': [ '' ],
'access-control-expose-headers': [ '' ],
'content-type': [ 'application/json; charset=utf-8' ] } },
config:
{ transformRequest: { '0': [Function: transformRequest] },
transformResponse: { '0': [Function: transformResponse] },
headers:
{ Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/json;charset=utf-8' },
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
method: 'post',
url: 'http://192.168.1.11:1337/login',
data: '{"email":"zach#homies.io","password":"dddddd"}' },
request:
{ url: 'http://192.168.1.11:1337/login',
credentials: 'omit',
headers:
{ map:
{ accept: [ 'application/json, text/plain, */*' ],
'content-type': [ 'application/json;charset=utf-8' ] } },
method: 'POST',
mode: null,
referrer: null,
_bodyInit: '{"email":"zach#homies.io","password":"dddddd"}',
_bodyText: '{"email":"zach#homies.io","password":"dddddd"}',
bodyUsed: true } } }
Here is a screenshot of what it looks like on the Android emulator (emulating a Samsung Galaxy S7):
There is nothing wrong in this snippet.
You send a request.
You get a 401 - unauthorized response.
Catch receives the error and logs it.
The interesting part is why you get that unhandled promise rejection error.
But this is thrown somewhere else. So you need to provide more of the code.
Edit:
Perhaps you just have to return your axios promise to the calling function?
I have same problem and I use Firebase for database
I resolve this problem
put database on realtime instead of cloud Firestore like the picture
I hope this worked for you