WooCommerce REST API PUT on Variations does not work - woocommerce-rest-api

I have logged this issue on GitHub but I understand it will take time to get attention. Is there another way of updating Product Variations?
https://github.com/woocommerce/woocommerce/issues/35555
When I PUT a stock_quantity or price update for a product variation nothing changes. This however works 100% on a product but not a variation. The below will have no effect even though I receive an OK status 200.
PUT: wp-json/wc/v3/products/6360/variations/6361
{
"stock_quantity": 7
}
I also tried using the batch endpoint but also nothing gets updated.
/wp-json/wc/v3/products/6360/variations/batch
"update": [
{
"id":6361,
"stock_quantity": 4
}
]

This is not a bug, I was using Postman and the 200 OK returned confused the issue.
Once I added the required Content-Type:application/json header, the record successfully updated.
I also made use of a deprecated NodeJS library woocommerce-api and later tried with the replacement woocommerce-rest-api but both does not seem to handle this correctly.
I can suggest to rather just axios directly to the woocommerce rest api:
const baseUrl = `${process.env.WOOCOMMERCE_URI}/wp-json/wc/v3/`;
const instance = {
headers: {'Content-Type': 'application/json'},
auth: {
username: process.env.WOOCOMMERCE_KEY,
password: process.env.WOOCOMMERCE_SECRET
}
};
let putUrl = `products/${woocommerceImport.onlineProductId}/variations/${woocommerceImport.onlineVariantId}`;
await axios.put(`${baseUrl}${putUrl}`, {
stock_quantity: stock
}, instance);

Related

strapi get related objects of User

I'm using strapi community edition v3.6.8. I have two different models ,User and CarModel. The User Model is strapi's integrated user model. The relation User: CarModel is 1:n
So I've got a profile page in which I want to fetch the User and their related CarModels. I can't get my head around how to achieve this.
I've read several answers that include creating a service which then fetches the related CarModelobjects but I can't figure out what to put into the service.
So the conclusion I've reached so far is that it is probably best if I just create a custom endpoint which fetches the current user and related objects.
How do I go on about this? This is the code I currently have:
axios.get(`http://localhost:1337/users/currentUser`, {
headers: {
Authorization: `Bearer ${token}`
}
})
In extensions/users-permissions/config I've created a routes.json with this content:
"method": "GET",
"path": "/users/currentUser",
"handler": "User.currentUser",
"config": {
"policies": ["policies.isAuthenticated"]
}
}
in config/policies I've created a is-authenticated.js - File with the following content:
module.exports = async (ctx, next) => {
if (ctx.state.user) {
return await next();
}
ctx.unauthorized(`You're not logged in!`);
};
And lastly in extensions/users-permissions/controllers I've created a User.js file with the following content:
const { sanitizeEntity } = require('strapi-utils');
const sanitizeUser = user =>
sanitizeEntity(user, {
model: strapi.query('user', 'users-permissions').model,
});
module.exports = {
currentUser: async (ctx, next) => {
strapi.query('user').find({id: ctx.id}, ['car-model']);
await next();
}
};
So now my questions would be:
1st: Something is wrong because when trying to GET /users/currentUser I get a 403. What exactly am I doing wrong?
2nd: Is this approach even valid in the first place?
And 3rd: What would be the correct approach to solving this problem? Because somewhere else I've read another approach which included writing a custom service which handles resolving the relation, but this looked very complicated imho, considering I'm simply trying to resolve a relation that already exists in the database.
I've also tried manipulating the users/me endpoint which didn't yield any results (and is probably also discouraged).
Interestingly: when the user logs in, I get the user object and all foreign key relations returned. Only when I query /users/me I get only the user data without relations. So I've read that this is a security feature, but what endpoint is used then, when posting to /auth/local and why does this endpoint return the user and related objects?
Could I use this endpoint instead of /users/me?
Any help to this problem would be greatly appreciated, best regards,
deM
So for anyone else looking for a solution, I figured it out. I added a custom route to currentUser as described above then I added a controller for this route in which I put the following code:
currentUser: async (ctx, next) => {
let carModelsOfUser = await (strapi.query('user', 'users-permissions').findOne({id: ctx.state.user.id}, ['carModels', 'carModels.images', 'carModels.ratings.rating']));
return carModelsOfUser;
}
CAUTION!
This also returns the user's hashed password and other potentially sensitive information.
Strapi offers the sanitizeEntity function to remove sensitive information, but as of now I haven't figured out how to use this in that context, as I'm not using the "raw" user here but instead joining some fields.

