Microsoft Graph Drive search - microsoft-graph-api

I'm attempting to modify the node.js Quick Start example to produce a list of the user's excel documents, but I'm running into issues.
This query works (returns a non-empty result) in the Graph Explorer:
https://graph.microsoft.com/v1.0/me/drive/root/search(q='.xlsx')?select=name,id,webUrl
I have tried a few ways to reproduce it in graphHelpers.js.
This query returns an empty result:
function getExcelDocs(accessToken, callback) {
// Get list of excel docs in the user's onedrive
request
.get("https://graph.microsoft.com/v1.0/me/drive/root/search(q='.xlsx')?select=name,id,webUrl")
.set('Authorization', 'Bearer ' + accessToken)
.end((err, res) => {
// Returns 200 OK and the search result in the body.
callback(err, res);
});
}
If I substitute the search URL with the drive children query, I get back a non-empty set of documents.
.get('https://graph.microsoft.com/v1.0/me/drive/root/children')
Is there a problem with how I'm formatting the query url?

The parens in the URI are causing the problem here. The content within those parens represents the body of the request. The underlying library that is processing this request (SuperAgent) doesn't seem to like them going directly into the URI.
I believe you can fix this by providing the URL components separately:
request
.get("https://graph.microsoft.com/v1.0/me/drive/root/search", "q='.xlsx'")
.query({ select: 'name,id,webUrl'})
.set('Authorization', 'Bearer ' + accessToken)
.end((err, res) => {
// Returns 200 OK and the search result in the body.
callback(err, res);
});
Alternatively, this might also work:
request
.get("https://graph.microsoft.com/v1.0/me/drive/root/search")
.query({ select: 'name,id,webUrl'})
.send("q='.xlsx'")
.set('Authorization', 'Bearer ' + accessToken)
.end((err, res) => {
// Returns 200 OK and the search result in the body.
callback(err, res);
});

Related

Edit yammer comment using REST Api

When using "https://api.yammer.com/api/v1/messages/", I get errors.First "Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource." error. Second CORS policy blocker error.
function editComment(MessagePostId,GroupID) {
var commentData = new FormData();
commentData.append('body', editedComment); //updated comment text
commentData.append('group_id', GroupID); //group id
commentData.append('replied_to_id', MessagePostId); Individual message id
yam.platform.request({
url: "https://api.yammer.com/api/v1/messages/"+MessagePostId,
method: "PATCH",
data: commentData,
success: function (res) {
alert("The request was successful.");
console.dir(res);
},
error: function (res) {
alert("There was an error with the request.");
console.log(res)
}
})}
I tried "POST" as well but facing the same issue again and again.
By any chance, is there any information about REST api for edit comments functionality ?.
Editing is not currently supported by the public API. This is noted in the original release announcement:
The endpoints will continue to get the most recent version of each
message. The data will not include version history or the edit flag.
There will not be endpoints for making edits to messages.

Google Spreadsheet Protected Web-App Access Level Anyone

I have deployed a gsheets web-app and the code executes fine if the web-app's "who has access to this" is set to "anyone, annonymous" access. below is this code.
var data = {
'command1': 'usermenu',
'command2': 'dopayroll'
};
var options = {
'method' : 'post',
'payload' : data
};
var response = UrlFetchApp.fetch(ScriptApp.getService().getUrl(), options);
getSpread().toast(response.getContentText());
What I want to do, is change the access level to "Anyone" - which is access by any authenticated google account (right?). Added the following code to "var options" but returns an error code 401. How can I make this work?
'header' : { 'Authorization': 'Bearer ' + ScriptApp.getOAuthToken() },
EDIT; I should add that I'm a newbie in things related to OAuth and stuff.
There was a response posted which is now not visible.
My thanks to the person who did and having tested it, I can now confirm that the solution proposed works. There were 2 parts to the solution. First the correct header below ("header" should really be "headers")
'headers' : { 'Authorization': 'Bearer ' + ScriptApp.getOAuthToken() },
and adding the following comment to trigger Drive scope access for the project.
// DriveApp.getFiles()

concatenate variable in URL.React Native

