I'm creating a contact form using Nextjs and SendGrid, according to this header status
202
{
server: 'nginx',
date: 'Thu, 08 Dec 2022 16:29:25 GMT',
'content-length': '0',
connection: 'close',
'x-message-id': 'CaVdpVAURza6JrUF7yIQQA',
'access-control-allow-origin': 'https://sendgrid.api-docs.io',
'access-control-allow-methods': 'POST',
'access-control-allow-headers': 'Authorization, Content-Type, On-behalf-
of, x-sg-elas-acl',
'access-control-max-age': '600',
'x-no-cors-reason':
'https://sendgrid.com/docs/Classroom/Basics/API/cors.html',
'strict-transport-security': 'max-age=600; includeSubDomains'
}
the email is sent but I find nothing in my inbox,
and this error occurs in the terminal
API resolved without sending a response for /api/contact, this may result in stalled requests.
I don't know what mistake I've done but. I invite you to look at my code bellow:
API :
import sgMail from "#sendgrid/mail";
export default function handler(req, res) {
if (req.method !== "POST") {
res.status(405).json({ message: "INVALID_METHOD" });
return;
}
// Variables from the client side
var name = req.body.name;
var email= req.body.email;
var subject= req.body.subject;
var content = req.body.content;
// auto line break message
const message = content
.replace(/\n/g, "<br>")
.replace(/\r/g, "<br>")
.replace(/\t/g, "<br>")
.replace(/<(?!br\s*\/?)[^>]+>/g, "");
// giving the api key API
sgMail.setApiKey(process.env.KEY_SENDGRID);
// Creating message
const sendGridMail = {
to: "arotiana4612#gmail.com",
from: "kaspersky2mahanaima#gmail.com",
subject: subject,
templateId: "d-b48909edf062437e8442f861a4c8be29",
dynamic_template_data: {
name: name,
email: email,
subject: subject,
content: message,
},
};
// SENDING MESSAGE VIA SENDGRID
(async () => {
try {
await sgMail.send(sendGridMail)
.then((response) => {
console.log(response[0].statusCode)
console.log(response[0].headers)
})
.catch((error) => {
console.error(error)
})
} catch (err){
console.error(err);
res.status(500).json({
error:JSON.stringify(err),
message: "ERROR_WITH_SENDGRID",
});
}
})();
}
And this is the method from the client side that from which I get the data:
const onSubmit: SubmitHandler<Inputs> = async (formData) => {
if (!isLoading) {
setIsLoading(true);
const response = await fetch("/api/contact", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(formData),
});
const result = await response.json();
setIsLoading(false);
if (!response.ok) {
console.log("error sending email:",result);
} else {
console.log("ok");
}
return result;
}
};
I want to receive the mail in my inbox. Your help would be very appreciated, I'm strugling
Related
I have a nuxt project deployed on Netlify and now I want to add a newsletter (add a subscriber to my audience on Mailchimp). To achieve that, I've opted to use the AWS serverless lambda functions. To be honest, it's the first time that i've heard about serverless functions. I found this tutorial https://hashinteractive.com/blog/nuxt-js-mailchimp-integration-add-contact-to-list/ and at the end, i've decided to make a test on Postman. I've made a post to http://localhost:8888/.netlify/functions/subscribe and it worked. But when I try the same thing with axios I get the error 405 (method not allowed).
Newsletter.vue
<form #submit.prevent='submitNewsletter' class="newsletter__form" >
<input type="email" placeholder="E-mail" class="newsletter__form-input" v-model="email">
<button class="newsletter__form-button" type="submit">Subscribe</button>
</form>
</div>
</template>
<script>
import axios from 'axios';
export default {
data(){
return{
email: ''
}
},
methods:{
submitNewsletter(){
axios.post('http://localhost:8888/.netlify/functions/subscribe', { email: this.email}, {
headers: {
methods: 'POST',
'Content-Type':'application/json'
}
})
.then(function (response) {
console.log(response);
}).
catch((error) =>{
console.log('The error:' + error)
})
this.$toasted.success("Thank you for your subscription !!!", {
theme: "toasted-primary",
position: "top-left",
containerClass: 'myContainer',
fitToScreen: true,
fullWidth: true,
duration : 5000
});
}
}
}
</script>
functions > subscribe > subscribe.js
const fetch = require('node-fetch');
const base64 = require('base-64');
exports.handler = async (event, context) => {
// Only allow POST
if (event.httpMethod !== 'POST') {
return { statusCode: 405, body: 'Method Not Allowed' };
}
const errorGen = msg => {
return { statusCode: 500, body: msg };
};
try {
const { email } = JSON.parse(event.body);
console.log(email);
if (!email) {
return errorGen('Missing Email');
}
const subscriber = {
email_address: email,
status: 'subscribed',
};
console.log(subscriber);
console.log(JSON.stringify(subscriber));
const creds = `blooming-thoughts:${process.env.MAILCHIMPS_API_KEY}`;
const response = await fetch(`https://us20.api.mailchimp.com/3.0/lists/${process.env.AUDIENCE_ID}/members/`, {
method: 'POST',
headers: {
Accept: '*/*',
'Content-Type': 'application/json',
Authorization: `Basic ${base64.encode(creds)}`, },
body: JSON.stringify(subscriber),
});
const data = await response.json();
if (!response.ok) {
// NOT res.status >= 200 && res.status < 300
return { statusCode: data.status, body: data.detail };
}
return {
statusCode: 200,
body: JSON.stringify({ msg: "You've signed up to the mailing list!", detail: data, }),
};
} catch (err) {
console.log(err); // output to netlify function log
return {
statusCode: 500,
body: JSON.stringify({ msg: err.message }),
};
}
};
My netlify.toml
[build]
publish = "dist"
functions = 'functions'
I've made a push to my repository and netlify built without any error, but when I try to add a newsletter from my site nothing happens.
I've solved my problem. If you're having trouble like I was, follow these steps:
Create a folder called functions in your root directory, then create a index.js (the file name is up to you).
Create a file called netlify.toml and add the following code :
[build]
functions = "functions"
Then, inside your index.js goes the code that will communicate with your API
On the vue component, make a post request to the <your-site>/.netlify/functions/index . You can find the endpoint going to functions on netlify dashbord.
Don't forget to register your env variables on Netlify (Build & Deploy) and that's it.
I have a simple app with two routes, which I use locally and on IBM Cloud/Cloud Foundry (512 M RAM)
/
returns "Hello World!" & 200 locally and on the IBM Cloud
/getData
returns some data locally & 200
on cloud it returns 400, no logs
Edit:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
var cors = require("cors"); // Cors
app.use(cors());
var port = process.env.PORT || 3000;
app.get('/', (req, res) => res.send('Hello World!'))
// *************** GETDATA ***************************************
app.get('/getData', function (req, res) {
var request = require("request");
var httpHeaderOptions = {
accept: "application/json",
"content-type": "application/json",
apikey: req.headers.apikey
};
var restoptions = {
method: "GET",
url: req.headers.route,
headers: httpHeaderOptions
};
// console.log("headers: " + JSON.stringify(req.headers));
// console.log("GET DOCS: \n", JSON.stringify(restoptions));
request(restoptions, function (error, response, body) {
console.log(typeof (body));
body_json = JSON.parse(body);
if (error) {
console.error("Failed: %s", error.message);
body = {
"error": error.message
};
res.status(400).json(body);
} else {
console.log("Success: \n", body);
res.status(200).json(body_json);
}
});
});
// *************** POST DOC ***************************************
app.post('/postData', function (req, res) {
var request = require("request");
var httpHeaderOptions = {
accept: "application/json",
"content-type": "application/json",
apikey: req.headers.apikey
};
var restoptions = {
method: "POST",
url: req.headers.route,
headers: httpHeaderOptions,
body: req.body,
json: true
};
console.log("headers: " + JSON.stringify(req.headers));
console.log("POST DOC: \n", JSON.stringify(restoptions));
request(restoptions, function (error, response, body) {
if (typeof (body) == 'object' && Object.keys(body).length === 0) {
// unknown error, empty resposne
res.status(400).json(body);
} else {
console.log("body: " + JSON.stringify(body));
if (error) {
console.error("Failed: %s", error.message);
body = {
"error": error.message
};
res.status(400).json(body);
} else {
console.log("Success: \n", JSON.stringify(body));
res.status(200).json(body);
}
}
});
});
// *********************
app.post('/watsonAssistant', function (req, res) {
var request = require("request");
var reqURL = "https://hackathon-jps.eu-de.mybluemix.net/watsonAssistant";
console.log("URL: \n", reqURL);
console.log("POST Body: \n", JSON.stringify(req.body));
var httpHeaderOptions = {
accept: "application/json",
"content-type": "application/json",
};
var restoptions = {
method: "POST",
url: reqURL,
headers: httpHeaderOptions,
body: req.body,
json: true
};
console.log("send request \n");
request(restoptions, function (error, response, body) {
console.log("in request \n");
if (error) {
console.error("Failed: %s", error.message);
body = {
"error": error.message
};
res.status(400).json(body);
} else {
console.log("Success: \n", body[0]);
res.status(200).json(body[0]);
}
});
});
// Start the server
app.listen(port, function () {
console.log('simple forward server is running')
});
link to the code
This will be because whatever req.headers.route is set to, is not visible to the app when it is running in the cloud. Your first check should be on error. Your second check should be if body is not null, and an object instead you immediately JSON.parse body, which may be throwing a parsing exception.
I am trying to do http post in protractor. The status of http.post sits in pending status and doesn't return any response.
I am calling a method in onPrepare function under specDone:
jasmine.getEnv().addReporter({
specDone: function(result) {
if (result.status == "failed") {
browser.getCapabilities().then(function(caps) {
var browserName = caps.get("browserName");
browser.takeScreenshot().then(function(png) {
var stream = fs.createWriteStream(
"./reports/screenshots/" +
browserName +
"-" +
result.fullName +
".png"
);
stream.write(new Buffer(png, "base64"));
stream.end();
});
});
}
new PortalData().PushDataToPortal("");
}
});
Below function in called from onPrepare, the API takes the parameter from body. I am using protractor-http-client package for API calls.
export class PortalData {
public PushDataToPortal(result) {
const http: HttpClient = new HttpClient();
const LogFilePathInSharedLocation =
"\\\\10.101.101.11\\temp\\DocStar\\Automation\\TestLogs\\Logs.txt";
http
.post(
someurl,
LogFilePathInSharedLocation,
{ "Content-Type": "application/x-www-form-urlencoded" }
)
.then((response: ResponsePromise) => {
console.log(response);
});
}
Please advise. Thanks!
I would suggest you use Http call in beforeAll instead of onPrepare.
You can try superagent or supertest npm modules:
Example for superagent
const superagent = require('superagent');
// callback
superagent
.post('/api/pet')
.send({ name: 'Manny', species: 'cat' }) // sends a JSON post body
.set('X-API-Key', 'foobar')
.set('accept', 'json')
.end((err, res) => {
// Calling the end function will send the request
});
// promise with then/catch
superagent.post('/api/pet').then(console.log).catch(console.error);
// promise with async/await
(async () => {
try {
const res = await superagent.post('/api/pet');
console.log(res);
} catch (err) {
console.error(err);
}
})();
Example for supertest
const supertest = require('supertest');
const request = supertest(`${baseURL}`);
request.put('/test/sendlocal')
.send(profileAddressData.createData)
.set('Content-Type', 'application/json')
.set('Accept', '*/*')
.expect(200)
.end((err, res) => {
if (err) {
console.error('Error: ', err);
console.error('Response: ', res);
}
});
The below response is returned upon calling the signup function
Response {_body: "string(85) "{"message":"A customer with the same email
already exists in an associated website."}"↵", status: 200, ok: true,
statusText: "OK", headers: Headers, …}
headers: Headers {_headers: Map(1), _normalizedNames: Map(1)}
ok: true
status: 200
statusText: "OK"
type: 2
url: "http://127.0.0.1/sandbox/M2API/signup/signup"
_body: "string(85) "{"message":"A customer with the same email already exists in an associated website."}"↵"
__proto__: Body
Signup Function:
signup() {
this.authServiceProvider.postData(this.userData, "signup").then((result) => {
this.responseData = result;
console.log(this.responseData);
if( (JSON.stringify(this.responseData._body)) != "" ) {
this.navCtrl.setRoot(HomePage);
} else {
console.log("User already exists");
}
}, (err) => {
//connection failed error message
console.log("something went wrong");
});
}
When i do console.log(JSON.stringify(this.responseData)); backslahes are added to json object
How to avoid that and access message in the response.
Use this
import 'rxjs/add/operator/map';
this.http.get('YOUR_API_ENDPOINT').map(res => res.json()).subscribe(data => {
console.log(data);
});
I'm trying to setup a Facebook messenger bot and keep running into the same two errors.
Webhooks failing:
Webhooks disabled:
I'm creating my chatbot with NodeJS, Express, and a server. I am running my webhook on a heroku server. I have had it verified and saved by Facebook.
After that, I ran this code:
curl -ik -X POST "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=<token>"
this replied with a success message so I started adding code to reply to the incoming messages but I can't seem to get it connected.
Here is my code:
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var port = process.env.PORT || 3000;
// body parser middleware
app.use(bodyParser.urlencoded({ extended: true }));
app.get('/', function (req, res) {
if (req.query['hub.verify_token'] === '<myToken>') {
res.send(req.query['hub.challenge']);
}
res.send('Error, wrong validation token');
})
app.post('/', function (req, res) {
messaging_events = req.body.entry[0].messaging;
for (i = 0; i < messaging_events.length; i++) {
event = req.body.entry[0].messaging[i];
sender = event.sender.id;
if (event.message && event.message.text) {
text = event.message.text;
sendTextMessage(sender, "Text received, echo: "+ text.substring(0, 200));
}
}
res.sendStatus(200);
});
// error handler
app.use(function (err, req, res, next) {
console.error(err.stack);
res.status(400).send(err.message);
});
app.listen(port, function () {
console.log('Listening on port ' + port);
});
var token = <myToken>;
function sendTextMessage(sender, text) {
messageData = {
text:text
}
request({
url: 'https://graph.facebook.com/v2.6/me/messages',
qs: {access_token:token},
method: 'POST',
json: {
recipient: {id:sender},
message: messageData,
}
}, function(error, response, body) {
if (error) {
console.log('Error sending message: ', error);
} else if (response.body.error) {
console.log('Error: ', response.body.error);
}
});
}
At this point I should be able to start a chat with my bot and have it reply with an echo but nothing is happening.
Any help is appreciated. Thanks!
You are not listening on the correct endpoint.
Your app.post('/' should be
app.post('/webhook', function(req, res) {
var messagingEvents = req.body.entry[0].messaging;
messagingEvents.forEach(function(event) {
var sender = event.sender.id;