Dynamic push notifications w/ Onesignal, Nuxtjs and Prismic CMS

I'm building a PWA using Nuxtjs that's fetching blog content from a prismic api. OneSignal has been installed and configured following the documentation provided here and I was able to subscribe a user to the app and deliver the welcome push along with other push via OneSignal's dashboard.
I now want to send push notifications whenever new content is posted to the blog. Any help would be appreciated.
EDIT
I am triggering the push notification whenever a user goes to https://example.com/blog. NB: prismic sorts by latest post so this.docs[0] fetches the latest article from the array.
async fetch() {
try {
const query = await this.$prismic.api.query(this.$prismic.predicates.at('document.type', 'blog_posts'), {pageSize: 6}).then((query)=>{
this.docs = query.results;
const requestOptions = {
method: "POST",
headers: {"Content-Type": "application/json", "Authorization": `Basic ${process.env.API_KEY}`},
body: JSON.stringify({
app_id: process.env.APP_ID,
included_segments: ["All"],
contents: {en: this.docs[0].data.post_content[0].text},
headings: {en: this.docs[0].data.post_title[0].text},
chrome_web_image: this.docs[0].data.featured_image.url,
big_picture: this.docs[0].data.featured_image.url,
web_url: `https://example.com/blog/${this.docs[0].uid}`
})
}; fetch('https://onesignal.com/api/v1/notifications', requestOptions)
})
} catch (e) {
// Send to bugsnag
console.log(e)
}
}, fetchDelay: 500,
Prismic allows you set webhooks that trigger when a document is published. See prismic blog. Using express, I created one that will do two things:
Get all blog post from prismic
Send onesignal web push notification when post is published
See code snippet here: https://gitlab.com/-/snippets/2003202
References:
Prismic Node Integration
Bearer.sh Guide on webhook listeners

Not be able to console log Auth0 user_metadata. I created a custom rule I also see the data in postman.What am I doing wrong

** I'm doing as following, I already created a custom rule.**
componentDidMount() {
console.log(token)
let response = fetch('https://DOmain.eu.auth0.com/userinfo', {
method: 'GET',
headers: {
Authorization: 'Bearer ' + token,
},
}).then((response) => response.json())
.then(responseJson => data = responseJson).then(console.log(data.nickname));
const metadata = data["https://Domain.eu.auth0.com/user_metadata"]
console.log(metadata);
}
My rule:
The Rule you have setup looks good, but will not work as the namespace is an Auth0 domain
Any non-Auth0 HTTP or HTTPS URL can be used as a namespace identifier,
and any number of namespaces can be used
Give it a shot with an alternate namespace, example 'https://myapp.example.com/', and you should be good to go!
As a side note, I would try to avoid adding all the usermetadata to the idtoken which can cause the generated token to be too large. You should also ensure that the data being included is not sensitive and can be disclosed. Some items that may be helpful, a quick read here: https://auth0.com/docs/metadata and here: https://auth0.com/docs/scopes/current/custom-claims to help you along the way!

Fetch Post request not working in Custom functions Office Addin [TypeError: Network request failed]

