Get Recent Media return deprecation_warning - instagram

I have spent hours for this issue, and it is driving me crazy.
I have access token and it works except for recent tagged media endpoints.
I called it using PHP:
$url = "https://api.instagram.com/v1/tags/omg/media/recent?access_token={ACCESS_TOKEN}";
$curl_connection = curl_init($url);
curl_setopt($curl_connection, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl_connection, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_connection, CURLOPT_SSL_VERIFYPEER, false);
//Data are stored in $data
$data = json_decode(curl_exec($curl_connection), true);
curl_close($curl_connection);
echo '<pre>';
echo print_r($data);
echo '</pre>';
And this is the result I got:
{"pagination": {"deprecation_warning": "next_max_id and min_id are deprecated for this endpoint; use min_tag_id and max_tag_id instead"}, "meta": {"code": 200}, "data": []}
While the other API seems to work fine except that. Is instagram tagged media API not working properly? Anyone is having this issue?

The status is 200, your request is OK. The problem is that your app still in sandbox mode. This will only return data from users that you've added on the sandbox.
From the Instagram website:
Instagram Platform and documentation update. Apps created on or after Nov 17, 2015 will start in Sandbox Mode and function on newly updated API rate-limits and behaviors. Prior to going Live, and being able to be used by people other than the developers of the app, these apps will have to go through a new review process. Please read the API documentation or the Change Log for more details.
Any app created before Nov 17, 2015 will continue to function until June 1, 2016. On that date, the app will automatically be moved to Sandbox Mode if it wasn't approved through the review process. The previous version of our documentation is still available here.
You will need to go through the app review process again to receive a new API Key, which involves providing a description of the api permissions you need and demonstrating how those permissions are used via a submitted video.
More details on http://instagram.com/developer

Because of Instagrams new update you can no longer get recent images by hashtag.
But i have made a workaround that can help you with your problem.
Check it out on Github
function getImagesByHashtag($hashtag, $ran_count= 16){
$crawl = file_get_contents("https://www.instagram.com/explore/tags/$hashtag/");
$crawl = (str_replace("window._sharedData = ", "", strstr($crawl, "window._sharedData =")));
$crawl = substr($crawl, 0, strpos($crawl, ';</script>'));
$crawl = json_decode($crawl);
$end_cursor = ($crawl->entry_data->TagPage[0]->tag->media->page_info->end_cursor);
$images = $crawl->entry_data->TagPage[0]->tag->media->nodes;
$more = array();
if($ran_count > 16) {
$count = $ran_count-16;
$url = "https://www.instagram.com/query/?q=ig_hashtag($hashtag)+%7B+media.after($end_cursor%2C+$count)+%7B%0A++count%2C%0A++nodes+%7B%0A++++caption%2C%0A++++code%2C%0A++++comments+%7B%0A++++++count%0A++++%7D%2C%0A++++date%2C%0A++++dimensions+%7B%0A++++++height%2C%0A++++++width%0A++++%7D%2C%0A++++display_src%2C%0A++++id%2C%0A++++is_video%2C%0A++++likes+%7B%0A++++++count%0A++++%7D%2C%0A++++owner+%7B%0A++++++id%0A++++%7D%2C%0A++++thumbnail_src%2C%0A++++video_views%0A++%7D%2C%0A++page_info%0A%7D%0A+%7D&ref=tags%3A%3Ashow";
$more = json_decode(file_get_contents($url));
$more = $more->media->nodes;
}
return array_merge($images, $more);
}

Related

Does Instagram Reels have an API for developers?

I cannot find an Instagram Reels related API. Does anyone know if there is one or if there will be one?
Currently the Facebook developer documentation does not mention anything about Instagram Reels.
https://developers.facebook.com/docs/instagram-api/overview/
UPDATED ANSWER:
Reels are now supported via the API; it became generally available on July 6, 2022. Please see https://developers.facebook.com/blog/post/2022/06/27/introducing-reels-apis-to-instagram-platform/.
ORIGINAL ANSWER:
In the Instagram API docs, under Limitations, it currently says "Reels are not supported."
Reels it is IG Media with type "VIDEO".
And you can fetch single "Reels" if you know his Facebook Media ID (It is not Media ID from instagram)
If reels published like stories you can get media's list from stories endpoint(GET graph.facebook.com/{ig-user-id}/stories). You will get array of medias' ids.
"data": [
{
"id": "{ig-media-id}"
},
...
]
}
Then you can fetch information from single media object endpoint (GET /{ig-media-id})
So at current moment you can get reels by api only if they published like story.
Anyway reels is not supported in some countries and you can see reels only from stories in this countries.
UPDATE
Reels also available when you fetch user media from business-discovery(GET {ig-user-id}?fields=business_discovery.username(instagramm_user_name){media{id,permalink,media_type,media_url}}
) or user media (GET /{ig-user-id}/media).
If media's permalink look likes https://www.instagram.com/reel/... and media_type VIDEO then is it reels.
Not sure, but I did some digging around an Instagram .ipa file and found these url scheme parameters.
instagram://reels_home
instagram://reels_share
Both of which if clicked on ios will take you to the reels feed. My intentions are to open the reels camera (or the story camera with the mode set to reels), but i guess currently we can only access the reels feed.
It seems they were included in the GET /{ig-user-id}/media and the GET {ig-user-id}?fields=business_discovery.username(instagramm_user_name) endpoints at the beginning but they removed them later. According to the docs they are not supported at the moment. Further confirmed in this bug report. It seems it is not the first time they include nodes that are not supposed to be included (IGTV and now reels).
Naa,
Instagram doesn't provide any API for Reels yet, since the reel feature is still not available in many countries but this going to be available soon.
So the question arises here, how we can get the reels data via API?
Well, the answer is you can't But! if you are in favour to do so some scraping thing then the answer is definitely Yes!
But How?
We all know scraping has lots of efforts, due to things get changed very frequent. and if you don't care about those below are sample PHP script to fetch reels data in JSON.
<?php
//!IMPORTANT
$sessionid = ["Cookie: sessionid=YOUR SESSION ID HERE"];
// REELS SHORT CODE FROM URL
$shortcode = null;
$response = [];
/**
* Get a web file (HTML, XHTML, XML, image, etc.) from a URL. Return an
* array containing the HTTP server response header fields and content.
*/
function get_web_page($url)
{
$user_agent = 'Mozilla/5.0 (Windows NT 6.1; rv:8.0) Gecko/20100101 Firefox/8.0';
$options = array(
CURLOPT_CUSTOMREQUEST => "GET", //set request type post or get
CURLOPT_POST => false, //set to GET
CURLOPT_USERAGENT => $user_agent, //set user agent
# CURLOPT_COOKIEFILE => "cookie.txt", //set cookie file
# CURLOPT_COOKIEJAR => "cookie.txt", //set cookie jar
CURLOPT_HTTPHEADER => $sessionid, // sending manually set cookie
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => false, // don't return headers
CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_ENCODING => "", // handle all encodings
CURLOPT_AUTOREFERER => true, // set referer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
CURLOPT_TIMEOUT => 120, // timeout on response
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
);
$ch = curl_init($url);
curl_setopt_array($ch, $options);
$content = curl_exec($ch);
$err = curl_errno($ch);
$errmsg = curl_error($ch);
$header = curl_getinfo($ch);
curl_close($ch);
$header['errno'] = $err;
$header['errmsg'] = $errmsg;
$header['content'] = $content;
return $header;
}
if ((isset($_GET['q'])) && !empty($_GET['q'])) {
$shortcode = $_GET['q'];
$reels_url = "https://www.instagram.com/p/$shortcode/?__a=1";
// read a web page and check for errors:
$result = get_web_page($reels_url);
if ($result['errno'] != 0) {
$response = json_encode(['error' => "bad url, timeout, redirect loop"]);
}
if ($result['http_code'] != 200) {
$response = json_encode(['error' => "no page, no permissions, no service"]);
}
if ($result['http_code'] === 200) {
$response = $result['content'];
}
}
// JSON OUTPUT OR ERROR HERE
header('Content-Type: application/json');
echo $response;
How to use this PHP script?
Save the above script in a PHP file e.g. fetch-reels.php and run it like
http://localhost/fetch-reels.php?q={SHORT-CODE}
Reels URL e.g.
https://www.instagram.com/p/COlKxQLAM11
https://www.instagram.com/reel/COlKxQLAM11/?igshid=12f6j9a1dfx2x
As mentioned earlier Instagram doesn't provide direct apis but you can take help of Instagrapi its really awesome and easy to use. Note : This Instagram Private API wrapper is in python.
Here's how to use it -
Install the lib :
python -m pip install instagrapi
Code
from instagrapi import Client
cl = Client()
#enter your username and password
cl.login('username', 'password')
#you can replace 10 with whatever amount of reels you want to fetch
reel = cl.explore_reels(amount = 10)
print(reel)
That's it !!!
Instagram just released reels support (Available to everyone from July 7th 2022).
More here
https://developers.facebook.com/docs/instagram-api/guides/content-publishing/
Instagram Reels API is now generally available:
https://developers.facebook.com/blog/post/2022/06/27/introducing-reels-apis-to-instagram-platform/
You can make a scheduled post. For example using JavaScript and uploading a video to the Reels API[1]:
const access_token = "Js82ks92jald"; // The access token given from FB
const instagram_user_id = "12345"; // The IG user's ID
const reelUrl = "https://www.website.com/reel.mp4";
const caption = "This is the best real ever #Reels4Real";
const postUrl = `https://graph.facebook.com/${instagram_user_id}/media?video_url=${encodeURIComponent(reelUrl)}&caption=${encodeURIComponent(caption)}&access_token=${access_token}&media_type=REELS&share_to_feed=true&thumb_offset=2000`;
const postOptions = {
method: "POST",
headers: {
"Content-Type": "application/json",
},
};
fetch(postUrl, postOptions)
.then((res) => res.json())
.then(json => console.log(json))
.catch(console.error);
Note the key fields of media_type=REELS, video_url, and caption.
[1] https://www.ayrshare.com/instagram-reels-api-how-to-post-videos-to-reels-using-a-social-media-api/
Update (14-July-2022): Meta (Facebook) launched support for Reels via their official Graph API. Read more about it here: https://developers.facebook.com/docs/instagram-api/reference/ig-user/media#reel-specifications
Meta just release Reels API for the Instagram Platform.
https://developers.facebook.com/blog/post/2022/06/27/introducing-reels-apis-to-instagram-platform/

Impossible to get an access_token for Instagram Basic Display API

I'm trying to get an access_token from Instagram to use their Basic Display API for a new app (simply display tweets on a webpage).
I followed these steps: https://developers.facebook.com/docs/instagram-basic-display-api/getting-started
But I'm stuck at Step 5: Exchange the Code for a Token
The cURL request always returns a 400 error with the message: "Matching code was not found or was already used"
However, after many tests, I got an access_token one time only, but it expired about one hour later. This seems to be very random.
The Instagram Basic Display API seems rather new. A while ago, I have used apps created on the https://www.instagram.com/developer/ website and it used to work. Now this site display this message:
UPDATE: Starting October 15, 2019, new client registration and permission review on Instagram API platform are discontinued in favor of the Instagram Basic Display API.
... with a link to the developers.facebook.com.
I tried using the command-line tool as per the original docs(https://developers.facebook.com/docs/instagram-basic-display-api/getting-started), but no luck...
Here's what to do in 3 easy steps:
First thing: Install Postman https://www.postman.com/downloads/
Make a POST request to https://api.instagram.com/oauth/access_token with the parameters in the body, NOT the params. Make sure that the x-www-form-urlencoded option is enable.
You should now get a status of 200 OK and a response with both access_token and user_id.
{
"access_token": "IGQVJYUXlDN...",
"user_id": 17841400...
}
Happy days!!
See the screenshot for the correct settings:
I just succeeded by removing the trailing #_ at the end in the code they give you. Not sure if that was your issue?
https://developers.facebook.com/support/bugs/436837360282557/
I had this problem when i was trying implement a application.
My problem was the code generated when you allow the permissions.
Try to remove #_ from the end of the generated code and try generate the token again
Generated code example:
AQBvrqqBJJTM49U1qTQWRMD96oRyMR3B_04JSfjc-nUIi0iGbSc3x_EceggQi9IyG3B3Rj3ocreMThQoPJbPpeXLUM4exJMy4o01fXcRtT_I9NovaNAqmWSneFt3MYv_k7ifAUUeMlC050n5xnjQP6oAvDBfCFQvTdrFaR95-5i71YsfQlmjYWDG6fcWRvOB9nqr6J9mbGMXMi9Y4tKlSfElaYm0YKRijZQDG2B5PaxQ8A #_
Generated code edited:
AQBvrqqBJJTM49U1qTQWRMD96oRyMR3B_04JSfjc-nUIi0iGbSc3x_EceggQi9IyG3B3Rj3ocreMThQoPJbPpeXLUM4exJMy4o01fXcRtT_I9NovaNAqmWSneFt3MYv_k7ifAUUeMlC050n5xnjQP6oAvDBfCFQvTdrFaR95-5i71YsfQlmjYWDG6fcWRvOB9nqr6J9mbGMXMi9Y4tKlSfElaYm0YKRijZQDG2B5PaxQ8A
I was also having the same problem, I solved clearing the cache, coockie and other browser data.
Then I made a new request.
Try it, it worked with me.
I found the solution.
The direct uri must the same as you use in the beginning.
ex. You use
www.abc.com/auth
to get the code. When you exchange the token the redirect_uri must be the same as
www.abc.com/auth
I was using the old Instagram API as well. I had to change a few things to make my code work on the new API. Not sure what you're using, this is how I did it with PHP.
$url = 'https://api.instagram.com/oauth/access_token';
$fields = array(
'app_id' => 'YOUR_APP_ID',
'app_secret' => 'YOUR_APP_SECRET_ID',
'grant_type' => 'authorization_code',
'redirect_uri' => 'YOUR_REDIRECT_URL',
'code' => $code
);
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close($ch);
//get the access token from the string sent from Instagram
$splitString = explode('"access_token":', $result);
$removeRest = explode(',', $splitString[1]);
$withSpace = str_replace('"','', $removeRest[0]);
$access_token = str_replace(' ','', $withSpace);
I am using PHP but without using any lib. Maybe this one help you.
curl.php
class InstagramApi
{
public function GetAccessToken($client_id, $redirect_uri, $client_secret, $code) {
$url = 'https://api.instagram.com/oauth/access_token';
$curlPost = 'app_id='. $client_id . '&redirect_uri=' . $redirect_uri . '&app_secret=' . $client_secret . '&code='. $code . '&grant_type=authorization_code';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$data = json_decode(curl_exec($ch), true);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if($http_code != '200')
throw new Exception('Error : Failed to receieve access token');
return $data;
}
index.php
include "curl.php";
include "instagram_keys.php"; // holding APP ID, SECRET KEY, REDIRECT URI
$instagram_ob = new InstagramApi();
$insta_data = $instagram_ob->GetAccessToken(INSTAGRAM_CLIENT_ID, INSTAGRAM_REDIRECT_URI, INSTAGRAM_CLIENT_SECRET, $_GET['code']);
echo $insta_data['access_token'];
echo $insta_data['user_id'];
NOTE: $_GET['code'] is required and you should know how to get the code. Read here

How can I capture Direct Message via Instagram API?

I searched the api instagram if there is any method to return the direct messages, and found nothing. Can you tell if there is something, or if it is not possible? Instagram does not offer? Or I can do programmatically?
I need capture direct message, is possible?
There is no Instagram API for direct messages, and since it's been almost 4 years now, I guess there won't be any. You may be able to use the Instagram node.js Private API library or the Instagram PHP Private API library.
I have to warn you though, that I did try to use the PHP library and Instagram didn't allow sending of direct messages, no matter how much hacking I tried to make it work. But maybe this was just me...
If you are able to use node.js, it seems that Thread.configureText can be used for sending direct messages on the node.js library.
string status_DM = string.Empty;
string Url_DirectMessage = "https://i.instagram.com/api/v1/direct_v2/threads/broadcast/text/";
string guid = obj_InstaUser.guid;
string userID = string.Empty; // put user id to whom you want to send message
string responce = obj_new.getHtmlfromUrl(new Uri("https://www.instagram.com/" + username));
if(string.IsNullOrEmpty(userID))
{
userID = Utils.getBetween(responce, "profilePage_", "}").Replace(" ","").Replace("\"","");
}
try
{
string postData = "recipient_users=%5B%5B%22" + userID + "%22%5D%5D&client_context=%22" + guid + "%22&text=" + text + "&thread_ids=%5B%220%22%5D";
try
{
string Finalresult = obj_InstaUser.globusHttpHelperMobile.postFormDataMobileLogin_Directmessage(new Uri(Url_DirectMessage), postData);
status_DM = "Success";
}
catch (Exception ex)
{
status_DM = "Fail";
}
}
catch(Exception ex)
{
}
you can use instagram-messager-api now.
the page you intended to receive its DMs must have 1k-100k followers.
As of August 16, 2021 you can send and receive IG messages through the official API.
Here is a quote from the official "FACEBOOK for developers" website:
"All Instagram business accounts can connect to Messenger API for Instagram as of August 16, 2021." (Instagram Messaging)
Use Instagram private API. Through this you are able to send Direct message.
I did in C# and that worked perfectly. (Direct message and upload post as well.)

Crm 2011 test the crm4 metadata endpoint

I'm having trouble with a third party product that suppose to connect to a CRM2011 CRM4 metadata endpoint. Basically the product is AVAYA EMC version 6.3.1, I'm aware that this specific version is not compatible with CRM2011, but the documents released by the company are not really clear if this involved the CRM2011 CRM4 metadata endpoint.
Long story short, there is this plugin ASMSCRMGuiPlugin.dll that is not able to authenticate the metadata endpoint provided as:
(this should be the metadata attribute endpoint for crm4)
http://server/MSCRMServices/2007/MetadataService.asmx
to confirm that the endpoint was working i wrote a console that was querying the metadata endpoint on that address with the provided credentials (the ones that in the plugin were not working), and i was able to retrieve all the contacts attributes.
Now I'm not a crm4 developer and I entered the CRM world when 2011 was already established, is there any setting on CRM2011 side that I have to tweak to allow this component to work?
I will append the code i used to connect to the metadata endpoint. Is there any other way for me to prove that is not a crm configuration issue? Anyone out there ever managed to configure AVAYA EMC6.3.1 with CRM 2011, using the endpoint crm4?
CrmAuthenticationToken token = new CrmAuthenticationToken();
token.OrganizationName = "Org";
token.AuthenticationType = 0;
MetadataService mdSevice = new MetadataService();
mdSevice.Credentials = new System.Net.NetworkCredential("User", "Passw", "domain");
mdSevice.Url = "http://org/MSCRMServices/2007/MetadataService.asmx";
mdSevice.UseDefaultCredentials = false;
mdSevice.CrmAuthenticationTokenValue = token;
RetrieveEntityRequest entityRequest = new RetrieveEntityRequest();
entityRequest.RetrieveAsIfPublished = false;
entityRequest.LogicalName = EntityName.contact.ToString();
entityRequest.EntityItems = EntityItems.IncludeAttributes;
RetrieveEntityResponse entityResponse = (RetrieveEntityResponse)mdSevice.Execute(entityRequest);
Console.WriteLine("Retrieved fields: ");
EntityMetadata retrievedEntityMetadata = entityResponse.EntityMetadata;
foreach (AttributeMetadata att in retrievedEntityMetadata.Attributes)
{
{
Console.WriteLine(att.LogicalName);
}
}

Sharepoint claims based vs classic authentication

I have 2 sharepoint sites running out of one sharepoint installation. One site has claims based enabled and the other has classic auth enabled. Both sites also both use Kerberos.
I am using ManifoldCF to connect to these sites to extract the all content as well as the permissions. The ManifoldCF connector connects to the site with classic auth enabled and works as expected. However, trying to crawl the claims based site generates a 401 unauthorised error.
There is a web service package supplied with ManifoldCF that is accessed called MCPermissions.asmx. This file contains the following block of code which sets the user's credentials:
try
{
// Only handle requests for "item". Send all other requests to the SharePoint web service.
if (objectType.Equals(itemType))
{
retVal = GetItemPermissions(objectName);
}
else
{
ServicePointManager.ServerCertificateValidationCallback +=
new RemoteCertificateValidationCallback(ValidateCertificate);
using (SPPermissionsService.Permissions service = new SPPermissionsService.Permissions())
{
service.Url = SPContext.Current.Web.Url + "/_vti_bin/Permissions.asmx";
service.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
retVal = service.GetPermissionCollection(objectName, objectType);
}
}
}
catch (SoapException soapEx)
{
throw soapEx;
}
catch (Exception ex)
{
SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("MCPermissions.asmx", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, "Error: "+ex.Message+"; SPContext.Current.Web.Url='"+SPContext.Current.Web.Url+"'", ex.StackTrace);
throw RaiseException(ex.Message, "1000", ex.Source);
}
This code is accessed via ManifoldCF correctly, but it seems its the request made in the plugin to /_vti_bin/Permissions.asmx that is causing the 401 issue.
I have tried setting pre defined credentials in the code above using NetworkCredential
("username", "password", "domain") but no luck.
Example:
string webUrl = SPContext.Current.Web.Url;
NetworkCredential myCredentials = new NetworkCredential("DOMAIN\\user", "mypassword", "DOMAIN");
CredentialCache credCache = new CredentialCache();
credCache.Add(new Uri(webUrl), "Negotiate", myCredentials);
service.Url = webUrl + "/_vti_bin/Permissions.asmx";
service.Credentials = credCache;
With the claims based authentication, the username that i enter into ManfoldCF or in the browser authentication gets changed from the regular \ format to the claims username format (e.g. i:0#.w||/).
Does anybody know why claims based would be causing the 401 issue where the classic authentication does not?
Turns out this was a bug with the ManifoldCF 1.2 release. It has been fixed in newer versions.

Resources