How do I search across all sites using Microsoft Graph? - sharepoint

I want to develop an application that displays a search result. For testing I uploaded a couple of files to the default document library in the root site. I can see these files with the following request:
https://graph.microsoft.com/v1.0/sites/root/drive/root/search(q='Test')
However, one of the requirements is that the query should match files regardless of in which site they are stored. As I understand the documentation I should use something like this:
https://graph.microsoft.com/v1.0/me/drive/search(q='Test')
The query is the same as in the first example but the results are empty.
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(driveItem)",
"value": []
}

As of today there is no endpoint to search across all site collections from the Microsoft Graph. You can upvote the request here

Related

What is the best way to retrieve SharePoint files' '#microsoft.graph.downloadUrl' from MSGraph when using the search query?

I'm creating an application that gets SharePoint files and uses the downloadURL in various places, I'm struggling with finding an efficient way of searching files whilst also being able to get the information I need in the response.
To search the SharePoint files I am using this endpoint:
https://graph.microsoft.com/v1.0/shares/{DriveID}/driveitem/search(q='{SearchQuery}')
I've looked around and it seems that when using the search criteria MSGraph doesn't retrieve instance properties like '#microsoft.graph.downloadUrl'. My current thought for a solution to this would be to retrieve the ItemID and Parent DriveID of each file from the search and then use batching to call the Graph for each file from the search.
With the limit on batching being so small, and searches being able to retrieve hundreds of files this seems like a bad solution as we would have to use many different batch calls to the graph per search.
Are there any better solutions to retrieving the downloadURL when using the search function in Microsoft Graph?
According to my research and testing, there is no way to use search query to retrieve #microsoft.graph.downloadUrl.Search API can retrieve only properties but not instance attributes like "#microsoft.graph.downloadUrl".
We can only use the GET /drive/items/{item-ID}?select=id,#microsoft.graph.downloadUrl to retrieve the download URL of the file.
For reference:
https://learn.microsoft.com/en-us/graph/api/driveitem-get-content?view=graph-rest-1.0&tabs=http#example-1

Sharepoint REST Api list not found when it's still available under the site

I am using Microsoft.SharePointOnline.CSOM. Authentication works fine and I can get the following api to work fine.
https://company.sharepoint.com/sites/{site}/_api/lists
This gives me results and that shows my integration/authentication works fine.
Now I have a list in this site. To query the list I have tried below;
https://company.sharepoint.com/sites/{site}/_api/lists(guid'{guid}')/items
https://company.sharepoint.com/sites/{site}/_api/lists/getbytitle('{list-name}')/items
In both cases it returns 404. But the list exists and list name does NOT have any spaces (so no encoding is needed). The GUID is also confirmed to be accurate.
Does it take some time to reflect the changes for the newly created list to appear in api results?
Are their any configurations that needs to be done to the list (like allow to be queried via api)?
You missed web in the url.
It shuoud be /_api/web/lists/getbytitle('{list-name}')

Get a file from SharePoint Online using Microsoft Graph API

While learning graph API, I was trying to get a file from a SharePoint document library using Microsoft Graph API.
I first tried by accessing files in Documents from https://graph.microsoft.com/v1.0/sites/tenant.sharepoint.com
by doing this GET request:
https://graph.microsoft.com/v1.0/sites/tenant.sharepoint.com/drive/root:/Test:/children
Everything worked great, I then tried accessing documents from another site within the same tenant. I told my self it was the same pathway while following the Microsoft docs.
I first did a test request to be sure i can first access to my site; here is what I did;
https://graph.microsoft.com/v1.0/sites/tenant.sharepoint.com:/sites/ObserveTestSite
On executing that query i got a 200 OK response.
Secondly I then tried accessing the drive Documents here is what i did;
https://graph.microsoft.com/v1.0/sites/tenant.sharepoint.com:/sites/ObserveTestSite:/drive
again everything worked fine.
I then used the root relation followed by the name of the directory and then the children relation; and this was my request:
https://graph.microsoft.com/v1.0/sites/tenant.sharepoint.com:/sites/ObserveTestSite:/drive/root:/Test:/children
But while executing that, I'm getting Bad Request - 400 - 96ms
Please help.
Thanks
I have the same issue when using site relative url to specify the specific site.
Now I'm using siteId instead and everything works as expected:
https://graph.microsoft.com/v1.0/sites/zheguo.sharepoint.com,91a47a59-db5e-4d17-a689-479ee8905533,274459c9-4c96-42bf-9b96-838ffa387aaa/drive/root:/X:/children

Posting Blog Entries to a Community