I having been facing this error in custom functions excel Add-in, where I'm trying to call an external service inside a custom function. It works fine for a GET request such as this:
function stockPrice(ticker) {
var url = "https://api.iextrading.com/1.0/stock/" + ticker + "/price";
return fetch(url)
.then(function(response) {
return response.text();
})
.then(function(text) {
return parseFloat(text);
});
}
CustomFunctionMappings.STOCKPRICE = stockPrice;
Taken from https://learn.microsoft.com/en-us/office/dev/add-ins/excel/excel-tutorial-custom-functions#create-a-custom-function-that-requests-data-from-the-web
But gives an exception for a POST request like this:
function stockPrice(ticker) {
var url = "https://westcentralus.api.cognitive.microsoft.com/text/analytics/v2.0/sentiment";
return fetch(url, {
method: 'POST',
headers: {
'Ocp-Apim-Subscription-Key': key,
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(body))
.then(function(response) {
return response.json();
})
.then(function(response) {
return response.somevalue;
})
.catch(e => {
console.error("Caught exception");
return JSON.stringify(e);
});
}
The above is just a sample to have an idea, of how I'm calling my service. I have tried it with 2-3 different services, and I figured out that after running fetch, the code goes to catch block, and the error value that is returned in the excel is an empty object '{}'. Since there are no ways to debug custom functions on windows, and since there is no specific error description, I'm unable to figure out the issue. I have also added my service domain to App Domain list in manifest file but still no effect.
I am not sure that particular API accepts POST requests, so you maybe running into that.
Debugging in Windows is still being worked on but you can use Excel online and F12tools to debug.
If you are on Windows, you can console.log statements in conjunction with the Runtime logging:
https://learn.microsoft.com/en-us/office/dev/add-ins/excel/custom-functions-best-practices#troubleshooting
Hope that helps and we will update this when debugging is ready on for custom functions on windows desktop.

PUT Request not happening at all in Fantom

I am having some trouble with PUT requests to the google sheets api.
I have this code
spreadsheet_inputer := WebClient(`$google_sheet_URI_cells/R3C6?access_token=$accesstoken`)
xml_test := XDoc{
XElem("entry")
{
addAttr("xmlns","http://www.w3.org/2005/Atom")
addAttr("xmlns:gs","http://schemas.google.com/spreadsheets/2006")
XElem("id") { XText("https://spreadsheets.google.com/feeds/cells/$spreadsheet_id/1/private/full/R3C6?access_token=$accesstoken"), },
XElem("link") { addAttr("rel","edit");addAttr("type","application/atom+xml");addAttr("href","https://spreadsheets.google.com/feeds/cells/$spreadsheet_id/1/private/full/R3C6?access_token=$accesstoken"); },
XElem("gs:cell") { addAttr("row","3");addAttr("col","6");addAttr("inputValue","testing 123"); },
},
}
spreadsheet_inputer.reqHeaders["If-match"] = "*"
spreadsheet_inputer.reqHeaders["Content-Type"] = "application/atom+xml"
spreadsheet_inputer.reqMethod = "PUT"
spreadsheet_inputer.writeReq
spreadsheet_inputer.reqOut.writeXml(xml_test.writeToStr).close
echo(spreadsheet_inputer.resStr)
Right now it returns
sys::IOErr: No input stream for response 0
at the echo statement.
I have all the necessary data (at least i'm pretty sure) and it works here https://developers.google.com/oauthplayground/
Just to note, it does not accurately update the calendars.
EDIT: I had it return the response code and it was a 0, any pointers on what this means from the google sheets api? Or the fantom webclient?
WebClient.resCode is a non-nullable Int so it is 0 by default hence the problem would be either the request not being sent or the response not being read.
As you are obviously writing the request, the problem should the latter. Try calling WebClient.readRes() before resStr.
This readRes()
Read the response status line and response headers. This method may be called after the request has been written via writeReq and reqOut. Once this method completes the response status and headers are available. If there is a response body, it is available for reading via resIn. Throw IOErr if there is a network or protocol error. Return this.
Try this:
echo(spreadsheet_inputer.readRes.resStr)
I suspect the following line will also cause you problems:
spreadsheet_inputer.reqOut.writeXml(xml_test.writeToStr).close
becasue writeXml() escapes the string to be XML safe, whereas you'll want to just print the string. Try this:
spreadsheet_inputer.reqOut.writeChars(xml_test.writeToStr).close