I am unable to concatenate state in URL. Have searched but I could not find the solution, and i'm a beginner sorry for asking such a basic question. State has the value before it is sent as a parameter in URL(i have seen it in console), API returns the expected result if I hard code the value, but if a state or even a variable is passed as a parameter it returns error: "NO records found". What am I doing wrong?
this.state.secid = this.props.navigation.state.params.secid
console.log(this.state.secid)
this.state.classid = this.props.navigation.state.params.clasid
console.log(this.state.classid)
// Sending Request
fetch('exampleapi/parameter?
class=${this.state.classid}&section=${this.state.secid}',{
headers: {
'Content-Type':'application/json',
'credentials': 'same-origin',
'Accept': 'application/json',
'Authorization': 'Bearer ' + tokenval
}
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({ allstudents : responseJson })
console.log(this.state.allstudents)
})
You need to make following changes in your code
var url = 'exampleapi/parameter?class='+this.state.classid+'&section='this.state.secid;
fetch(url,{
headers: {
'Content-Type':'application/json',
'credentials': 'same-origin',
'Accept': 'application/json',
'Authorization': 'Bearer ' + tokenval
}
})
Concatenation in react native is done by (+) operator. As URL also a string.
Hope it works for you.
I solved this issue by using backtick notation. Replacing ' '(single quote) in URL by ``(back ticks).
If anybody wants to read more about backtick notation this is an amazing answer : What is the usage of the backtick symbol (`) in JavaScript?
From what I can see in the code added the string concatenation is not done correctly.
It should be done as explained below:
this.state.secid = this.props.navigation.state.params.secid
this.state.classid = this.props.navigation.state.params.clasid
const requestURL = `exampleapi/parameterclass=${this.state.classid}&section=${this.state.secid}`
Then, I would recommend to log and check if you are getting the URL as expected. Also I would suggest to stick to do this es6 way rather than using + for concatenation (As using + is more error prone, you might miss a space place where required - In your case the place you are setting Authorization header ).
Moreover why not use the good stuff when its supported out of the box by react native
Some references:
https://developers.google.com/web/updates/2015/01/ES6-Template-Strings#string_substitution
https://facebook.github.io/react-native/docs/javascript-environment.html
(search for text Template Literals in the page).

How to retrieve Medium stories for a user from the API?

I'm trying to integrate Medium blogging into an app by showing some cards with posts images and links to the original Medium publication.
From Medium API docs I can see how to retrieve publications and create posts, but it doesn't mention retrieving posts. Is retrieving posts/stories for a user currently possible using the Medium's API?
The API is write-only and is not intended to retrieve posts (Medium staff told me)
You can simply use the RSS feed as such:
https://medium.com/feed/#your_profile
You can simply get the RSS feed via GET, then if you need it in JSON format just use a NPM module like rss-to-json and you're good to go.
Edit:
It is possible to make a request to the following URL and you will get the response. Unfortunately, the response is in RSS format which would require some parsing to JSON if needed.
https://medium.com/feed/#yourhandle
⚠️ The following approach is not applicable anymore as it is behind Cloudflare's DDoS protection.
If you planning to get it from the Client-side using JavaScript or jQuery or Angular, etc. then you need to build an API gateway or web service that serves your feed. In the case of PHP, RoR, or any server-side that should not be the case.
You can get it directly in JSON format as given beneath:
https://medium.com/#yourhandle/latest?format=json
In my case, I made a simple web service in the express app and host it over Heroku. React App hits the API exposed over Heroku and gets the data.
const MEDIUM_URL = "https://medium.com/#yourhandle/latest?format=json";
router.get("/posts", (req, res, next) => {
request.get(MEDIUM_URL, (err, apiRes, body) => {
if (!err && apiRes.statusCode === 200) {
let i = body.indexOf("{");
const data = body.substr(i);
res.send(data);
} else {
res.sendStatus(500).json(err);
}
});
});
Nowadays this URL:
https://medium.com/#username/latest?format=json
sits behind Cloudflare's DDoS protection service so instead of consistently being served your feed in JSON format, you will usually receive instead an HTML which is suppose to render a website to complete a reCAPTCHA and leaving you with no data from an API request.
And the following:
https://medium.com/feed/#username
has a limit of the latest 10 posts.
I'd suggest this free Cloudflare Worker that I made for this purpose. It works as a facade so you don't have to worry about neither how the posts are obtained from source, reCAPTCHAs or pagination.
Full article about it.
Live example. To fetch the following items add the query param ?next= with the value of the JSON field next which the API provides.
const MdFetch = async (name) => {
const res = await fetch(
`https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/${name}`
);
return await res.json();
};
const data = await MdFetch('#chawki726');
To get your posts as JSON objects
you can replace your user name instead of #USERNAME.
https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/#USERNAME
With that REST method you would do this: GET https://api.medium.com/v1/users/{{userId}}/publications and this would return the title, image, and the item's URL.
Further details: https://github.com/Medium/medium-api-docs#32-publications .
You can also add "?format=json" to the end of any URL on Medium and get useful data back.
Use this url, this url will give json format of posts
Replace studytact with your feed name
https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/studytact
I have built a basic function using AWS Lambda and AWS API Gateway if anyone is interested. A detailed explanation is found on this blog post here and the repository for the the Lambda function built with Node.js is found here on Github. Hopefully someone here finds it useful.
(Updating the JS Fiddle and the Clay function that explains it as we updated the function syntax to be cleaner)
I wrapped the Github package #mark-fasel was mentioning below into a Clay microservice that enables you to do exactly this:
Simplified Return Format: https://www.clay.run/services/nicoslepicos/medium-get-user-posts-new/code
I put together a little fiddle, since a user was asking how to use the endpoint in HTML to get the titles for their last 3 posts:
https://jsfiddle.net/h405m3ma/3/
You can call the API as:
curl -i -H "Content-Type: application/json" -X POST -d '{"username":"nicolaerusan"}' https://clay.run/services/nicoslepicos/medium-get-users-posts-simple
You can also use it easily in your node code using the clay-client npm package and just write:
Clay.run('nicoslepicos/medium-get-user-posts-new', {"profile":"profileValue"})
.then((result) => {
// Do what you want with returned result
console.log(result);
})
.catch((error) => {
console.log(error);
});
Hope that's helpful!
Check this One you will get all info about your own post........
mediumController.getBlogs = (req, res) => {
parser('https://medium.com/feed/#profileName', function (err, rss) {
if (err) {
console.log(err);
}
var stories = [];
for (var i = rss.length - 1; i >= 0; i--) {
var new_story = {};
new_story.title = rss[i].title;
new_story.description = rss[i].description;
new_story.date = rss[i].date;
new_story.link = rss[i].link;
new_story.author = rss[i].author;
new_story.comments = rss[i].comments;
stories.push(new_story);
}
console.log('stories:');
console.dir(stories);
res.json(200, {
Data: stories
})
});
}
I have created a custom REST API to retrieve the stats of a given post on Medium, all you need is to send a GET request to my custom API and you will retrieve the stats as a Json abject as follows:
Request :
curl https://endpoint/api/stats?story_url=THE_URL_OF_THE_MEDIUM_STORY
Response:
{
"claps": 78,
"comments": 1
}
The API responds within a reasonable response time (< 2 sec), you can find more about it in the following Medium article.

file_get_contents('YOUTUBE API') returns cached/non-updated/old information

https://gdata.youtube.com/feeds/api/users/EXAMPLE/uploads?v=2&alt=jsonc
When visiting this url direct from a browser, it will return the correct data 100% of the time. If a video has been added, it's there, if a video has been deleted, it's gone.
When getting this data through file_get_contents('https://gdata.youtube.com/feeds/api/users/EXAMPLE/uploads?v=2&alt=jsonc');
The data seems to be cached or not updated/current data...
If you continue refreshing the page, it will show/hide new videos, as well as show/hide deleted videos for about 5-10 minutes, then it will be accurate.
The same thing happens when I get data using $.getJSON(), or $.ajax()...
Shouldn't the data be the same as when visiting the url in the browser?
I'm simply trying to get the most recent video uploaded by a user "EXAMPLE".
public function ajaxUpdateVideoFeed()
{
header("Content-type: application/json");
$json = file_get_contents('https://gdata.youtube.com/feeds/api/users/EXAMPLE/uploads?v=2&alt=jsonc');
$data = json_decode($json, TRUE);
$videoId = $data['data']['items'][0]['id'];
echo json_encode($videoId);die();
}
Try appending a random number to the end of you url call. https://gdata.youtube.com/feeds/api/users/EXAMPLE/uploads?v=2&alt=jsonc&r=RAND where RAND would be some arbitrary randomly generated number each time the url is called. Not sure if this will work for you, but it may be worth a try.
I'm having a similar issue. I'm trying to retrieve current state of a specific video via $.ajax() call, and the response data appears to stay cached. If I try the url from a browser the data is updated.
$.ajax({
url: 'https://gdata.youtube.com/feeds/api/videos/YouTubeID?v=2&alt=json'
type: "post",
dataType: 'json',
cache: false,
success: function(response, textStatus, jqXHR){
var ytState = response.entry.app$control.yt$state.name;
},
error: function(jqXHR, textStatus, errorThrown){
console.log( "The following error occured: "+ textStatus + errorThrown );
},
complete: function(){
}
});
I have tried json, jsonp, cached=false, appending a time stamp, appending my developer key to url, and no success.
**EDIT
By using POST vs GET in my ajax request it seems to eliminate my similar caching issue.
EDIT EDIT
Nevermind, I suck. Using POST is producing a 400 error.

Resources