Integrating Instagram into micro.blog using Google Apps Script
This is a Google Apps Script I made to reintegrate Instagram into my micro.blog flow since Instagram had started blocking the feature without being a developer. It does require access to Instagram’s developer API, which is available to Professional (creator or business) accounts. It’s a very simple tick-the-box in one’s account settings to change from a personal to creator account.
How to obtain the required long-lived tokens and such is beyond the scope of this post. An instagram long-lived token lasts for 60 or 90 days and you’ll need to update it manually in the script.
The script is designed to be triggered hourly to poll the Instagram API and import any new posts, with photos and videos posted within the previous hour. It attempts to download images and video and push them to micro.blog, with the “caption” (text content of the post) as the text content of the micro.blog entry with a photo-emoji and “(from Instagram)” header with link to the original. It cannot currently pull Reels or Stories as those are treated separately by the Instagram API.
function myFunction() {
// Include your Instagram and Micro.blog tokens below.
// For Instagram, highly recommend using a long-lived key that only needs replacement every 60 days. Instructions are provided
// on Facebook/Meta's developer pages.
var instagramtoken = "XXX";
var microblogtoken = "XXX"
// Imports `moment.js` library from CDN for easier date calcluation.
// Depending on how you schedule this script you may wish to adjust startHour and endHour. I have it set for the previous hour.
eval(UrlFetchApp.fetch("https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.30.1/moment.min.js").getContentText());
var startHour = moment().startOf('hour').subtract(1, 'hours').unix();
var endHour = moment().endOf('hour').subtract(1, 'hours').unix();
// This script is designed to push both video and photo content. Thus the script can time out if
// it takes too long to download or push a video file.
// IT WILL NOT PULL REELS OR STORIES.
var instagramdata = JSON.parse(
UrlFetchApp.fetch(
`https://graph.instagram.com/v23.0/me/media?since=${startHour}&until=${endHour}&fields=shortcode,caption,media_type,media_url,timestamp,children%7Bmedia_url%7D&access_token=${instagramtoken}`,
{
"method": "GET"
}
).getContentText()
);
for (i = 0; i < instagramdata.data.length; i++) {
var post = instagramdata.data[i];
var photolist = new Array();
if (post.media_type != 'CAROUSEL_ALBUM') {
var photo = UrlFetchApp.fetch(post.media_url).getBlob();
var photoupload = JSON.parse(UrlFetchApp.fetch(
"https://micro.blog/micropub/media", {
"method": "POST",
"headers": {
"Authorization": `Bearer ${microblogtoken}`
},
"payload": {
"file": photo
}
}
).getContentText());
if (photoupload.url.includes('mp4')) {
post.caption += `\n\n<video width="600" height="600" controls><source src="${photoupload.url}" type="video/mp4"></video>\n\n`
} else {
photolist.push(photoupload.url)
}
var microdata = {
"type": ["h-entry"],
"properties": {
"published": [post.timestamp],
"content": [`📸: (from [Instagram](https://www.instagram.com/p/${post.shortcode}))\n\n${post.caption}`]
}
};
if (photolist.length > 0) {
microdata.properties.photo = photolist;
}
} else {
for (j = 0; j < post.children.data.length; j++) {
var child = post.children.data[j];
var media = UrlFetchApp.fetch(child.media_url).getBlob();
var photoupload = JSON.parse(UrlFetchApp.fetch(
"https://micro.blog/micropub/media", {
"method": "POST",
"headers": {
"Authorization": `Bearer ${microblogtoken}`
},
"payload": {
"file": media
}
}
).getContentText());
if (photoupload.url.includes('mp4')) {
post.caption += `\n\n<video width="600" height="600" controls><source src="${photoupload.url}" type="video/mp4"></video>\n\n`
} else {
photolist.push(photoupload.url)
}
}
var microdata = {
"type": ["h-entry"],
"properties": {
"published": [post.timestamp],
"content": [`📸: (from [Instagram](https://www.instagram.com/p/${post.shortcode}))\n\n${post.caption}`],
"photo": photolist
}
};
}
var request = UrlFetchApp.fetch(
"https://micro.blog/micropub", {
"method": "POST",
"headers": {
"Authorization": "Bearer ${microblogtoken}"
},
"payload": JSON.stringify(microdata)
}
).getContentText();
console.log(request);
}
}