Our tool is submitting blog entries to the idation blog for a configured community by using the Connections API.
Therefore, I use the following workflow, given only a community ID:
1) query /blogs/api/blogs?commUuid=<ID_HERE>&blogType=ideationblog
2) retrieve the link to the communities ideation blog from the xml result of aboves query. the xPath for this is "/app:service/app:workspace/app:collection[a:category[#term='entries']][1]/#href"
3) post the created blog entry payload to this url.
This all worked fine in our environment. However, when I deployed this at a customer, it did not work anymore. The url from the first step returns an empty xml document, and the following steps thus cannot be executed. I tried to query different urls on the customers server like /blogs/{homepageHandle}/api/blogs?commUuid=&blogType=ideationblog which work fine, however the query to the api service document above is the only one which contains the collection element with the link I need.
Is there any other API call I can do, to get this url? Do you know of any reason, why the call is working just fine in our environment, but fails at the customer? Might this be an access rights problem?
I am aware, that I could probably just create a url like "blogs//api/entries" and post to it, however I would prefer the above way, since I only have the communityUuid configured, and also because it is exactly the way that the API Documentation describes:
http://www-10.lotus.com/ldd/appdevwiki.nsf/xpDocViewer.xsp?lookupName=IBM+Connections+4.5+API+Documentation#action=openDocument&res_title=Creating_blog_posts_ic45&content=pdcontent
ServiceDoc -> Collection -> href
UPDATE:
This might be a problem with the SBT really. My assumption, that an empty xml document was returned was wrong, it is rather that calls via the SBT Endpoint classes are returning null.
Endpoint endpoint = EndpointFactory.getEndpoint("connections");
Object result = endpoint.xhrGet("/blogs/api"); // also tried for /blogs/<homepage>/api
When I again tried those URLs in the Browser, I got the complete results. Problem with all this is, that I can neither reproduce this in our own environment nor am I able to debug this at the customer. I tried to catch possible exceptions from this, but none are thrown. It's just that the result is null.
To clarify: The same requests work perfectly fine in our own (Connections 4.0) environment, and also from the browser at the customer. I am of course using the same user to authenticate as well in the browser as in the API calls.
endpoint.isAuthenticationValid();
also returns true, so seemingly no problem there...
I have long ago given up trying to follow the IBM documented REST API instructions (not least of all because it always ends in a myriard of REST requests just to get to the URL I need to send my request to).
I tried both your URLs (/blogs/api/blogs?commUuid=... and /blogs/<homepage>/api/blogs...) against all our Connections 4.5 systems, but although I do get an xml document back it doesn't contain a reference to the ideationblog anywhere (and yes, I made sure to quest against a Community that does contain an ideation blog).
This is a dirty workaround, which you mentioned you did not want to do, but which I do use because the documented way doesn't work:
To post blog entries, you need to POST against
/blogs/<bloghandle>/api/entries
To find out the handle (<snx:handle>) of the ideation blog in your community, you can do the following:
1.) Get the widgets-feed for the community: /communities/service/atom/community/widgets?communityUuid=...
2.) Navigate to the entry of the Ideation Blog widget: <snx:widgetDefId>IdeationBlog</snx:widgetDefId>.
Unless someone in your customer system has messed with the widgets-config.xml, the widgetDefId will be IdeationBlog.
3.) Take the <snx:widgetInstanceId> text of the Ideation Blog entry.
That is the handle of your ideation blog. (Yes, community ideation blogs are created with the widgetInstanceId of the Ideation Blog widget as handle. Normal blogs are created with some mashup of their title as handle). You can now construct the URL to post the entries to.

Grab instagram photo based on hashtags

I am new to instagram and i am tasked to program an application to grab instagram photo uploads based on a certain hashtag. Meaning if the application is started and searching for the hashtag "#awesomeevent" any one that uploads a photo with that hashtags it will automatically be stored into our database.
The application should work something similar to http://statigr.am/tag/ but instead displaying the photos it should store the photos into the database.
What is the process of doing this. Any tutorials that has this from start to end. Even covering how to start creating a instagram app from scratch. any help would be greatly appreciated.
Thanks
Things we developers often overlook are the API Terms and Conditions. I've been there myself.
API TERMS OF USE
Before you start using the API, we have a few guidelines that we'd like to tell you about. Please make sure to read the full API Terms of Use
Terms of Use. Here's what you'll read about:
Instagram users own their images. It's your responsibility to make sure that you respect that right.
You cannot use the Instagram name in your application.
You cannot use the Instagram API to crawl or store users' images without their express consent.
You cannot replicate the core user experience of Instagram.com
Do not abuse the API. Too many requests too quickly will get your access turned off
However, a part in the terms also states that:
You shall not cache or store any Instagram user photos other than for reasonable periods in order to provide the service you are
providing to Instagram users.
Hope that's a start before you actually get coding and storing images.
API Terms of Use: http://instagram.com/about/legal/terms/api/
API: http://instagram.com/developer/
For starter, you should consult to instagram api.
As for the specific api you will need is:
/tags/tag-name/media/recent
For example, if you want to look for images from tag #awesomeevent, you will do an api query to:
https://api.instagram.com/v1/tags/awesomeevent/media/recent?access_token=ACCESS-TOKEN
I would have a look at the two libraries Instagram provides. The ruby library is at https://github.com/Instagram/instagram-ruby-gem and the python library is at https://github.com/Instagram/python-instagram
They both seem to have examples to get you started if you're programming with either libraries.
As far as the storing issue goes, could you instead store the URL address of the images instead of the actual images themselves? The API returns JSON information of which the URL of the images are returned.
Hope that helps.
You can use the below ruby script to retrieve the images and save them to a file. You can then either reference the file within the database or replace the last block with code for your particular database implementation. Without knowing your database type and schema, no one can tell you how to add something to it.
require "instagram"
require "restclient"
Instagram.configure do |config|
config.client_id = INSTAGRAM_CLIENT_ID
config.client_secret = INSTAGRAM_CLIENT_SECRET
end
instagram_client = Instagram.client(:access_token => INSTAGRAM_ACCESS_TOKEN)
tags = instagram_client.tag_search('cat')
urls = Array.new
for media_item in instagram_client.tag_recent_media(tags[0].name)
urls << media_item.images.standard_resolution.url
end
urls.each_with_index do |url, idx|
image = RestClient.get(url)
path = Dir.pwd + "/#{idx}.jpg"
File.open(path, 'w') {|f| f.write(image) }
end

Resources