Skip to content

Instantly share code, notes, and snippets.

@thiagobraga
Last active October 23, 2020 19:06
Show Gist options
  • Save thiagobraga/0794a33f908eef48d590d19d95fe5e75 to your computer and use it in GitHub Desktop.
Save thiagobraga/0794a33f908eef48d590d19d95fe5e75 to your computer and use it in GitHub Desktop.
Get media from the new Instagram API (July 2020)
/**
* Get instagram photos with Instagram API.
*
* The Instagram API has a limit of 240 requests per hour. With that,
* it was necessary to save the responses in jsonbox.io free service to serve
* the contents within that 1 hour. LocalStorage is also used to store the
* response in user browser, making access to the website faster.
*/
(async () => {
let photos;
const JSONBOX = 'https://jsonbox.io/box_<YOUR_BOX_ID>';
const INSTAGRAM_API = 'https://graph.instagram.com';
const TOKEN = '<YOUR_VERY_LONG_INSTAGRAM_TOKEN>';
const REFRESH_TOKEN = `${INSTAGRAM_API}/refresh_access_token?grant_type=ig_refresh_token&access_token=${TOKEN}`;
const USER_ID = '<USER_ID_OBTAINED_IN_DEBUG_TOOLS>';
const fields = 'media_url,permalink,media_type,caption';
// Check LocalStorage for item 'instagram-photos'
const localPhotos = localStorage.getItem('instagram-photos');
/**
* Render the HTML in the site with obtained photos.
*/
const render = (photos) => {
const html = /* html */ `
<ul class="slides">
${photos
.filter((media) => media.media_url.indexOf('video') === -1)
.map((item) => /*html*/ `
<li>
<a href="${item.permalink}" target="_blank" rel="noreferrer noopener">
<img src="${item.media_url}"
class="instagram-photo"
alt="Instagram Photo"
width="480"
height="480" />
</a>
</li>
`).join('')
}
</ul>
`;
document.querySelector('.container').innerHTML = html;
};
/**
* Check LocalStorage for previous downloaded media.
* Also the 'last-request' is used to compare the time.
*/
const checkLocalStorage = () => {
let photos;
const currentTime = new Date().getTime();
const lastRequest = localStorage.getItem('last-request');
const timeCalc = (currentTime - lastRequest) / 36e5;
// If time expired, a new request should be made.
// In other words, if the difference is higher than 1 hour.
photos = timeCalc > 1 ? [] : JSON.parse(localPhotos);
return photos;
};
/**
* Make a request to the jsonbox.io service endpoint
* to obtain the stored photos in JSON format.
* If JSON is empty, a new request to Instagram API should be made.
*/
const checkJsonBox = async () => {
const { data: [result] } = await axios.get(JSONBOX);
let { photos, _createdOn } = result;
const createdOn = new Date(_createdOn).getTime();
const currentTime = new Date().getTime();
const timeCalc = (currentTime - createdOn) / 36e5;
// If time expired, a new request should be made.
// In other words, if the difference is higher than 1 hour.
if (timeCalc > 1) {
// But we need to empty the array from jsonbox.io
await axios.post(JSONBOX, { photos: [] });
// And reset photos array, so the script will call the Instagram method.
photos = [];
}
return photos;
};
/**
* Refresh Instagram token after each request.
*/
const refreshToken = async () => await axios.get(REFRESH_TOKEN);
/**
* Get photos from Instagram API after all tests failed.
*/
const getInstagramPhotos = async () => {
let photos = [];
try {
const currentTime = new Date().getTime();
const { data } = await axios.get(
`${INSTAGRAM_API}/${USER_ID}?fields=media&access_token=${TOKEN}`,
);
const { data: response } = data.media;
const promises = response.map(async (item) => {
const { data } = await axios.get(
`${INSTAGRAM_API}/${item.id}?fields=${fields}&access_token=${TOKEN}`,
);
const { media_url, permalink } = data;
return { media_url, permalink };
});
// Wait until all promises resolve.
photos = await Promise.all(promises);
// Save results in localStorage avoiding the limitation
// of Instagram Graph API.
localStorage.setItem('instagram-photos', JSON.stringify(photos));
localStorage.setItem('last-request', currentTime);
// Save in jsonbox.io too
await axios.post(JSONBOX, { photos });
// Refresh token
refreshToken();
} catch (error) {
console.error('Unable to retrieve photos. Reason: ' + error.toString());
} finally {
return photos;
}
};
// If the key does not exist, the remaining steps must be checked
// before making a new request to the Instagram API.
if (localPhotos) photos = checkLocalStorage();
if (!localPhotos || photos.length === 0) photos = await checkJsonBox();
if (photos && photos.length === 0) photos = await getInstagramPhotos();
// Finally we call the render function.
render(photos);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment