I need you help with the MTN MOMO API...I am posting below some code I tried debugging for the entire day yesterday. The code works in Postman but the same fails to work in browser since Browsers implement CORS( Access-Control-Allow-Origin). Any guidance would be appreciated.
I was able to work around the CORS issue, now am stuck on the error ' POST https://sandbox.momodeveloper.mtn.com/v1_0/apiuser 401 (Access Denied) '. This error worries me since I have give all parameters as needed by the API call.
async function postData() {
try {
let result = await fetch(
"https://sandbox.momodeveloper.mtn.com/v1_0/apiuser",
{
method: "post",
mode: "no-cors",
headers: {
"X-Reference-Id": "9de3e973-53c8-4cc4-a8eb-25a4a9ccb5f9",
"Ocp-Apim-Subscription-Key": "15e4e92ef6914728b8414e2bb67d7357",
"Content-type": "application/json",
//'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify({
providerCallbackHost: "username",
}),
}
);
console.log(result);
} catch (e) {
console.log(e);
}
}
I decided to post the KEYS since they are on sandbox and not live account(I have no live account yet).
THe full API is here...https://momodeveloper.mtn.com/
Related
I am trying to access the API to get some data however i keep getting this CORS error. I have checked my code for any syntax errors but i can't find any. I have attached a picture of the error and my function which is supposed to get the data.
async function getData(){
const request = await fetch('https://api.igdb.com/v4/games', {
method: 'POST',
headers: {
'Client-ID': 'jglmao8u28qo1p9wltqne325i7xh3u',
'Authorization': 'Bearer 4xau27m6liukizor4z2l8mlb7vbpjk',
}
})
const response = await request.json();
console.log(response);
}
There is a great proxy out there used just for this - bypassing a CORS block. The source code is here: https://github.com/Rob--W/cors-anywhere, and you would use it like this:
https://cors-anywhere.herokuapp.com/https://api.igdb.com/v4/games
basically just adding the CORS-Anywhere URL before your actual image URL.
In your situation, it would be
async function getData(){
const request = await fetch('https://cors-anywhere.herokuapp.com/https://api.igdb.com/v4/games', {
method: 'POST',
headers: {
'Client-ID': 'jglmao8u28qo1p9wltqne325i7xh3u',
'Authorization': 'Bearer 4xau27m6liukizor4z2l8mlb7vbpjk',
}
})
const response = await request.json();
console.log(response);
}
If you get rate limited by that website, try https://circumvent-cors.herokuapp.com/, this is one that I have deployed from the GitHub source code, no modifications and I do not think it should rate limit you.
Cheers, and let me know if this works.
I have the following code which works when I run it as a local serverless function with netlify dev, but I need it to run cross origin from a dev server to the hosted server function. I put the function in a aws lambda function but I am getting a cross origin blocked error on my https:dev.website.com, I thought I have the correct headers in the return object so not sure why I am getting a cross origin error.
Any help would be great
const sanityClient = require("#sanity/client");
const client = sanityClient({
projectId: "random-id",
dataset: "production",
useCdn: true,
});
exports.lambdaHandler = async (event, context) => {
var body = JSON.parse(event.body);
//console.log(body.price_id)
try {
const checkPriceId = async (test) => {
const query = `*[_type == "products" && price_id == "${body.price_id}"]`;
const documents = await client.fetch(query, {}); // this could throw
return documents.map((document) => document.sold);
};
var ok = checkPriceId().then((test) => {
return new Promise(function (resolve, reject) {
//console.log(test) // this will log the return value from line 7
console.log(test);
resolve(test);
});
});
var bools = await ok;
// prettier-ignore
return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Methods':'GET, POST, OPTION',
},
body: JSON.stringify({
sold: bools,
}),
};
} catch (err) {
return { statusCode: 500, body: err.toString() };
}
};
This is my request to the function if that helps
var fetchUrl = https://random.executue-api.aws.com/prod/sold //not exact
var fetchData = async function () {
const response = await fetch(fetchUrl, {
method: "post",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
price_id: final,
}),
})
.then(res => {
return res.json()
})
.catch(error => console.log(error))
return response
}
Update:
I tried adding cors the way suggested in the answer below, but it failed seen below so I tried manually adding the method response seen after.
I still get a cross domain error. And I have changed the domain so it is now https as well. Really stuck here.
I was looking into this more, and it seems like before it does the actual post it does a cors check at the options method, so I added in the same access control headers, and deployed but did not work. Don't quite get this.
Your headers look ok to me. (note: If you mix HTTP and HTTPS you are most likely to get a mixed content error in the client). If it is ONLY a CORS issue that you are seeing in the console in the web browser, then you might not have configured the API Gateway correctly in AWS.
In AWS, go to API Gateway and you should see something like the below:
Make sure that you enable CORS and then redeploy.
UPDATE:
Just looking at a previous implementation of a lambda function I setup with AWS. The headers I declared were as follows:
headers: {
"Content-Type" : "application/json",
"Access-Control-Allow-Origin" : "*",
"Allow" : "GET, OPTIONS, POST",
"Access-Control-Allow-Methods" : "GET, OPTIONS, POST",
"Access-Control-Allow-Headers" : "*",
"Access-Control-Allow-Credentials" : true
}
Your headers look OK to me though. However, when you created the method in the API Gateway, did you select Use Proxy Lambda Integration? (see screenshot).
Your client side fetch request looks ok. For reference mine was:
const url = 'your url';
const options = {
method: 'POST',
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
};
fetch(url, options).then(res => res.json());
Unrelated to this issue, but its not advisable to mix Async/Await with .then promise chaining. But this isn't the issue you are having. Just something to note.
Check the values from your Integration Response / try setting them manually for both OPTIONS and POST (and if that works, make sure you are passing through the response correctly from the lambda).
Your POST action should only require the Access-Control-Allow-Origin header. The other two (Access-Control-Allow-Methods, Access-Control-Allow-Headers) belong in the OPTION action. See this writeup, and note the full example exchange for a preflighted request (in grey): https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#preflighted_requests
I'm trying to implement a simple URL shortener using firebase dynamic links via the REST API.
I prepared a simple async JS function for testing (since I don't have a billing account to make external egress calls in cloud functions).
Below is the code:
async function fetcher(keyAPI,tempURL) {
let reqURL=`https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key=${keyAPI}`;
let parameters = {
method : "POST",
headers: {
'Content-Type': 'application/json'
},
body : JSON.stringify({
"longDynamicLink": tempURL,
"suffix": {
"option": "SHORT"
}
})
};
await fetch(reqURL,parameters)
.then(res => console.log(res))
.catch(err => console.log(err));
}
I'm recieving a bad request as the response:
Response {
type: "cors", "https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key=[MY_WEB_API_KEY_HERE]",
redirected: true,
status: 400,
ok: false,
statusText: "Bad Request",
headers: Headers,
body: ReadableStream,
bodyUsed: false
}
I need help to debug it.
Try the following after creating a prefix link URL in the firebase console since it is required as a parameter:
let reqURL=`https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key=<API_KEY_HERE>`;
let parameters = {
method : "POST",
headers: {
'Content-Type': 'application/json'
},
body : JSON.stringify({
"dynamicLinkInfo": {
"domainUriPrefix": "[PREFIX_URL]",
"link": "[YOUR_LINK]",
},
"suffix": {
"option": "SHORT"
}
})
};
// Get response since it returns pending promise above
return await fetch(reqURL,parameters)
.then(res => res.json())
.catch(err => err);
}
// Fetch from Promise
sURL.then(res => {
console.log(res);
return res;
});
My previous answer was deleted, I don't know why, but its ok
Deleted Post IMG
I faced this problem earlier and some research on it. And it was working. So I took my all code, cleaned it up, and published it on Github, so this doubt can go.
So, Some comments asked How to use this, So here is the answer
You have to add lib from the CDN or self host it, its better to customize the code by yourself for your needs. CDN Link - https://fdl.js.org/src/links.js
Now when you have added the lib, try to call it with this function.
This returns you the shortlink
makefdl(key, st, si, sd, domain, link);
Expression Docs
And You get the shortlink back...
Note: You have to wait for the API to reply, so make a await call, like this
async function links(){
var slink = await makefdl(key, st, si, sd, domain, link);
if(slink != null){
console.log(slink);
// do something here with the shortlink
}
}
<script src="https://fdl.js.org/src/links.js"></script>
If you have any questions then please write down in the comments. I will be happy to answer. :)
For more info about FDljs, visit FDL.js Official Site
I am trying to make a post request to create a new wiki page using the redmine-api. I am using JavaScript and Axios. However I a getting a 401 error(UnAuthorize).
My goal is to be able to send a word document to my redmine and create a wiki page.
I am using the Api key provided and I did enable the rest api feature in my redmine setting
I have included the api key in the header however it is not working.
var wordDocument = "./Redmine.docx"
axios.post('<website url>/uploads.json', {
headers: {
'Content-Type': 'application/octet-stream',
'Cache-Control': 'no-store',
'key': '<api-key>'
},
data:wordDocument
})
.then(function (response) {
console.log("succeeed---> ");
console.log (response)
})
.catch(function (error) {
console.log("failed-----> ");
console.log(error.response.headers)
console.log(error.message)
console.log("failed-----> ");
})
I am getting a status: '401 Unauthorized',
Try using the other authentication methods mentioned in the docs:
x passed in as a "key" parameter
- passed in as a username with a random password via HTTP Basic authentication
- passed in as a "X-Redmine-API-Key" HTTP header (added in Redmine 1.1.0)
https://www.redmine.org/projects/redmine/wiki/Rest_api#Authentication
Also ensure that you're using the correct API key.
You can find your API key on your account page ( /my/account ) when logged in, on the right-hand pane of the default layout.
Alright I got it working.
I did "axios({})" instead of "axios.post". I do not know what the different is? I thought it was the same.
Here is my code for anyone who run into this.\
var wordDocument = "./Redmine.docx"
axios({
method: 'post',
url: '<redmind_url>/uploads.json',
headers: { 'Content-Type': 'application/octet-stream'},
params: { 'key': '<api key>'},
data: wordDocument
})
.then(function (response) {
console.log("succeeed---> ");
console.log(response.data)
})
.catch(function (error) {
console.log("failed-----> ");
console.log(error.response.statusText, "-->", error.response.status);
console.log(error.response.headers)
console.log(error.message)
console.log("failed-----> ");
})
I am still learning to work with different APIs, and have been working with JavaScript and the Yelp API. I have tried using Ajax, as well as the code I have posted here, but I continue to get the error of:
"code": "TOKEN_MISSING",
"description": "An access token must be supplied in order to use this endpoint."
I will continue to search through other posts, but if anyone could point out to me what I am doing incorrectly and how to fix it, I would really appreciate it?
var URL = 'https://api.yelp.com/v3/businesses/search?location=40515&term&categories=vet&limit=10';
var API_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxx';
var req = new Request(url, {
method: 'GET',
headers: new Headers({
'Authorization: Bearer', API_KEY,
'Content-Type': 'application/json'
})
mode: 'no-cors'
});
fetch (req)
.then((response) => {
if(response.ok){
return response.json();
}else{ssss
throw new Error();
}
})
.then((jsonData) => {
console.log(jsonData);
})
.catch((err) => {
console.log('ERROR: ', err.message);
});
I think you just need to fix up:
'Authorization: Bearer', API_KEY,
to be something like:
'Authorization': `Bearer ${API_KEY}`,
or:
'Authorization': 'Bearer ' + API_KEY,
And if this line isn't just redacted for posting here:
var API_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxx';
then you would need to actually get an API key from yelp as 'xxxxxxxxxxxxxxxxxxxxxxxxxx' would not be a valid key
I think an answer I posted before to a similar question with a full code sample may lead you in the right direction:
https://stackoverflow.com/a/51461033/9525657
Have a look, it’s an easy and simple process of pulling from the service :)