I'm trying to translate a curl request to an axios request as such:
Here is the curl request format:
curl -s -X POST \
-d '{"version": "12ac28616dba364cc9f1e30c610c6efd62dbe9b9c7d1d03ea", "input": {"prompt": "sunset over a lake in the mountains"}' \
-H "Authorization: Token 123123123123123123" \
-H 'Content-Type: application/json' \
https://api.replicate.com/v1/predictions
And here is how I translated it to an axios request:
try {
const response = await axios.post(
"https://api.replicate.com/v1/predictions",
'{"version": "12ac28616dba364cc9f1e30c610c6efd62dbe9b9c7d1d03ea", "input": {"prompt": "sunset over a lake in the mountains"}',
{
headers: {
Authorization: "Token 123123123123123123",
"Content-Type": "application/json",
},
}
);
console.log("RESPONSE ----->", response);
} catch (err) {
console.info("ERROR---->", err);
}
However, I keep receiving the following error:
ERROR----> [AxiosError: Request failed with status code 400] {
code: 'ERR_BAD_REQUEST'
Is the code formatted properly?
Full error:
2022-07-04T15:14:47.902Z d13a7d45-eb0b-4365-a721-f06f2f2fc968 INFO ERROR----> [AxiosError: Request failed with status code 400] {
code: 'ERR_BAD_REQUEST',
config: {
transitional: {
silentJSONParsing: true,
forcedJSONParsing: true,
clarifyTimeoutError: false
},
adapter: [Function: httpAdapter],
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
env: { FormData: [Function] },
validateStatus: [Function: validateStatus],
headers: {
Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/json',
Authorization: 'Token 123123123',
'User-Agent': 'axios/0.27.2',
'Content-Length': 150
},
method: 'post',
url: 'https://api.replicate.com/v1/predictions',
data: '"{\\"version\\": \\"2e3975b1692cd6aecac28616dba364cc9f1e30c610c6efd62dbe9b9c7d1d03ea\\", \\"input\\": {\\"prompt\\": \\"sunset over a lake in the mountains\\"}"'
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype] {
abort: [Function (anonymous)],
aborted: [Function (anonymous)],
connect: [Function (anonymous)],
error: [Function (anonymous)],
socket: [Function (anonymous)],
timeout: [Function (anonymous)],
prefinish: [Function: requestOnPrefinish]
},
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: null,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
secureConnecting: false,
_SNICallback: null,
servername: 'api.replicate.com',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 10,
connecting: false,
_hadError: false,
_parent: null,
_host: 'api.replicate.com',
_readableState: [ReadableState],
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular *1],
[Symbol(res)]: [TLSWrap],
[Symbol(verified)]: true,
[Symbol(pendingSession)]: null,
[Symbol(async_id_symbol)]: 6,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(kSetNoDelay)]: false,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object],
[Symbol(RequestTimeout)]: undefined
},
_header: 'POST /v1/predictions HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'Content-Type: application/json\r\n' +
'Authorization: Token 123123123123123\r\n' +
'User-Agent: axios/0.27.2\r\n' +
'Content-Length: 150\r\n' +
'Host: api.replicate.com\r\n' +
'Connection: close\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: noopPendingOutput],
agent: Agent {
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object],
requests: {},
sockets: [Object],
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
scheduling: 'lifo',
maxTotalSockets: Infinity,
totalSocketCount: 1,
maxCachedSessions: 100,
_sessionCache: [Object],
[Symbol(kCapture)]: false
},
socketPath: undefined,
method: 'POST',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: '/v1/predictions',
_ended: true,
res: IncomingMessage {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 4,
_maxListeners: undefined,
socket: [TLSSocket],
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
headers: [Object],
rawHeaders: [Array],
trailers: {},
rawTrailers: [],
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 400,
statusMessage: 'Bad Request',
client: [TLSSocket],
_consuming: false,
_dumped: false,
req: [Circular *1],
responseUrl: 'https://api.replicate.com/v1/predictions',
redirects: [],
[Symbol(kCapture)]: false,
[Symbol(RequestTimeout)]: undefined
},
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'api.replicate.com',
protocol: 'https:',
_redirectable: Writable {
_writableState: [WritableState],
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
_options: [Object],
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 150,
_requestBodyBuffers: [],
_onNativeResponse: [Function (anonymous)],
_currentRequest: [Circular *1],
_currentUrl: 'https://api.replicate.com/v1/predictions',
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] {
accept: [Array],
'content-type': [Array],
authorization: [Array],
'user-agent': [Array],
'content-length': [Array],
host: [Array]
}
},
response: {
status: 400,
statusText: 'Bad Request',
headers: {
date: 'Mon, 04 Jul 2022 15:14:47 GMT',
'content-type': 'application/json',
'content-length': '74',
connection: 'close',
allow: 'GET, POST, HEAD, OPTIONS',
'x-frame-options': 'DENY',
'x-content-type-options': 'nosniff',
'referrer-policy': 'same-origin',
'cross-origin-opener-policy': 'same-origin',
via: '1.1 vegur',
'cf-cache-status': 'DYNAMIC',
'expect-ct': 'max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"',
'report-to': '{"endpoints":[{"url":"https:\\/\\/a.nel.cloudflare.com\\/report\\/v3?s=BBZ%2FuLKvNnSPD5CiPhRgFwAJA2cjjQUj29MokMhPaNhdRqCr%2Fe4xMan2uLUk2YW3q10spY8wQPnRlmhFUfg6N5t4kLVwBqmKs2UD%2B8Q9Fx7v5zXNpoV%2FkTNRt352MjWtAmKV"}],"group":"cf-nel","max_age":604800}',
nel: '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}',
'strict-transport-security': 'max-age=15552000',
server: 'cloudflare',
'cf-ray': '7258d008fc19823f-IAD'
},
config: {
transitional: [Object],
adapter: [Function: httpAdapter],
transformRequest: [Array],
transformResponse: [Array],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
env: [Object],
validateStatus: [Function: validateStatus],
headers: [Object],
method: 'post',
url: 'https://api.replicate.com/v1/predictions',
data: '"{\\"version\\": \\"2e3975b1692cd6aecac28616dba364cc9f1e30c610c6efd62dbe9b9c7d1d03ea\\", \\"input\\": {\\"prompt\\": \\"sunset over a lake in the mountains\\"}"'
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: null,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [TLSSocket],
_header: 'POST /v1/predictions HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'Content-Type: application/json\r\n' +
'Authorization: Token 123123123123123\r\n' +
'User-Agent: axios/0.27.2\r\n' +
'Content-Length: 150\r\n' +
'Host: api.replicate.com\r\n' +
'Connection: close\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: noopPendingOutput],
agent: [Agent],
socketPath: undefined,
method: 'POST',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: '/v1/predictions',
_ended: true,
res: [IncomingMessage],
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'api.replicate.com',
protocol: 'https:',
_redirectable: [Writable],
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype]
},
data: { non_field_errors: [Array] }
}
}
You are forgetting the Token part in the Authorization header:
Authorization: "123123123123123123"
If you look on the response from your axios call you will see this:
data: { detail: 'Authentication credentials were not provided.' }
So just update your code and add the Token:
Authorization: "Token 123123123123123123"
I also think you might have problem with you actual data, try sending it like this instead:
const response = await axios.post(
"https://api.replicate.com/v1/predictions",
{
version: "12ac28616dba364cc9f1e30c610c6efd62dbe9b9c7d1d03ea",
input: {
prompt: "sunset over a lake in the mountains"
}
},
{
headers: {
Authorization: "Token 123123123123123123",
"Content-Type": "application/json",
},
}
);
or serialize the data before you send it:
const data = JSON.stringify({
version: "12ac28616dba364cc9f1e30c610c6efd62dbe9b9c7d1d03ea",
input: {
prompt: "sunset over a lake in the mountains"
}
});
const response = await axios.post(
"https://api.replicate.com/v1/predictions", data,
{
headers: {
Authorization: "Token 123123123123123123",
"Content-Type": "application/json",
},
}
);
As you can see in your error message the data is getting escaped, so this is probably the problem:
data: '"{\\"version\\": \\"2e3975b1692cd6aecac28616dba364cc9f1e30c610c6efd62dbe9b9c7d1d03ea\\", \\"input\\": {\\"prompt\\": \\"sunset over a lake in the mountains\\"}"'
Related
I am trying to get the youtube transcription with youtube API on the Express.js server. From what I understand, I need to use the client id for this, so I am trying to authenticate to google API. For this purpose I use quickstart.js from google docs and Express listener on redirect_uri to handle authentication:
interface GoogleOAuthTokenResponse {
access_token: string
token_type: string
expires_in: number
id_token: string
refresh_token?: string
}
// Handle authentication callback from Google
app.get('/auth/google/callback', async (req, res, next) => {
const code = req.query.code
const response = await axios.post<GoogleOAuthTokenResponse>('https://oauth2.googleapis.com/token', {
code,
client_id: process.env.YOUTUBE_CLIENT_ID,
client_secret: process.env.YOUTUBE_CLIENT_SECRET,
redirect_uri: process.env.YOUTUBE_REDIRECT_URI,
grant_type: 'authorization_code'
}, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
const accessToken = response.data.access_token
// Now that we have the access token and id token, we can use them to call Google API services
const googleResponse = await axios.get('https://www.googleapis.com/some_google_api', {
headers: {
Authorization: `Bearer ${accessToken}`
}
})
res.send(googleResponse.data)
})
But I get the following error:
/Users/demian/Desktop/work/youtube-navigator/server/node_modules/axios/lib/core/settle.js:19
reject(new AxiosError(
^
AxiosError: Request failed with status code 400
at settle (/Users/demian/Desktop/work/youtube-navigator/server/node_modules/axios/lib/core/settle.js:19:12)
at Unzip.handleStreamEnd (/Users/demian/Desktop/work/youtube-navigator/server/node_modules/axios/lib/adapters/http.js:548:11)
at Unzip.emit (node:events:525:35)
at Unzip.emit (node:domain:489:12)
at endReadableNT (node:internal/streams/readable:1359:12)
at processTicksAndRejections (node:internal/process/task_queues:82:21) {
code: 'ERR_BAD_REQUEST',
config: {
transitional: {
silentJSONParsing: true,
forcedJSONParsing: true,
clarifyTimeoutError: false
},
adapter: [ 'xhr', 'http' ],
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
env: { FormData: [Function], Blob: [class Blob] },
validateStatus: [Function: validateStatus],
headers: AxiosHeaders {
Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'axios/1.3.2',
'Content-Length': '313',
'Accept-Encoding': 'gzip, compress, deflate, br'
},
method: 'post',
url: 'https://oauth2.googleapis.com/token',
data: 'code=4%2F0AWtgzh5yCRs6xsZCCAEUhJGVTNE22-xpI9u3KaaCrgGl_wI618yJSGHUta53Z-w5VB7_Lw&client_id=252564275188-g55c2qnu6ajii45m3d154uuj9fnhlbfb.apps.googleusercontent.com&client_secret=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&redirect_uri=http%3A%2F%2Flocalhost%3A8000%2Fauth%2Fgoogle%2Fcallback&grant_type=authorization_code'
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype] {
abort: [Function (anonymous)],
aborted: [Function (anonymous)],
connect: [Function (anonymous)],
error: [Function (anonymous)],
socket: [Function (anonymous)],
timeout: [Function (anonymous)],
finish: [Function: requestOnFinish]
},
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: true,
_last: false,
chunkedEncoding: false,
shouldKeepAlive: true,
maxRequestsOnConnectionReached: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
strictContentLength: false,
_contentLength: '313',
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
_closed: true,
socket: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
secureConnecting: false,
_SNICallback: null,
servername: 'oauth2.googleapis.com',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 9,
connecting: false,
_hadError: false,
_parent: null,
_host: 'oauth2.googleapis.com',
_closeAfterHandlingError: false,
_readableState: [ReadableState],
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
timeout: 5000,
parser: null,
_httpMessage: null,
[Symbol(res)]: [TLSWrap],
[Symbol(verified)]: true,
[Symbol(pendingSession)]: null,
[Symbol(async_id_symbol)]: -1,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: [Timeout],
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kSetNoDelay)]: false,
[Symbol(kSetKeepAlive)]: true,
[Symbol(kSetKeepAliveInitialDelay)]: 1,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object]
},
_header: 'POST /token HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'Content-Type: application/x-www-form-urlencoded\r\n' +
'User-Agent: axios/1.3.2\r\n' +
'Content-Length: 313\r\n' +
'Accept-Encoding: gzip, compress, deflate, br\r\n' +
'Host: oauth2.googleapis.com\r\n' +
'Connection: keep-alive\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: nop],
agent: Agent {
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object: null prototype],
requests: [Object: null prototype] {},
sockets: [Object: null prototype] {},
freeSockets: [Object: null prototype],
keepAliveMsecs: 1000,
keepAlive: true,
maxSockets: Infinity,
maxFreeSockets: 256,
scheduling: 'lifo',
maxTotalSockets: Infinity,
totalSocketCount: 1,
maxCachedSessions: 100,
_sessionCache: [Object],
[Symbol(kCapture)]: false
},
socketPath: undefined,
method: 'POST',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: '/token',
_ended: true,
res: IncomingMessage {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 4,
_maxListeners: undefined,
socket: null,
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
rawHeaders: [Array],
rawTrailers: [],
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 400,
statusMessage: 'Bad Request',
client: [TLSSocket],
_consuming: true,
_dumped: false,
req: [Circular *1],
responseUrl: 'https://oauth2.googleapis.com/token',
redirects: [],
[Symbol(kCapture)]: false,
[Symbol(kHeaders)]: [Object],
[Symbol(kHeadersCount)]: 30,
[Symbol(kTrailers)]: null,
[Symbol(kTrailersCount)]: 0
},
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'oauth2.googleapis.com',
protocol: 'https:',
_redirectable: Writable {
_writableState: [WritableState],
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
_options: [Object],
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 313,
_requestBodyBuffers: [],
_onNativeResponse: [Function (anonymous)],
_currentRequest: [Circular *1],
_currentUrl: 'https://oauth2.googleapis.com/token',
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false,
[Symbol(kBytesWritten)]: 0,
[Symbol(kEndCalled)]: true,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] {
accept: [Array],
'content-type': [Array],
'user-agent': [Array],
'content-length': [Array],
'accept-encoding': [Array],
host: [Array]
},
[Symbol(errored)]: null,
[Symbol(kUniqueHeaders)]: null
},
response: {
status: 400,
statusText: 'Bad Request',
headers: AxiosHeaders {
date: 'Tue, 07 Feb 2023 12:04:34 GMT',
expires: 'Mon, 01 Jan 1990 00:00:00 GMT',
pragma: 'no-cache',
'cache-control': 'no-cache, no-store, max-age=0, must-revalidate',
'content-type': 'application/json; charset=utf-8',
vary: 'Origin, X-Origin, Referer',
server: 'scaffolding on HTTPServer2',
'x-xss-protection': '0',
'x-frame-options': 'SAMEORIGIN',
'x-content-type-options': 'nosniff',
'alt-svc': 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000',
'transfer-encoding': 'chunked'
},
config: {
transitional: [Object],
adapter: [Array],
transformRequest: [Array],
transformResponse: [Array],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
env: [Object],
validateStatus: [Function: validateStatus],
headers: [AxiosHeaders],
method: 'post',
url: 'https://oauth2.googleapis.com/token',
data: 'code=4%2F0AWtgzh5yCRs6xsZCCAEUhJGVTNE22-xpI9u3KaaCrgGl_wI618yJSGHUta53Z-w5VB7_Lw&client_id=252564275188-g55c2qnu6ajii45m3d154uuj9fnhlbfb.apps.googleusercontent.com&client_secret=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&redirect_uri=http%3A%2F%2Flocalhost%3A8000%2Fauth%2Fgoogle%2Fcallback&grant_type=authorization_code'
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: true,
_last: false,
chunkedEncoding: false,
shouldKeepAlive: true,
maxRequestsOnConnectionReached: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
strictContentLength: false,
_contentLength: '313',
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
_closed: true,
socket: [TLSSocket],
_header: 'POST /token HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'Content-Type: application/x-www-form-urlencoded\r\n' +
'User-Agent: axios/1.3.2\r\n' +
'Content-Length: 313\r\n' +
'Accept-Encoding: gzip, compress, deflate, br\r\n' +
'Host: oauth2.googleapis.com\r\n' +
'Connection: keep-alive\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: nop],
agent: [Agent],
socketPath: undefined,
method: 'POST',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: '/token',
_ended: true,
res: [IncomingMessage],
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'oauth2.googleapis.com',
protocol: 'https:',
_redirectable: [Writable],
[Symbol(kCapture)]: false,
[Symbol(kBytesWritten)]: 0,
[Symbol(kEndCalled)]: true,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype],
[Symbol(errored)]: null,
[Symbol(kUniqueHeaders)]: null
},
data: { error: 'invalid_grant', error_description: 'Bad Request' }
}
}
I checked few times that my env variables are correct. So I think this is problem with my code.
Maybe this is stupid question, but I really couldn't understand what I do incorrectly. What to do?
I am trying to use Marea Tide Api to build a tide application returning results based on location (latitude, longitude).
I was originally struggling to make a successful fetch from the front end due to a CORS error. I am now trying to build an express backend to both hide my api keys and navigate the CORS issue with a proxy.
I keep getting an unauthorized error when trying to navigate to localhost:8000/tides.
Express:
const PORT = 8000;
const express = require('express');
const cors = require('cors');
const axios = require('axios');
const { application, json } = require('express');
require('dotenv').config
const backend = express()
backend.listen(PORT, () => console.log(`Tide backend is working on PORT:${PORT}`))
backend.get('/tides', (req, res, next) => {
const url = 'https://api.marea.ooo/v2/tides';
const options = {
params: {
duration: 1440,
interval: 60,
latitude: 36.888,
longitude: -76.100,
}
};
const config = {
headers: {
'x-marea-api-token': process.env.MareaToken,
}
};
axios.get(url, options, config)
.then(response => {console.log(response)})
.catch(err => console.log(err))
});
Terminal Error:
[nodemon] starting `node backend.js`
Tide backend is working on PORT:8000
[AxiosError: Request failed with status code 401] {
code: 'ERR_BAD_REQUEST',
config: {
transitional: {
silentJSONParsing: true,
forcedJSONParsing: true,
clarifyTimeoutError: false
},
adapter: [Function: httpAdapter],
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
env: { FormData: [Function] },
validateStatus: [Function: validateStatus],
headers: {
Accept: 'application/json, text/plain, */*',
'User-Agent': 'axios/0.27.2'
},
params: {
duration: 1440,
interval: 60,
latitude: 36.888,
longitude: -76.1
},
method: 'get',
url: 'https://api.marea.ooo/v2/tides',
data: undefined
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype] {
abort: [Function (anonymous)],
aborted: [Function (anonymous)],
connect: [Function (anonymous)],
error: [Function (anonymous)],
socket: [Function (anonymous)],
timeout: [Function (anonymous)],
prefinish: [Function: requestOnPrefinish]
},
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
maxRequestsOnConnectionReached: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
_closed: false,
socket: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
secureConnecting: false,
_SNICallback: null,
servername: 'api.marea.ooo',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 10,
connecting: false,
_hadError: false,
_parent: null,
_host: 'api.marea.ooo',
_readableState: [ReadableState],
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular *1],
[Symbol(res)]: [TLSWrap],
[Symbol(verified)]: true,
[Symbol(pendingSession)]: null,
[Symbol(async_id_symbol)]: 17,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kSetNoDelay)]: false,
[Symbol(kSetKeepAlive)]: true,
[Symbol(kSetKeepAliveInitialDelay)]: 60,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object],
[Symbol(RequestTimeout)]: undefined
},
_header: 'GET /v2/tides?duration=1440&interval=60&latitude=36.888&longitude=-76.1 HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'User-Agent: axios/0.27.2\r\n' +
'Host: api.marea.ooo\r\n' +
'Connection: close\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: nop],
agent: Agent {
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object: null prototype],
requests: [Object: null prototype] {},
sockets: [Object: null prototype],
freeSockets: [Object: null prototype] {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
scheduling: 'lifo',
maxTotalSockets: Infinity,
totalSocketCount: 1,
maxCachedSessions: 100,
_sessionCache: [Object],
[Symbol(kCapture)]: false
},
socketPath: undefined,
method: 'GET',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: '/v2/tides?duration=1440&interval=60&latitude=36.888&longitude=-76.1',
_ended: true,
res: IncomingMessage {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 4,
_maxListeners: undefined,
socket: [TLSSocket],
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
rawHeaders: [Array],
rawTrailers: [],
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 401,
statusMessage: 'Unauthorized',
client: [TLSSocket],
_consuming: false,
_dumped: false,
req: [Circular *1],
responseUrl: 'https://api.marea.ooo/v2/tides?duration=1440&interval=60&latitude=36.888&longitude=-76.1',
redirects: [],
[Symbol(kCapture)]: false,
[Symbol(kHeaders)]: [Object],
[Symbol(kHeadersCount)]: 16,
[Symbol(kTrailers)]: null,
[Symbol(kTrailersCount)]: 0,
[Symbol(RequestTimeout)]: undefined
},
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'api.marea.ooo',
protocol: 'https:',
_redirectable: Writable {
_writableState: [WritableState],
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
_options: [Object],
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 0,
_requestBodyBuffers: [],
_onNativeResponse: [Function (anonymous)],
_currentRequest: [Circular *1],
_currentUrl: 'https://api.marea.ooo/v2/tides?duration=1440&interval=60&latitude=36.888&longitude=-76.1',
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] {
accept: [Array],
'user-agent': [Array],
host: [Array]
}
},
response: {
status: 401,
statusText: 'Unauthorized',
headers: {
'cache-control': 'max-age=0, private, must-revalidate',
'content-length': '40',
'content-type': 'application/json; charset=utf-8',
date: 'Tue, 19 Jul 2022 18:46:46 GMT',
server: 'Caddy',
'x-request-id': 'FwNPaorYW0wySfUApCrB',
connection: 'close'
},
config: {
transitional: [Object],
adapter: [Function: httpAdapter],
transformRequest: [Array],
transformResponse: [Array],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
env: [Object],
validateStatus: [Function: validateStatus],
headers: [Object],
params: [Object],
method: 'get',
url: 'https://api.marea.ooo/v2/tides',
data: undefined
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
maxRequestsOnConnectionReached: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
_closed: false,
socket: [TLSSocket],
_header: 'GET /v2/tides?duration=1440&interval=60&latitude=36.888&longitude=-76.1 HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'User-Agent: axios/0.27.2\r\n' +
'Host: api.marea.ooo\r\n' +
'Connection: close\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: nop],
agent: [Agent],
socketPath: undefined,
method: 'GET',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: '/v2/tides?duration=1440&interval=60&latitude=36.888&longitude=-76.1',
_ended: true,
res: [IncomingMessage],
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'api.marea.ooo',
protocol: 'https:',
_redirectable: [Writable],
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype]
},
data: { status: 401, error: 'Unauthorized' }
}
}
axios.get() accepts only two parameters...
axios.get(url[, config])
Combine your options and config objects and don't forget to send an actual response.
axios.get(url, { ...options, ...config })
.then(({ data }) => res.json(data))
.catch(next);
I have a site that is returning a server error 500 when requesting data from OpenAi api. I'm using the text-curie-001. I'm a newbie with this type of thing so I apologise in advance if I've got something totally wrong.
You can see in the console how the error shows: https://original-story-maker.vercel.app/
I'm using the free version of OpenAi if that makes any difference.
Here is the code that requests from api.
import { Configuration, OpenAIApi } from "openai";
const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);
export default async function (req, res) {
const completion = await openai.createCompletion("text-curie-001", {
// prompt: generatePrompt(req.body.animal),
prompt: "Write a story about " + req.body.employee + " wearing a " + req.body.wearing,
temperature: 0.9,
max_tokens: 720,
top_p: 1.0,
frequency_penalty: 0.0,
presence_penalty: 0.0
});
res.status(200).json({ result: completion.data.choices[0].text });
}
Vercel error log
: [WritableState],
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
_options: [Object],
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 142,
_requestBodyBuffers: [],
_onNativeResponse: [Function (anonymous)],
_currentRequest: [Circular *1],
_currentUrl: 'https://api.openai.com/v1/engines/text-curie-001/completions',
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] {
accept: [Array],
'content-type': [Array],
'user-agent': [Array],
authorization: [Array],
'content-length': [Array],
host: [Array]
}
},
response: {
status: 401,
statusText: 'Unauthorized',
headers: {
date: 'Tue, 21 Jun 2022 10:33:02 GMT',
'content-type': 'application/json; charset=utf-8',
'content-length': '280',
connection: 'close',
vary: 'Origin',
'x-request-id': '5534283309335fe6e2bf1c0ed0c68c1d',
'strict-transport-security': 'max-age=15724800; includeSubDomains'
},
config: {
transitional: [Object],
adapter: [Function: httpAdapter],
transformRequest: [Array],
transformResponse: [Array],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
validateStatus: [Function: validateStatus],
headers: [Object],
method: 'post',
data: '{"prompt":"Write a story about jack wearing a wallet","temperature":0.9,"max_tokens":720,"top_p":1,"frequency_penalty":0,"presence_penalty":0}',
url: 'https://api.openai.com/v1/engines/text-curie-001/completions'
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
maxRequestsOnConnectionReached: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: null,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
_closed: false,
socket: [TLSSocket],
_header: 'POST /v1/engines/text-curie-001/completions HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'Content-Type: application/json\r\n' +
'User-Agent: OpenAI/NodeJS/2.0.0\r\n' +
'Authorization: Bearer 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\r\n' +
'Content-Length: 142\r\n' +
'Host: api.openai.com\r\n' +
'Connection: close\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: nop],
agent: [Agent],
socketPath: undefined,
method: 'POST',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: '/v1/engines/text-curie-001/completions',
_ended: true,
res: [IncomingMessage],
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'api.openai.com',
protocol: 'https:',
_redirectable: [Writable],
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype]
},
data: { error: [Object] }
},
isAxiosError: true,
toJSON: [Function: toJSON]
}
END RequestId: 427a64bf-859c-4f86-b3ca-33e5017aa24d
REPORT RequestId: 427a64bf-859c-4f86-b3ca-33e5017aa24d Duration: 697.32 ms Billed Duration: 698 ms Memory Size: 1024 MB Max Memory Used: 45 MB
RequestId: 427a64bf-859c-4f86-b3ca-33e5017aa24d Error: Runtime exited with error: exit status 1
Runtime.ExitError
Here are screenshots from dev tools.
const headers = {
'Authorization': `Bearer ${api.oathToken.accessToken}`,
'Content-Type': 'application/json',
}
const body = {
subject: "No Subject",
note: "Please pay this within 10 days!",
}
console.log(invoiceDraft.links[1].href)
await axios({
data : body,
method: "post",
headers: headers,
url: invoiceDraft.links[1].href,
}).then((response) => {
console.log(response.data)
}).catch((err)=> {
console.log(err.response.data.details)
interaction.channel.send(err.toString().slice(0, 1900))
})
I have this code here to send a created invoice
But for some reason it returns this
Error: Request failed with status code 422
This is a UNPROCESSABLE_ENTITY error from Axios and Paypal Invoicing
Im not able to figure out what the issue is.
I am using Node JS and Discord integerations to do this.
Error: Request failed with status code 422
at createError (C:\Users\AriesAsAkshay\OneDrive\Documents\GitHub\AspectServices\node_modules\axios\lib\core\createError.js:16:15)
at settle (C:\Users\AriesAsAkshay\OneDrive\Documents\GitHub\AspectServices\node_modules\axios\lib\core\settle.js:17:12)
at IncomingMessage.handleStreamEnd (C:\Users\AriesAsAkshay\OneDrive\Documents\GitHub\AspectServices\node_modules\axios\lib\adapters\http.js:269:11)
at IncomingMessage.emit (node:events:402:35)
at endReadableNT (node:internal/streams/readable:1343:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
config: {
url: 'https://api.sandbox.paypal.com/v2/invoicing/invoices/INV2-4PSV-VKBJ-AK8G-P5CL/send',
method: 'post',
data: '{"subject":"No Subject","note":"Please pay this within 10 days!","send_to_invoicer":true,"send_to_recipient":true,"additional_recipients":[]}',
headers: {
Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/json',
Authorization: '',
'User-Agent': 'axios/0.21.4',
'Content-Length': 141
},
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
adapter: [Function: httpAdapter],
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
validateStatus: [Function: validateStatus],
transitional: {
silentJSONParsing: true,
forcedJSONParsing: true,
clarifyTimeoutError: false
}
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype] {
abort: [Function (anonymous)],
aborted: [Function (anonymous)],
connect: [Function (anonymous)],
error: [Function (anonymous)],
socket: [Function (anonymous)],
timeout: [Function (anonymous)],
prefinish: [Function: requestOnPrefinish]
},
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
maxRequestsOnConnectionReached: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: null,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
_closed: false,
socket: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
secureConnecting: false,
_SNICallback: null,
servername: 'api.sandbox.paypal.com',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 10,
connecting: false,
_hadError: false,
_parent: null,
_host: 'api.sandbox.paypal.com',
_readableState: [ReadableState],
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular *1],
[Symbol(res)]: [TLSWrap],
[Symbol(verified)]: true,
[Symbol(pendingSession)]: null,
[Symbol(async_id_symbol)]: 933,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(kSetNoDelay)]: false,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object],
[Symbol(RequestTimeout)]: undefined
},
_header: 'POST /v2/invoicing/invoices/INV2-4PSV-VKBJ-AK8G-P5CL/send HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'Content-Type: application/json\r\n' +
'Authorization: \r\n' +
'User-Agent: axios/0.21.4\r\n' +
'Content-Length: 141\r\n' +
'Host: api.sandbox.paypal.com\r\n' +
'Connection: close\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: nop],
agent: Agent {
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object: null prototype],
requests: [Object: null prototype] {},
sockets: [Object: null prototype],
freeSockets: [Object: null prototype] {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
scheduling: 'lifo',
maxTotalSockets: Infinity,
totalSocketCount: 1,
maxCachedSessions: 100,
_sessionCache: [Object],
[Symbol(kCapture)]: false
},
socketPath: undefined,
method: 'POST',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: '/v2/invoicing/invoices/INV2-4PSV-VKBJ-AK8G-P5CL/send',
_ended: true,
res: IncomingMessage {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
socket: [TLSSocket],
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
rawHeaders: [Array],
rawTrailers: [],
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 422,
statusMessage: 'Unprocessable Entity',
client: [TLSSocket],
_consuming: true,
_dumped: false,
req: [Circular *1],
responseUrl: 'https://api.sandbox.paypal.com/v2/invoicing/invoices/INV2-4PSV-VKBJ-AK8G-P5CL/send',
redirects: [],
[Symbol(kCapture)]: false,
[Symbol(kHeaders)]: [Object],
[Symbol(kHeadersCount)]: 18,
[Symbol(kTrailers)]: null,
[Symbol(kTrailersCount)]: 0,
[Symbol(RequestTimeout)]: undefined
},
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'api.sandbox.paypal.com',
protocol: 'https:',
_redirectable: Writable {
_writableState: [WritableState],
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_options: [Object],
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 141,
_requestBodyBuffers: [],
_onNativeResponse: [Function (anonymous)],
_currentRequest: [Circular *1],
_currentUrl: 'https://api.sandbox.paypal.com/v2/invoicing/invoices/INV2-4PSV-VKBJ-AK8G-P5CL/send',
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] {
accept: [Array],
'content-type': [Array],
authorization: [Array],
'user-agent': [Array],
'content-length': [Array],
host: [Array]
}
},
response: {
status: 422,
statusText: 'Unprocessable Entity',
headers: {
'content-type': 'application/json',
'content-length': '377',
connection: 'close',
date: 'Wed, 16 Mar 2022 01:35:50 GMT',
application_id: 'APP-80W284485P519543T',
'cache-control': 'max-age=0, no-cache, no-store, must-revalidate',
caller_acct_num: '7K54CC6QVVV78',
'paypal-debug-id': 'b5b17b1cdd466',
'strict-transport-security': 'max-age=31536000; includeSubDomains'
},
config: {
url: 'https://api.sandbox.paypal.com/v2/invoicing/invoices/INV2-4PSV-VKBJ-AK8G-P5CL/send',
method: 'post',
data: '{"subject":"No Subject","note":"Please pay this within 10 days!","send_to_invoicer":true,"send_to_recipient":true,"additional_recipients":[]}',
headers: [Object],
transformRequest: [Array],
transformResponse: [Array],
timeout: 0,
adapter: [Function: httpAdapter],
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
validateStatus: [Function: validateStatus],
transitional: [Object]
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
maxRequestsOnConnectionReached: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: null,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
_closed: false,
socket: [TLSSocket],
_header: 'POST /v2/invoicing/invoices/INV2-4PSV-VKBJ-AK8G-P5CL/send HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'Content-Type: application/json\r\n' +
'Authorization: \r\n' +
'User-Agent: axios/0.21.4\r\n' +
'Content-Length: 141\r\n' +
'Host: api.sandbox.paypal.com\r\n' +
'Connection: close\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: nop],
agent: [Agent],
socketPath: undefined,
method: 'POST',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: '/v2/invoicing/invoices/INV2-4PSV-VKBJ-AK8G-P5CL/send',
_ended: true,
res: [IncomingMessage],
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'api.sandbox.paypal.com',
protocol: 'https:',
_redirectable: [Writable],
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype]
},
data: {
name: 'UNPROCESSABLE_ENTITY',
message: 'The requested action could not be performed, semantically incorrect, or failed business validation.',
debug_id: 'b5b17b1cdd466',
details: [Array],
links: [Array]
}
},
isAxiosError: true,
toJSON: [Function: toJSON]
}
Error Response Details
[
{
issue: 'USER_NOT_FOUND',
description: 'User is not associated with paypal based on invoicer email.'
}
]
const sampleInvoice = (
invoiceNumber,
fromEmail = "sb-pbqgq14333806#business.example.com",
toEmail = "sb-47vx64314481641#personal.example.com"
) => ({
detail: {
invoice_number: invoiceNumber,
currency_code: "USD",
payment_term: { term_type: "NET_10" },
invoice_date: new Date().toISOString().split("T")[0],
},
invoicer: {
name: {
given_name: "John",
surname: "Doe",
},
email_address: fromEmail,
website: "https://www.aspecthosts.com/",
},
primary_recipients: [
{
billing_info: {
name: {
given_name: "John",
surname: "Doe",
},
email_address: toEmail,
},
},
],
items: [
{
name: service,
description: "Hello!",
quantity: "1",
unit_amount: {
currency_code: "USD",
value: amount,
},
unit_of_measure: "QUANTITY",
},
],
});
Most likely there's a problem with the invoice draft's original creation. Show that invoice creation request/response bodies in their entirety. In particular, what is the sandbox email of the invoicer account ? Does it correspond to an actual www.sandbox.paypal.com PayPal business account that you can log into? If not, create it with the correct email via the developer dashboard -> sandbox accounts.
I generate an access token using 'simple-oauth2' that looks like this
import { AuthorizationCode } from 'simple-oauth2';
scopes = ['offline_access', 'https://outlook.office.com/IMAP.AccessAsUser.All',
'https://outlook.office.com/SMTP.Send','User.Read'];
async getCredentials(code: string) {
const client = new AuthorizationCode(this.oauthConfig);
let tokenParams = {
code,
redirect_uri: config.MICROSOFT_CREDENTIALS.REDIRECT_URIS[0],
scope: this.scopes.join(' ')
}
return await client.getToken(tokenParams)
};
// Result from getCredentials
AccessToken {
token: {
token_type: 'Bearer',
scope: 'https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/SMTP.Send https://outlook.office.com/User.Read',
expires_in: 3599,
ext_expires_in: 3599,
access_token: 'eyJ0eXAiOiJKV1QiLCJub25jZSI6I...',
refresh_token: '0.ATUAd-LjmxfEgkWp0wIFCKwhpRA-z-...',
expires_at: 2020-09-25T01:13:08.970Z
}
}
Following this guide, I then pass the access_token field to a GET request to https://graph.microsoft.com/v1.0/me
getUserProfile(accessToken: string) {
return axios.get("https://graph.microsoft.com/v1.0/me", {
headers: {
Authorization: 'Bearer ' + accessToken,
'Content-Type': 'application/json'
}
})
.then((res) => {
return res.data;
})
.catch((reason) => {
console.log("getUserProfile failed");
console.log(reason);
})
};
This fails with the following error
getUserProfile failed
Error: Request failed with status code 401
at createError (C:\Users\me\Desktop\projects\proj\node_modules\axios\lib\core\createError.js:16:15)
at settle (C:\Users\me\Desktop\projects\proj\node_modules\axios\lib\core\settle.js:17:12)
at IncomingMessage.handleStreamEnd (C:\Users\me\Desktop\projects\proj\node_modules\axios\lib\adapters\http.js:236:11)
at IncomingMessage.emit (events.js:323:22)
at IncomingMessage.EventEmitter.emit (domain.js:482:12)
at endReadableNT (_stream_readable.js:1204:12)
at processTicksAndRejections (internal/process/task_queues.js:84:21) {
config: {
url: 'https://graph.microsoft.com/v1.0/me',
method: 'get',
headers: {
Accept: 'application/json, text/plain, */*',
Authorization: 'Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6IjByZ0t3MFRLOEF...',
'Content-Type': 'application/json',
'User-Agent': 'axios/0.19.2'
},
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
adapter: [Function: httpAdapter],
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
data: undefined
},
request: ClientRequest {
_events: [Object: null prototype] {
socket: [Function],
abort: [Function],
aborted: [Function],
error: [Function],
timeout: [Function],
prefinish: [Function: requestOnPrefinish]
},
_eventsCount: 6,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: 'graph.microsoft.com',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 9,
connecting: false,
_hadError: false,
_parent: null,
_host: 'graph.microsoft.com',
_readableState: [ReadableState],
readable: true,
_maxListeners: undefined,
_writableState: [WritableState],
writable: false,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular],
[Symbol(res)]: [TLSWrap],
[Symbol(asyncId)]: 1233,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object]
},
connection: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: 'graph.microsoft.com',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 9,
connecting: false,
_hadError: false,
_parent: null,
_host: 'graph.microsoft.com',
_readableState: [ReadableState],
readable: true,
_maxListeners: undefined,
_writableState: [WritableState],
writable: false,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular],
[Symbol(res)]: [TLSWrap],
[Symbol(asyncId)]: 1233,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object]
},
_header: 'GET /v1.0/me HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6IjByZ0t...\r\n' +
'Content-Type: application/json\r\n' +
'User-Agent: axios/0.19.2\r\n' +
'Host: graph.microsoft.com\r\n' +
'Connection: close\r\n' +
'\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: Agent {
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object],
requests: {},
sockets: [Object],
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: [Object],
[Symbol(kCapture)]: false
},
socketPath: undefined,
method: 'GET',
insecureHTTPParser: undefined,
path: '/v1.0/me',
_ended: true,
res: IncomingMessage {
_readableState: [ReadableState],
readable: false,
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
socket: [TLSSocket],
connection: [TLSSocket],
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
headers: [Object],
rawHeaders: [Array],
trailers: {},
rawTrailers: [],
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 401,
statusMessage: 'Unauthorized',
client: [TLSSocket],
_consuming: false,
_dumped: false,
req: [Circular],
responseUrl: 'https://graph.microsoft.com/v1.0/me',
redirects: [],
[Symbol(kCapture)]: false
},
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
_redirectable: Writable {
_writableState: [WritableState],
writable: true,
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_options: [Object],
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 0,
_requestBodyBuffers: [],
_onNativeResponse: [Function],
_currentRequest: [Circular],
_currentUrl: 'https://graph.microsoft.com/v1.0/me',
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] {
accept: [Array],
authorization: [Array],
'content-type': [Array],
'user-agent': [Array],
host: [Array]
}
},
response: {
status: 401,
statusText: 'Unauthorized',
headers: {
'cache-control': 'private',
'content-type': 'application/json',
'request-id': '6026815f-6c31-48c3-9b70-a6eb3cda8e44',
'client-request-id': '6026815f-6c31-48c3-9b70-a6eb3cda8e44',
'x-ms-ags-diagnostic': '{"ServerInfo":{"DataCenter":"West US","Slice":"SliceC","Ring":"5","ScaleUnit":"002","RoleInstance":"AGSFE_IN_13"}}',
'www-authenticate': 'Bearer realm="", authorization_uri="https://login.microsoftonline.com/common/oauth2/authorize", client_id="00000003-0000-0000-c000-000000000000"',
'strict-transport-security': 'max-age=31536000',
date: 'Fri, 25 Sep 2020 00:13:11 GMT',
connection: 'close',
'content-length': '330'
},
config: {
url: 'https://graph.microsoft.com/v1.0/me',
method: 'get',
headers: [Object],
transformRequest: [Array],
transformResponse: [Array],
timeout: 0,
adapter: [Function: httpAdapter],
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
data: undefined
},
request: ClientRequest {
_events: [Object: null prototype],
_eventsCount: 6,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [TLSSocket],
connection: [TLSSocket],
_header: 'GET /v1.0/me HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6IjByZ0...\r\n' +
'Content-Type: application/json\r\n' +
'User-Agent: axios/0.19.2\r\n' +
'Host: graph.microsoft.com\r\n' +
'Connection: close\r\n' +
'\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: [Agent],
socketPath: undefined,
method: 'GET',
insecureHTTPParser: undefined,
path: '/v1.0/me',
_ended: true,
res: [IncomingMessage],
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
_redirectable: [Writable],
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype]
},
data: { error: [Object] }
},
isAxiosError: true,
toJSON: [Function]
Documentation for /me and the guide states I just need User.Read for my permissions and that my headers are correct so I do not know why it is failing. The Microsoft account I am using for testing is a Work Account.
I have briefly tried using the Graph SDK but I feel like this approach is 99% of the way there.
Big picture wise I am trying to save the user's email address so I can use the OAuth2 token to connect to O365 through IMAP and SMTP. If I hardcode what I know the email address to be everything works so automating the retrieval of the user's email address through Graphs is the last thing I need.
You should not use a token that does not belong to the api. You are calling the Microsoft graph api, but you are requesting a token for Outlook, so you only need to change the scope to:
scopes = ['offline_access', 'https://graph.microsoft.com/.default'];
Another method is keeping your current scopes and call GET https://outlook.office365.com/api/v2.0/me/ to get the signed-in user's information.