I've got a problem with google api in NodeJS with hapi. I downloaded files with npm install googleapis and google-auth-library. Everything is setup correctly.
function listData(auth) {
let webmasters = google.webmasters('v3');
webmasters.searchanalytics.query({
auth: auth,
siteUrl: 'http%3A%2F%2Falanmroczek.pl%2F',
startDate: "2016-09-20",
endDate: "2016-10-14"
}, function(err, response) {
if (err) {
console.log('The API returned an error: ' + err);
return;
}
console.log(response);
});
}
I'm authorised to that scope by this app (if not it throws an error, so I'm sure that this part is okey). When I done listing my gmail folders it works perfectly. Wrong may be only this part of code or googleapis. Strange for me is that:
When I console.log request to Google API:
protocol: 'https:',
slashes: true,
auth: null,
host: 'www.googleapis.com',
port: null,
hostname: 'www.googleapis.com',
hash: null,
search: '?startDate=2016-09-20&endDate=2016-10-14',
query: 'startDate=2016-09-20&endDate=2016-10-14',
pathname: '/webmasters/v3/sites/http%3A%2F%2Falanmroczek.pl%2F/searchAnalytics/query',
path: '/webmasters/v3/sites/http%3A%2F%2Falanmroczek.pl%2F/searchAnalytics/query?startDate=2016-09-20&endDate=2016-10-14',
href: 'https://www.googleapis.com/webmasters/v3/sites/http%3A%2F%2Falanmroczek.pl%2F/searchAnalytics/query?startDate=2016-09-20&endDate=2016-10-14' },
Query, path and href looks like normal GET, I have no idea why. I tried to override it but still I get "backend error".
EDIT: Gmail list folders via GET, thats why I pointed out POST.
It's probably issue with googleapis for node.js. It's sending data via GET not required POST and JSON. We have to do it manually.
Backend Errors which are being returned from Google API calls will have 503 as its error code which means "Service Unavailable".
Check the various API's and its status here and ensure the service that you are trying to hit is up and running fine.
https://www.google.com/appsstatus#hl=en&v=status
Hope this helps!
i work on the similar code. This Reference helped me.
Just have a look: NodeJS & Goodgle Express API
Related
I am attempting to send an email using Nodemailer and Twilio Sendgrid, following the tutorial here. As far as I can tell I am following the instructions in the tutorial, as well as theNodemailer and Sendgrid documentation. Every time this method is called, the code in the catch block executes, and I get the error Error: Missing credentials for "PLAIN".
My question was closed due to association with the question here, however my problem is different and none of the solutions on the thread apply. I am using my own domain to send, not gmail.com. I want to solve the problem without using Oauth2, which from what I understand I should not need, given that I am using an email domain I control. Also I am already using pass' rather than 'password for my authorization data (the top solution on the associated answer).
I've been stuck on this for a few days now , and I'd appreciate any insight anyone can offer!
Here is my code:
async function sendEmail(email, code) {
try{
const smtpEndpoint = "smtp.sendgrid.net";
const port = 465;
const senderAddress = 'Name "contact#mydomain.com"';
const toAddress = email;
const smtpUsername = "apikey";
const smtpPassword = process.env.SG_APIKEY;
const subject = "Verify your email";
var body_html = `<!DOCTYPE>
<html>
<body>
<p>Your authentication code is : </p> <b>${code}</b>
</body>
</html>`;
let transporter = nodemailer.createTransport({
host: smtpEndpoint,
port: port,
secure: true,
auth: {
user: smtpUsername,
pass: smtpPassword,
},
logger: true,
debug: true,
});
let mailOptions = {
from: senderAddress,
to: toAddress,
subject: subject,
html: body_html,
};
let info = await transporter.sendMail(mailOptions);
return { error: false };
} catch (error) {
console.error("send-email-error", error);
return {
error: true,
message: "Cannot send email",
};
}
}
And here is the log:
Thanks!
You have already identified the issue of API key not being passed into the Nodemailer transport. While hardcoding the key is a possible solution, it's not a good practice. Usually secrets and keys are managed via environment variables so they are, for example, not accidentally committed to a repository and can be configured externally without changing the code.
In the tutorial you linked, working with the environment variable is addressed, but I see there is a mistake with .env file. So let me try to recap how to properly get SG_APIKEY from environment variable and .env file.
In your project directory create the .env file with the following contents:
SG_APIKEY=<your_sendgrid_api_key>
(obviously replace <your_sendgrid_api_key> with your actual API key)
Make sure dotenv package is installed: npm i dotenv
At the beginning of the file where you use Nodemailer, add the following line:
require("dotenv").config();
This will ensure the SG_APIKEY is loaded from .env file.
You can check if the env variable is set correctly with console.log(process.env.SG_APIKEY)
A comment on the (closed) previous version of this thread solved the problem for me:
Description:
I have a frontend React client that is hosted on Firebase Hosting and a NodeJS Express API that is hosted on Google App Engine. The client needs to send a POST request to a NodeJS Express route, the request need to contain a variable called formid that holds the name of a firebase document. When both the server and client is run locally the formid variable gets sent to the API and it is not empty or undefined. But when the API is deployed and the request is sent to GAE instead I get this error:
UnhandledPromiseRejectionWarning: Error: Value for argument "documentPath" is not a valid resource path. Path must be a non-empty string.
The error appears in the Google Cloud Platform Console. In left hand menu I go to; Operations > Logging > Logs Viewer. But I can also tail the logs to my local console with the command "gcloud app logs tail -s default".
Question: Why does the error appear only when the request is sent to GAE and not when I run them locally?
request.headers.form_id contains the name of the document stored in a collection (which is an autoID) in Google Firestore.
async function postFormQuestionHandler(request, response) {
let form_ref = db.collection("forms").doc(request.headers.form_id);
... other code
Express router that recieves the request, forwards it to postFormQuestionHandler function.
router.post("/question", (req, res) => {
postFormQuestionHandler(req, res);
});
Here is where the request firstly is being sent:
async addQuestionsToFormDb(idToken, fomrid, questionids) {
let result = await questionids.map(async (questionid) => {
let data = {
idToken: idToken,
form_id: formid,
question_id: questionid,
};
return await fetch(`${process.env.REACT_APP_API}/form/question`, {
method: 'POST',
mode: 'cors',
headers: data
});
}
From above code I have also tried using the Axios library but it also produces the same error on when the API is deployed to GAE. I have tried reading the documentation of both Axios (Github Axios Documentation) and Fetch (Firefox MDN web docs) but it have not helped me, am I missunderstanding something? Below is what I tried with Axios:
return await axios.post(`${process.env.REACT_APP_API}/form/question`, {}, {
headers: data,
}
);
Other information
Im using Express v4.17.1 and Node v10.19.0, I am also developing this with WSL 2 on Windows 10 2004.
your request.headers.form_id is either empty string or contain invalid character. I guess it contains slash /. Here is more info https://firebase.google.com/docs/firestore/quotas#collections_documents_and_fields
I have been working on a simple production management process based around smartsheet. The code that I have been running has been working fine on my Ubuntu machine, then I copied it over to my Parrot Linux machine running the same node version and it won't find a row that exists. Below is the request:
var copyRow = {
"rowIds": artToProdRowsToCopy,
"to": {
"sheetId": productionId
}
};
// Set options
var options = {
sheetId: artId,
body: copyRow,
queryParameters: {
include: "all"
}
};
console.log(options);
// Copy the normal engraved rows from art to production
smartsheet.sheets.copyRowToAnotherSheet(options)
.then(function(results) {
callback1(null, results);
})
.catch(function(error) {
console.log(error);
});
The log output of options:
{ sheetId: 8129017524546436,
body:
{ rowIds: [ 8886954296800644 ],
to: { sheetId: 6941481487333252 } },
queryParameters: { include: 'all' } }
The error:
{ statusCode: 404,
errorCode: 1006,
message: 'Not Found',
refId: 'zjl2z56296l9' }
I'm running node v8.9.1, on Parrot Linux 3.9.
I've checked that each of these sheet and row ID #'s are correct and they all are (the ones in the examples are not real however). Any help would be appreciated.
Edit: Adding debug info:
[Smartsheet] 2017-11-20T20:22:55.876Z[ INFO] POST https://api.smartsheet.com/2.0/sheets/8129017124546436/rows//copy?include=all
[Smartsheet] 2017-11-20T20:22:55.876Z[VERBOSE] Request Payload (preview): {"rowIds":[2759271070885764,3212501789763460,4576920289470340,8982631438149508,2962733838690180,8886959296800644],"to":{"sheetId":6941441487333252}}
[Smartsheet] 2017-11-20T20:22:55.876Z[ DEBUG] Request Payload (full): {"rowIds":[2759271070885764,3212501789763460,4576920289470340,8982631438149508,2962733838690180,8886959296800644],"to":{"sheetId":6941441487333252}}
[Smartsheet] 2017-11-20T20:22:56.155Z[ ERROR] Request failed after 0 retries
[Smartsheet] 2017-11-20T20:22:56.156Z[ ERROR] POST https://api.smartsheet.com/2.0/sheets/8129017124546436/rows//copy?include=all
[Smartsheet] 2017-11-20T20:22:56.156Z[ ERROR] Response: Failure (HTTP 404)
Error Code: 1006 - Not Found
Ref ID: 85bn0m2j8oki
I don't see any obvious issues with your request structure. Typically, the 404 Not Found error is related to an issue with the request URI, rather than the contents of the request itself. i.e., a 404 Not Found error means that, for some reason or another, the request URI is not reachable.
The URI for the Copy Row(s) request is:
POST /sheets/{sheetId}/rows/copy
A few troubleshooting suggestions:
Verify that the casing of all characters in the request URI are lowercase.
Verify that the sheet corresponding to the sheetId value in the request URI exists.
Verify that the user who owns the API Access token that you're specifying in the Authorization header of the Copy Row(s) API request does indeed have access to the sheet corresponding to the sheetId value in the request URI.
As described in the Troubleshooting section of the API docs, I'd suggest that you use a tool like Fiddler or Charles HTTP Proxy to examine the raw HTTP request that your app is sending, then you can investigate/verify the items I've listed above.
Update #1
Thanks for updating your post with debugging info. Based on that, it looks like your request URI contains an extra slash between the words rows and copy:
POST https://api.smartsheet.com/2.0/sheets/8129017124546436/rows//copy?include=all
Perhaps this is causing your problem?
Update #2
I've been able to reproduce the Not Found error in Postman if my Request URI contains two slashes between the words rows and copy(like your debug output shows). Removing one of these slashes fixes the issue. That is, your request should look like this (only one slash between the words rows and copy).
POST https://api.smartsheet.com/2.0/sheets/8129017124546436/rows/copy?include=all
Looks like our SDK bug. Stay tuned for a fix.
Fixed in version 1.0.3 - now on Github and npm.
https://www.npmjs.com/package/smartsheet
https://github.com/smartsheet-platform/smartsheet-javascript-sdk/releases/tag/v1.0.3
I've calling a windows REST service which requires NTLM. When I call the service using a utility like SOAP-UI and supply my credentials for NTLM authorization it works fine, I get a result. when I use httpnltm (https://www.npmjs.org/package/httpntlm) to accomplish this from node.js I always get a 401 error, with the following message: "You do not have permission to view this directory or page.". The get options set are exactly the same used in SOAP-UI and it works there.
httpntlm.get({
url: 'endpoint',
username: 'my_username',
password: 'my_password',
domain: 'my_domain'
}, function (err, res){
if(err){
callback(err.message, null);
}else{
if(res.statusCode == 401){
// always the case!
}
}
});
Is there something I am missing from this get request?
I'm writing some node code to do a server side login to Facebook. I'm pretty close to having it completely functioning, but I am having troubles requesting the auth_code.
I'm thinking it might have something to do with the facebook app setting Site URL but nothing I've tried has worked.
I'm using node version 0.8.14.
Here is the code I do my request in:
options =
host: 'graph.facebook.com'
port: 443
path: "/oauth/access_token?" + qs.stringify(
client_id: app_id
redirect_uri: my_url
client_secret: app_secret
code: vars.code)
https.get(options, (face_res)->
console.log face_res
)
In the face_res I get a couple of objects like this:
authorizationError: 'Hostname/IP doesn\'t match certificate\'s altnames'
Any help is greatly appreciated
Ok funny thing is the error I was getting was completely irrelevant. As soon as I added a request.on("data", function(data){}) event listener I was able to see that I was receiving the auth_token as expected.