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/
I have a test in NodeJS that downloads a file from a website using Google Chrome on the cloud (BrowserStack). I am trying to download the file to a directory in my project. I understand I have to set this via Chrome Options but no answers posted here to seem work.
Could someone please share an example how this is done using NodeJS? Below is one example I have tried that doesn't work.
module.exports.createChromeDriver = async function () {
if (parameters.runOnCloud === true) {
await filesDirectory.createAppDirIfRequired(paths.tempDir, paths.downloadDirName);
let capabilities = {
'name' : parameters.report,
'browserName' : 'Chrome',
'browser_version' : '79.0',
'os' : 'OS X',
'os_version' : 'Mojave',
'resolution' : '1920x1080',
'browserstack.user' : credentials.browserstack.user,
'browserstack.key' : credentials.browserstack.key,
'browserstack.local' : 'true',
'browserstack.localIdentifier': parameters.bsLocalIdentifier,
'browserstack.networkLogs' : 'false',
}
if (parameters.tests === "wallet-web") {
capabilities['browserstack.networkLogs'] = 'true';
}
let options = new chrome.Options();
const prefs = {'download.default_directory' : paths.downloadsDir};
options.addArguments('prefs', prefs);
options.merge(capabilities);
let driver = await new Builder().
usingServer('http://hub-cloud.browserstack.com/wd/hub').
withCapabilities(capabilities).
build();
return driver;
}
You have a mistake when set the capabilities. capabilities does not include download option, because merge(options.merge(capabilities);) operator means , merge capabilities in to options.
You only need change one line:
withCapabilities(capabilities).
to
withCapabilities(options.toCapabilities()).
If it not working, I think you have to change the option variable, like:
const options = new chrome.Options();
options.setUserPreferences({
'download.default_directory': paths.downloadsDir,
'download.prompt_for_download': false, // Maybe
});
options.merge(capabilities);
Update:
The final way, you can try use
capabilities['goog:chromeOptions'] = options;
instead of
options.merge(capabilities);
I am building a php application which needs to post the user uploaded picture directly to Instagram, but after a quick search i found that there is no such function in the API :( and it feels weird... because they should provide one. I am not sure if there is any other way (except the apps for android and iOS) to upload picture using php. Kindly give me any sort of idea if there is any possibility.
I also read this ,
How do I share a link and photo with Instagram using PHP
Update:
Instagram are now banning accounts and removing the images based on this method. Please use with caution.
It seems that everyone who has answered this question with something along the lines of it can't be done is somewhat correct. Officially, you cannot post a photo to Instagram with their API. However, if you reverse engineer the API, you can.
function SendRequest($url, $post, $post_data, $user_agent, $cookies) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://i.instagram.com/api/v1/'.$url);
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
if($post) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
}
if($cookies) {
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
} else {
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
}
$response = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return array($http, $response);
}
function GenerateGuid() {
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
mt_rand(0, 65535),
mt_rand(0, 65535),
mt_rand(0, 65535),
mt_rand(16384, 20479),
mt_rand(32768, 49151),
mt_rand(0, 65535),
mt_rand(0, 65535),
mt_rand(0, 65535));
}
function GenerateUserAgent() {
$resolutions = array('720x1280', '320x480', '480x800', '1024x768', '1280x720', '768x1024', '480x320');
$versions = array('GT-N7000', 'SM-N9000', 'GT-I9220', 'GT-I9100');
$dpis = array('120', '160', '320', '240');
$ver = $versions[array_rand($versions)];
$dpi = $dpis[array_rand($dpis)];
$res = $resolutions[array_rand($resolutions)];
return 'Instagram 4.'.mt_rand(1,2).'.'.mt_rand(0,2).' Android ('.mt_rand(10,11).'/'.mt_rand(1,3).'.'.mt_rand(3,5).'.'.mt_rand(0,5).'; '.$dpi.'; '.$res.'; samsung; '.$ver.'; '.$ver.'; smdkc210; en_US)';
}
function GenerateSignature($data) {
return hash_hmac('sha256', $data, 'b4a23f5e39b5929e0666ac5de94c89d1618a2916');
}
function GetPostData($filename) {
if(!$filename) {
echo "The image doesn't exist ".$filename;
} else {
$post_data = array('device_timestamp' => time(),
'photo' => '#'.$filename);
return $post_data;
}
}
// Set the username and password of the account that you wish to post a photo to
$username = 'ig_username';
$password = 'ig_password';
// Set the path to the file that you wish to post.
// This must be jpeg format and it must be a perfect square
$filename = 'pictures/test.jpg';
// Set the caption for the photo
$caption = "Test caption";
// Define the user agent
$agent = GenerateUserAgent();
// Define the GuID
$guid = GenerateGuid();
// Set the devide ID
$device_id = "android-".$guid;
/* LOG IN */
// You must be logged in to the account that you wish to post a photo too
// Set all of the parameters in the string, and then sign it with their API key using SHA-256
$data ='{"device_id":"'.$device_id.'","guid":"'.$guid.'","username":"'.$username.'","password":"'.$password.'","Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"}';
$sig = GenerateSignature($data);
$data = 'signed_body='.$sig.'.'.urlencode($data).'&ig_sig_key_version=4';
$login = SendRequest('accounts/login/', true, $data, $agent, false);
if(strpos($login[1], "Sorry, an error occurred while processing this request.")) {
echo "Request failed, there's a chance that this proxy/ip is blocked";
} else {
if(empty($login[1])) {
echo "Empty response received from the server while trying to login";
} else {
// Decode the array that is returned
$obj = #json_decode($login[1], true);
if(empty($obj)) {
echo "Could not decode the response: ".$body;
} else {
// Post the picture
$data = GetPostData($filename);
$post = SendRequest('media/upload/', true, $data, $agent, true);
if(empty($post[1])) {
echo "Empty response received from the server while trying to post the image";
} else {
// Decode the response
$obj = #json_decode($post[1], true);
if(empty($obj)) {
echo "Could not decode the response";
} else {
$status = $obj['status'];
if($status == 'ok') {
// Remove and line breaks from the caption
$caption = preg_replace("/\r|\n/", "", $caption);
$media_id = $obj['media_id'];
$device_id = "android-".$guid;
$data = '{"device_id":"'.$device_id.'","guid":"'.$guid.'","media_id":"'.$media_id.'","caption":"'.trim($caption).'","device_timestamp":"'.time().'","source_type":"5","filter_type":"0","extra":"{}","Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"}';
$sig = GenerateSignature($data);
$new_data = 'signed_body='.$sig.'.'.urlencode($data).'&ig_sig_key_version=4';
// Now, configure the photo
$conf = SendRequest('media/configure/', true, $new_data, $agent, true);
if(empty($conf[1])) {
echo "Empty response received from the server while trying to configure the image";
} else {
if(strpos($conf[1], "login_required")) {
echo "You are not logged in. There's a chance that the account is banned";
} else {
$obj = #json_decode($conf[1], true);
$status = $obj['status'];
if($status != 'fail') {
echo "Success";
} else {
echo 'Fail';
}
}
}
} else {
echo "Status isn't okay";
}
}
}
}
}
}
Just copy and paste the code above in your text editor, change the few variables accordingly and VOILA! I wrote an article about this and I've done it many times. See a demo here.
If you read the link you shared, the accepted answer is:
You cannot post pictures to Instagram via the API.
Instagram has now said:
Now you can post your content using Instagram's APIs (New) effects from
26th Jan 2021!
https://developers.facebook.com/blog/post/2021/01/26/introducing-instagram-content-publishing-api/
Instagram now allows businesses to schedule their posts, using the new Content Publishing Beta endpoints.
https://developers.facebook.com/blog/post/2018/01/30/instagram-graph-api-updates/
However, this blog post - https://business.instagram.com/blog/instagram-api-features-updates - makes it clear that they are only opening that API to their Facebook Marketing Partners or Instagram Partners.
To get started with scheduling posts, please work with one of our
Facebook Marketing Partners or Instagram Partners.
This link from Facebook - https://developers.facebook.com/docs/instagram-api/content-publishing - lists it as a closed beta.
The Content Publishing API is in closed beta with Facebook Marketing
Partners and Instagram Partners only. We are not accepting new
applicants at this time.
But this is how you would do it:
You have a photo at...
https://www.example.com/images/bronz-fonz.jpg
You want to publish it with the hashtag "#BronzFonz".
You could use the /user/media edge to create the container like this:
POST graph.facebook.com
/17841400008460056/media?
image_url=https%3A%2F%2Fwww.example.com%2Fimages%2Fbronz-fonz.jpg&
caption=%23BronzFonz
This would return a container ID (let's say 17889455560051444), which you would then publish using the /user/media_publish edge, like this:
POST graph.facebook.com
/17841405822304914/media_publish
?creation_id=17889455560051444
This example from the docs.
I tried using IFTTT and many other services but all were doing things or post from Instagram to another platform not to Instagram. I read more to found Instagram does not provide any such API as of now.
Using blue stack is again involving heavy installation and doing things manually only.
However, you can use your Google Chrome on the desktop version to make a post on Instagram. It needs a bit tweak.
Open your chrome and browse Instagram.com
Go to inspect element by right clicking on chrome.
From top right corener menu drop down on developer tools, select more tool.
Further select network conditions.
In the network selection section, see the second section there named user agent.
Uncheck select automatically, and select chrome for Android from the list of given user agent.
Refresh your Instagram.com page.
You will notice a change in UI and the option to make a post on Instagram.
Your life is now easy.
Let me know an easier way if you can find any.
I wrote on https://www.inteligentcomp.com/2018/11/how-to-upload-to-instagram-from-pc-mac.html about it.
Working Screenshot
For anyone who is searching for a solution about posting to Instagram using AWS lambda and puppeteer (chrome-aws-lambda). Noted that this solution allow you to post 1 photo for each post only. If you are not using lambda, just replace chrome-aws-lambda with puppeteer.
For the first launch of lambda, it is normal that will not work because instagram detects “Suspicious login attempt”. Just goto instagram page using your PC and approve it, everything should be fine.
Here's my code, feel free to optimize it:
// instagram.js
const chromium = require('chrome-aws-lambda');
const username = process.env.IG_USERNAME;
const password = process.env.IG_PASSWORD;
module.exports.post = async function(fileToUpload, caption){
const browser = await chromium.puppeteer.launch({
args: [...chromium.args, '--window-size=520,700'],
defaultViewport: chromium.defaultViewport,
executablePath: await chromium.executablePath,
headless: false,
ignoreHTTPSErrors: true,
});
const page = await browser.newPage();
await page.setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) FxiOS/7.5b3349 Mobile/14F89 Safari/603.2.4');
await page.goto('https://www.instagram.com/', {waitUntil: 'networkidle2'});
const [buttonLogIn] = await page.$x("//button[contains(., 'Log In')]");
if (buttonLogIn) {
await buttonLogIn.click();
}
await page.waitFor('input[name="username"]');
await page.type('input[name="username"]', username)
await page.type('input[name="password"]', password)
await page.click('form button[type="submit"]');
await page.waitFor(3000);
const [buttonSaveInfo] = await page.$x("//button[contains(., 'Not Now')]");
if (buttonSaveInfo) {
await buttonSaveInfo.click();
}
await page.waitFor(3000);
const [buttonNotificationNotNow] = await page.$x("//button[contains(., 'Not Now')]");
const [buttonNotificationCancel] = await page.$x("//button[contains(., 'Cancel')]");
if (buttonNotificationNotNow) {
await buttonNotificationNotNow.click();
} else if (buttonNotificationCancel) {
await buttonNotificationCancel.click();
}
await page.waitFor('form[enctype="multipart/form-data"]');
const inputUploadHandle = await page.$('form[enctype="multipart/form-data"] input[type=file]');
await page.waitFor(5000);
const [buttonPopUpNotNow] = await page.$x("//button[contains(., 'Not Now')]");
const [buttonPopUpCancel] = await page.$x("//button[contains(., 'Cancel')]");
if (buttonPopUpNotNow) {
await buttonPopUpNotNow.click();
} else if (buttonPopUpCancel) {
await buttonPopUpCancel.click();
}
await page.click('[data-testid="new-post-button"]')
await inputUploadHandle.uploadFile(fileToUpload);
await page.waitFor(3000);
const [buttonNext] = await page.$x("//button[contains(., 'Next')]");
await buttonNext.click();
await page.waitFor(3000);
await page.type('textarea', caption);
const [buttonShare] = await page.$x("//button[contains(., 'Share')]");
await buttonShare.click();
await page.waitFor(3000);
return true;
};
// handler.js
await instagram.post('/tmp/image.png', '#text');
it must be local file path, if it is url, download it to /tmp folder first.
Updated:
Instagram is blocking all suspicious login attempt now unless you approve it manually every time it executed. To solve that, better to save your cookies as json and import it to puppeteer.
For users who find this question, you can pass photos to the instagram sharing flow (from your app to the filters screen) on iPhone using iPhone hooks: http://help.instagram.com/355896521173347 Other than that, there is currently no way in version 1 of the api.
If it has a UI, it has an "API". Let's use the following example: I want to publish the pic I use in any new blog post I create. Let's assume is Wordpress.
Create a service that is constantly monitoring your blog via RSS.
When a new blog post is posted, download the picture.
(Optional) Use a third party API to apply some overlays and whatnot to your pic.
Place the photo in a well-known location on your PC or server.
Configure Chrome (read above) so that you can use the browser as a mobile.
Using Selenium (or any other of those libraries), simulate the entire process of posting on Instagram.
Done. You should have it.
There is no API to post photo to instagram using API , But there is a simple way is that install google extension " User Agent " it will covert your browser to android mobile chrome version . Here is the extension link https://chrome.google.com/webstore/detail/user-agent-switcher/clddifkhlkcojbojppdojfeeikdkgiae?utm_source=chrome-ntp-icon
just click on extension icon and choose chrome for android and open Instagram.com
In Firefox extension, we can do:
var _prefService = Components.classes["#mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
var httpHandler = Cc["#mozilla.org/network/protocol;1?name=http"].getService(Ci.nsIHttpProtocolHandler);
setCharPref("general.useragent.override",httpHandler.userAgent + " OurUAToken/1.0");
To add "OurUAToken/1.0" at the end of User-Agent string.
How can we duplicate this behavior in Google Chrome?
Not sure if someone still looking for the solution but the chrome.webRequest API suggested earlier is quite stable now.
chrome.webRequest.onBeforeSendHeaders.addListener(
function (details) {
for (var i = 0; i < details.requestHeaders.length; ++i) {
if (details.requestHeaders[i].name === 'User-Agent') {
details.requestHeaders[i].value = details.requestHeaders[i].value + ' OurUAToken/1.0';
break;
}
}
return { requestHeaders: details.requestHeaders };
},
{ urls: ['<all_urls>'] },
['blocking', 'requestHeaders']
);
One of the chrome extensions, Requestly already has similar implementation to allow overriding User Agent string for any website opened in the browser.
For more info, please visit blog: https://medium.com/#requestly_ext/switching-user-agent-in-browser-f57fcf42a4b5
The extension is also available for Firefox. Visit http://www.requestly.in for details.
You can use the WebRequest api: http://code.google.com/chrome/extensions/trunk/experimental.webRequest.html
Unfortunately, it's still in Experimental stage. I think it will be released as stable with Chrome version 17