Posting Comments to WordPress with WPAPI - wordpress

I'm using Netlify event-triggered webhooks to call a script that's designed to post a new comment to the WordPress API. I'm trying to implement wpapi to make the POST request but not sure if I'm hooked up properly.
exports.handler = async (event, context, callback) => {
let body = JSON.parse(event.body).payload
if (body.form_name == 'comment-form') {
// I assume I have to authenticate here
var wp = new WPAPI({
endpoint: 'https://example.com/wp-json',
username: 'username',
password: '123456'
});
...
I then form the data to pass in... From what I can tell from the WordPress REST API, I can pass in a name, comment, and a post id. I'm not sure if I'm missing a parameter as I can't find any documentation about required params.
// url encode - not sure if this is required
let comment = {
author_name: encodeURI(author_name),
author_comment: encodeURI(author_name),
post: body.data.postId
}
I then try calling wp.comments().create() passing in the object and setting up a callback:
wp.comments().create(comment, function(args) {
console.log(args) }
).then(function( response ) {
console.log( response );
}).catch(function (err) {
console.log(err);
});
I am using this function in a Gatsby project and am utitlizing gatsby-source-wordpress to pull data from a WordPress site, if that makes any difference.
When I run this function in Netlify, in the function log, there is no response or error message.
Thanks

Related

In Meteor with Iron router how would I redirect to a thank you URL stored in the database after form submission

I have a system written in meteor where when someone submits a form it currently just shows a thankyou message in a modal. My client wants to be able to allow for multiple different thank you pages based on a thank you URL field on a clients record.
I am using iron router. I have successfully setup a server side route but I'm unable to even call that.
What I would like is to on form submission update the database then pull the clients thankyou URL and redirect the user to that. Sorry for not code to tweak but I'm just looking for the best way to handle it.
UPDATE:
Client Side
Meteor.call(
"addSendLeads",
{
bookingType: bookingType,
ad_platfrom: ad_platform,
senderID: email,
facebookPageID: fbPageID,
first_name: first_name,
last_name: last_name,
event_name: event_name,
startDate: startDate,
email: email,
phone: phone,
comments: comments,
},
(err) => {
if (err) {
console.log(err);
swal(
"Error",
"Sorry, there was an error. Please try again later."
);
} else {
target.firstName.value = "";
target.lastName.value = "";
target.email.value = "";
target.phone.value = "";
target.comments.value = "";
Router.go("/thankyou/" + url);
}
}
);
The Route in server/routes.js
Router.route("/thankyou/:url", { where: "server" }).get(function () {
this.response.writeHead(302, {
Location: url,
});
this.response.end();
});
Hope this helps to clarify...
Your submit form method should return your user custom URL, unless you pull that in the initial stage when you open the form.
With a method, you have a callback (pre Node16) or a .then(result => do_something_with_it). Async methods are already usable in Meteor 2.10.
Your call back or your async effect can call your routing:
Meteor.callAsync('submitForm', form) // or Meteor.call('name', {object data}, (err, res) => do_something_with_res)
.then(url => Router.go(url)
.catch(methodErrors => console.log(methodErros))

Contact Form 7 Recaptcha 3 headless site

I am building a wordpress headless site (frontend using Nuxt.js) and am trying to use recaptcha v3 in contact form 7 . I have already setup the integration using the built in cf7 integration.
But, the problem is contact form 7 is marking all of my emails as spam. Therefore I installed Flamingo plugin just to see the error log. Apparently the error log says reCAPTCHA response token is empty. Which makes sense because the recaptcha is setup in WordPress while since my frontend is decoupled, it doesn't get the token.
I have read about using vue-recaptcha but that means setting up a new recaptcha that is entirely separate from the recaptcha I setup in WordPress. I can't find a way to link the recaptcha for WordPress and my frontend together.
Any advice would be very much appreciated, thanks!
A post that I found similar to mine:
https://www.reddit.com/r/Wordpress/comments/o48hd1/contact_form_7_plugin_endpoint_for_recaptcha/
, but no clear answers.
I am successful in implementing recaptcha at the frontend right now but I have no idea how to make use of the recaptcha token from WordPress for the backend and frontend to work together. The recaptcha certainly cannot be only at the frontend because else people would be able to use Postman to spam my endpoint. This is how I did it:
async function verifyCaptcha() {
try {
// #ts-ignore
recaptchaToken.value = await context.$recaptcha.execute();
const response = await axios.post(
`/captcha-api/siteverify?secret=${process.env.SECRET_KEY}&response=${recaptchaToken.value}`
);
// console.log(response)
return response;
} catch (error) {
return error;
}
}
async function onSubmit(e: any) {
const recaptchaResponse = await verifyCaptcha();
// Display error message if verification was not successful
if (!recaptchaResponse.data.success) {
// #ts-ignore
context.$recaptcha.reset()
return;
}
// If verification was successful, send the message
await submit(e);
}
I have found the solution. We simply need to pass some specific recaptcha 3 responses required by contact form 7 back to contact form 7.
const token = await context.$recaptcha.execute('login')
// console.log('ReCaptcha token:', token)
const emailBody = {
"your-name" : form.name,
"email" : form.email,
"enquiry" : form.enquiry,
"message" : form.message,
//recaptcha responses to pass back to CF7
"_wpcf7_recaptcha_response" : token,
"wpcf7_recaptcha_response" : token,
"recaptcha_response" : token,
"recaptcha" : token,
"token" : token
}
const body = new FormData()
for (const field in emailBody) {
// #ts-ignore
body.append(field, emailBody[field])
}
const headers = {
'Content-Type': 'multipart/form-data',
}
const response = await axios.post('https://yourdomain.com/wp-json/contact-form-7/v1/contact-forms/{id}/feedback', body, { headers: headers})
// Use responseData to check its status to do some logic
const responseData = response.data
onMounted(async () => {
await context.$recaptcha.init()
})
onBeforeUnmount(() => {
context.$recaptcha.destroy()
})

Scraping an ASP.NET website with NodeJS

i am trying to login to my supplier website programatically and get the resseller price by code. i have my username and password provided by the supplier to use in the website which is powred by ASP.NET. i tried to use the request module but got no luck with it.
this the code i used so far :
var request = require('request');
var j = request.jar();
var request = request.defaults({ jar : j }) //it will make the session default for every request
//...
request({
url:"https://www.XXXXX.com/login.aspx",
method:"POST",
form:{
ctl00$cpholder$txtUserName:"YYYYYYYY",
ctl00$cpholder$txtPassword:"ZZZZZZZZ"
}
},
function(err,response,body){
console.log(err);
// here i try to access the product page like a reseller
request({
url:"https://www.XXXXXX.com/productdetails.aspx?id=20000028&itemno=90NB0CL1-M08420",
method:"GET",
}, function(err, response, body){
console.log(err);
//Some logic
});
});
}
this is the login form code ( in pastebin because it is very long )
https://pastebin.com/kwuRdLX4
please help

MailChimp API 3.0 Subscribe

I am having trouble sorting out the new MailChimp API (V3.0). It does not seem like there is a way to call a subscribe method. It seems like I have to use their Sign Up Form. Am I correct?
If by "subscribe" you mean that your application will add someone to a mailing list, you may want to take a look at the List Members Collection portion of their documentation.
http://kb.mailchimp.com/api/resources/lists/members/lists-members-collection
Adding/editing a subscriber via MailChimp v3.0 REST API.
// node/javascript specific, but pretty basic PUT request to MailChimp API endpoint
// dependencies (npm)
var request = require('request'),
url = require('url'),
crypto = require('crypto');
// variables
var datacenter = "yourMailChimpDatacenter", // something like 'us11' (after '-' in api key)
listId = "yourMailChimpListId",
email = "subscriberEmailAddress",
apiKey = "yourMailChimpApiKey";
// mailchimp options
var options = {
url: url.parse('https://'+datacenter+'.api.mailchimp.com/3.0/lists/'+listId+'/members/'+crypto.createHash('md5').update(email).digest('hex')),
headers: {
'Authorization': 'authId '+apiKey // any string works for auth id
},
json: true,
body: {
email_address: email,
status_if_new: 'pending', // pending if new subscriber -> sends 'confirm your subscription' email
status: 'subscribed',
merge_fields: {
FNAME: "subscriberFirstName",
LNAME: "subscriberLastName"
},
interests: {
MailChimpListGroupId: true // if you're using groups within your list
}
}
};
// perform update
request.put(options, function(err, response, body) {
if (err) {
// handle error
} else {
console.log('subscriber added to mailchimp list');
}
});

Webhook for Mailgun POST?

I am trying to store email messages as JSON (as parsed by Mailgun) in a Mongo.Collection through a Mailgun webhook. I set up an iron-router server-side route to handle the request, but this.request.body is empty. I am using Mailgun's "Send A Sample POST" to send the request, and the POST looks fine using e.g. http://requestb.in/. I was hoping that request.body would have the data, as mentioned in How do I access HTTP POST data from meteor?. What am I doing wrong?
Router.map(function () {
this.route('insertMessage', {
where: 'server',
path: '/api/insert/message',
action: function() {
var req = this.request;
var res = this.response;
console.log(req.body);
...
I'm not sure that is the right syntax. Have you tried using Router.route ?
Router.route('insertMessage',
function () {
// NodeJS request object
var request = this.request;
// NodeJS response object
var response = this.response;
console.log("========= request: =============");
console.log(request);
// EDIT: also check out this.params object
console.log("========= this.params: =============");
console.log(this.params);
// EDIT 2: close the response. oops.
return response.end();
},
{
where: 'server',
path: '/api/insert/message'
}
);
I think the issue is that Mailgun sends a multipart POST request, e.g. it sends "fields" as well as "files" (i.e. attachments) and iron-router does not set up a body parser for multipart requests. This issue is discussed here and here on iron-router's Github Issues. I found this comment particularly helpful, and now I can parse Mailgun's sample POST properly.
To get this working, in a new Meteor project, I did
$ meteor add iron:router
$ meteor add meteorhacks:npm
In a root-level packages.json I have
{
"busboy": "0.2.9"
}
which, using the meteorhacks:npm package, makes the "busboy" npm package available for use on the server via Meteor.npmRequire.
Finally, in a server/rest-api.js I have
Router.route('/restful', {where: 'server'})
.post(function () {
var msg = this.request.body;
console.log(msg);
console.log(_.keys(msg));
this.response.end('post request\n');
});
var Busboy = Meteor.npmRequire("Busboy");
Router.onBeforeAction(function (req, res, next) {
if (req.method === "POST") {
var body = {}; // Store body fields and then pass them to request.
var busboy = new Busboy({ headers: req.headers });
busboy.on("field", function(fieldname, value) {
body[fieldname] = value;
});
busboy.on("finish", function () {
// Done parsing form
req.body = body;
next();
});
req.pipe(busboy);
}
});
In this way I can ignore files (i.e., I don't have a busboy.on("file" part) and have a this.request.body available in my routes that has all the POST fields as JSON.

Resources