totemstech / instagram-node Goto Github PK
View Code? Open in Web Editor NEWNodeJS driver for the instagram API
NodeJS driver for the instagram API
To be added on user:likes
, user:followed-by
, user:follows
I think I'd like to use this, but there's no documentation on how it's used.
Does is use a callback function? Does it take any arguments?
Can someone point me at an example?
Thanks
Hi,
When I use tag_media_recent, i get the deprecation warning of:
deprecation_warning: "next_max_id and min_id are deprecated for this endpoint; use min_tag_id and max_tag_id instead"
Should this be fixed or we can leave it?
I'm following the instructions on the gitpage and when I try to use this method:
user_followers(userId, function(...){})
The "users" array is always empty. My instagram account has around 190 followers in it. Why is it returning an empty array, then?
My configuration object is:
var config = {
//lob_api_key: 'xxxx',
instagram_redirect_uri: 'http://localhost:3000/handleauth',
instagram_client_id: 'idd',
instagram_client_secret: 'sss',
instagram_scopes: { scope: ['basic', 'public_content', 'follower_list', 'relationships', 'likes'], state: 'a state' }
};
full code:
api.user_followers('USERID', function(err, users, pagination, remaining, limit) {
if(err) res.status(500).json(err.body);
res.status(200).json(users);
})
Module was working great as I tested with my Instagram credentials declared in the controller, but I can't get them to work as env variables. (The credentials are valid, and all my other env variables work.)
I scaffolded my app with the angular-fullstack Yeoman generator, and haven't changed its basic architecture. In /server/config/local.env.js I have:
(function()
{
'use strict';
module.exports = Env();
function Env()
{
var IEnvironmentVariables = {
// Instagram Credentials - placeholders here in internet-land, obviously
INSTAGRAM_ACCESS_TOKEN: 'my-access-token',
INSTAGRAM_CLIENT_ID: 'my-client-id',
INSTAGRAM_CLIENT_SECRET: 'my-client-secret'
};
return IEnvironmentVariables;
}
})();
In /server/config/environment/index.js:
instagram: {
accessToken: process.env.INSTAGRAM_ACCESS_TOKEN || process.env.OPENSHIFT_INSTAGRAM_ACCESS_TOKEN || 'instagram-access-token',
clientId: process.env.INSTAGRAM_CLIENT_ID || process.env.OPENSHIFT_INSTAGRAM_CLIENT_ID || 'instagram-client-id',
clientSecret: process.env.INSTAGRAM_CLIENT_SECRET || process.env.OPENSHIFT_INSTAGRAM_CLIENT_SECRET || 'instagram-client-secret'
}
In /server/api/feed/feed.controller.js:
var Instagram = require('instagram-node').instagram();
var config = require('../../config/environment').instagram;
Instagram.use({
access_token: config.accessToken,
client_id: config.clientId,
client_secret: config.clientSecret
});
The above Instagram.use({})
is returning 'instagram-access-token', 'instagram-client-id' and 'instagram-client-secret', the defaults from my config file when there aren't any environment variables found. I'm flummoxed. Help?
I am trying to use the add_tag_subscription to use the realtime Instagram API. However, I can't seem to use this endpoint.
When I run:
instagram.add_tag_subscription('funny', 'localtunnelurl/callback', { verify_token: 'funnytag' }, function(err, result, remaining, limit) { console.log(err); console.log(result) });
it returns:
{ [Error: OAuthParameterException: Missing client_id or access_token URL parameter.]
code: 400,
error_type: 'OAuthParameterException',
error_message: 'Missing client_id or access_token URL parameter.',
retry: [Function] }
I am sure my setup of client_id and client_secret is correct since other endpoints like tag_media_recent is returning results as expected. I know that the subscription endpoint requires client_id and client_secret but I have pass these information in the instagram.use() method. Perhaps it is a bug for this subscription endpoint method? Or is there something on my end that I forgot to do? Documentation doesn't state that I need to do anything else except just provide the callback url.
I'm just curious how you actually use this api since I don't see how you specify the userid.
ig.add_user_subscription('http://MYHOST/user', [options,] function(err, result, remaining, limit){});
Ive tried doing something like this but that didn't work either.
var callBackURL = 'http://'+server.ip+'/user/userid';
ig.add_user_subscription(callBackURL, [], function(err, result, remaining, limit){
});
express.post("/user/:userid", function(req,res){
console.log("user call back");
});
media_search
needs the optional parameter count
added to it:
if(options.count) {
params.count = options.count;
}
can be between 1 and 100.
On user_media_recent, the count option successfully restricts results received at once, but count isn't being taken into consideration for the pagination algorithm. If I request only 5 user_media_recent, pagination.next still allows me to fetch more than 5. In fact, it seems like it walks through all of the user's recent media.
Hi,
I'm having a real brain fart trying to get my subscriptions working. I have it working locally using your library and it works perfectly. I can add, and delete subscriptions which has a callback url to my aws hosted ec2 instance. It works and the ec2 instance receives the updates.
My problem is that if I try and create the subscription from the ec2 instance (with the same code + config, etc) it fails with an APISubscriptionError Unable to reach callback URL
error.
I've tried running the basic curl command from the server and that creates the subscription no problem too.
I don't suppose you guys have any idea why this might be happening?
I'm using v0.5.8 of your lib with node v0.12.6 both locally and on the ec2 instance.
I'm properly stumped! Any help would be greatly appreciated.
Hi there,
If I use the pagination object to call my callback repeatedly, I believe it fetches 'count' number of media over and over to reach the offset of data. I was wondering if there's a way to jump to an offset without fetching all the medias before it. Please let me know.
Since about yesterday (20-30 hours ago) the users.search method took whatever string and returnd a bunch of results. Now it returns an empty array. It returns someting only if the string perfectly matches an instagram username. The instagram API changelog has nothing on this modification. How do I get around this issue back to the previous functionality?
What would you think about migrating to promises and leaving backwards compatibility (or maybe not and release 1.0.0) ?
I'm willing to make the PR
On the first hit of the route /authorize_user authorises oaky.
On further hits of the route /authorize_user it results in a "Error: Please supply client_id and client_secret via use()" error, even thought both the client_id and client_secret's are set in the use.
instagram.tag('тест', function(err, result, remaining, limit) {
console.log(err);
}
shows
{ [SyntaxError: Unexpected token <]
retry: [Function],
status_code: 400,
body: '<html><body><h1>400 Bad request</h1>\nYour browser sent an invalid request.\n</body></html>\n' }
I know that this is not a limitation of this lib, but I think you guys might have a clue or two on how to get all comments from a media because Instagram's API only return the last 150.
Any help is appreciate, thanks!
In the last days i get this error after the instagram authentication form:
code: 400,
error_type: 'OAuthException',
error_message: 'You must provide a client_id',
The code i'm trying is the one present in the 'Server-Side Authentication using OAuth and the Instagram API' section of your github page... I'm sure the client_id is set.
thx.
Fabrizio
Is video upload supported? Thanks.
Hi teleportd (?Nitrogram team),
Just wondering what the status on geographies is? I'm keen to use it, but less interested to do a recurring media_search which is a bit of a PITA.
Awesome package though :) keep up the good work, and I'll contribute anything that I can (I'm not a massively competent developer...)
Hugh
When using the signed request as in the example
ig.add_like(medias[i].id, {
sign_request: {
client_secret: 'CLIENT_SECRET'
}}, function(err, remaining, limit) {
});
this error is thrown
{ [Error: OAuthParameterException: Missing access_token URL parameter.]
code: 400,
error_type: 'OAuthParameterException',
error_message: 'Missing access_token URL parameter.',
retry: [Function] }
To be coherent with instagram API output
I took a cursory look at the code, and it doesn't appear that there is a function in this library to verify the integrity of a POST from Instagram when using the real time API. Here is a link to the Ruby version which does include this, and a StackOverflow answer which (maybe) implements it in Node:
http://stackoverflow.com/questions/19557887/verify-pubsubhubbub-content-signature-in-node-express
The method get_authorization_url in file instagram.js (line 1415) uses only response_type 'code'.
Is there another way to change this value to 'token'?
The "limit" variable you are passing to callbacks is not the "x-ratelimit-limit" header, but the "x-ratelimit-remaining". It would be helpful to have both values passed instead of just the one.
https://github.com/teleportd/instagram-node/blob/master/lib/instagram.js#L163
I guess the simplest solution would be parse out that other header and pass it along as another argument to callbacks.
EDIT: Link to file added
Hello,
So my app often reached the limit, and I've made an errorhandling function to set a timeout for 5 min when the error comes from reaching the limit
(by adding this after each API call)
if (err) {
errorHandling(err);
}
and this part in the errorHandling function :
if (err.code == 429) {
console.log(getDateTime()+"The limit has been reached. ");
console.log("Automatically trying again in 5 minutes...");
setTimeout(err.retry, 1000 * 300);
}
So, when I call it from app.js because the limit has been reached it works as expected, namly times out for 5 minutes and then keeps going if the limit has been reset or waits 5 more minutes if it hasn't.
But today I realized the same kind of code keeps looping even though the limit has been reset. This happens when I call errorHandling from another .js file. Is it not possible to call err.retry() when err comes from a different .js file ?
Am I correct: The system assumes that you either use client_id
+ client_secret
OR an access_token
(eg in the use
public function).
But if I want to sign my requests so I don't run into spamming algorithms as quickly (yup that's the case), I want to request with an access_token (to get 5k req's per user) and still need to send my app's client_secret
for signing.
While it works by overriding client_secret
manually at https://github.com/totemstech/instagram-node/blob/master/lib/instagram.js#L142 it's obviously dirty as hell and still throws errors on https://github.com/totemstech/instagram-node/blob/master/lib/instagram.js#L343
Do you have any advice for me?
SyntaxError: Unexpected token O
at Object.parse (native)
at IncomingMessage. (/srv/www/heart/releases/20151202120536/node_modules/instagram-node/lib/instagram.js:192:27)
at emitNone (events.js:72:20)
at IncomingMessage.emit (events.js:166:7)
at endReadableNT (_stream_readable.js:903:12)
at doNTCallback2 (node.js:439:9)
at process._tickCallback (node.js:353:17)
When there is an exception raised in the callback 'cb' line 130, the exception-handling line 126 causes its re-firing.
Change proposition : (line 126)
try {
var result = JSON.parse(body);
} catch(err) {
return handle_error(err, cb, retry, res.statusCode, body);
}
var limit = parseInt(res.headers['x-ratelimit-remaining'], 10) || 0;
my.limit = limit;
return cb(null, result, limit);
Is it possible to use proxy with you library?
I mean connect to instagram server through proxy server via HTTPS.
Would it be useful to others to allow realtime subscription, so instagram can call your URL when new User, Tags, etc come in?
People would still need to implement the web callback, as described here:
http://instagram.com/developer/realtime/
If others want this, I will make a pull-request.
This is an example of how I imagine it would work:
You make express callback that looks like this:
app.all('/callback/instagram/tag/:tag', function(req, res){
// do stuff with req.body
res.send(req.query['hub.challenge']);
});
req.body
is the posted subscription update, and it would look something like this:
[
{
"subscription_id": "1",
"object": "tag",
"object_id": "funny",
"changed_aspect": "media",
"time": 1297286541
}
...
]
This will just let instagram know you are cool with the subscripton if they GET, and handle POSTs when they come in from subscription.
Next, instagram lib use would look like this:
ig.subscribe_tag({
url:'http://YOURHOST/callback/instagram/tag/funny',
'aspect': 'media',
'object_id': 'funny'
}, function(err, results){
// do stuff with results
})
or maybe with some inference, and sensible defaults:
ig.subscribe_tag('funny', {}, function(err, results){
// do stuff with results
})
results
is return from subscribe, which looks something like this:
{ meta: { code: 200 },
data:
{ object: 'tag',
object_id: 'funny',
aspect: 'media',
callback_url: 'http://YOURHOST/callback/instagram/tag/funny',
type: 'subscription',
id: '4513584' } }
Maybe data
should be pulled out, to make it neater?
What do people think? Would this be helpful?
For my own documentation, the basic implementation for subscribe_tag would be:
subscribe_tag = function(tag, callback_url, options, cb){
var retry = function(){
subscribe_tag(tag, callback_url, options, cb);
};
var params = {
callback_url: callback_url,
object:'tag',
aspect: options.aspect || 'media',
object_id: tag,
client_id: my.auth.client_id,
client_secret: my.auth.client_secret
};
call('POST', '/subscriptions/', params, function(err, result, limit) {
if(err) {
return handle_error(err, cb, retry);
} else if(result) {
return cb(null, result, limit);
} else {
return handle_error(result, cb, retry);
}
}, retry);
};
fwk.method(that, 'subscribe_tag', subscribe_tag, _super);
Usage looks like this:
ig.subscribe_tag('funny', 'http://SITE/callback/instagram/tag/funny', {}, function(er, results){
console.log(er, results);
});
Again, if this is useful, I can make one for all the subcription-types, and make a pull-request.
add_tag_subscription function does not allow verify_token
https://www.instagram.com/developer/endpoints/users/#get_users_media_recent_self
uses GET/users/self/media/recent
currently '/users/self/feed' is used
call('GET', '/users/self/feed',
instagram.js line 403
I am using the package along with browserify in a chrome extension's background process.
My issue is that the protocol of that page is chrome-extension, not https. Recently, the calls have been to chrome-extension://api.instagram.com:443/v1/...
instead of https://api.instagram.com:443/v1/...
. This obviously fails.
tag_media_recent can have count parameter, in the implementation, dont have.
I patched implementation of tag_media_recent like this:
params.count = options.count || 33;
33 is the max i think in instagram implmentation check this:
ig.media('media_id', function(err, result, limit) {});
result
-> media
i don't know why using pagination with user_media_recent
method the two parameters : remaining
& limit
sets to 5000 the in each iterate remaining
counts down by 20 & the pagination will never ends and loops forever. (note that the user only have 30 media)
var ig = require('instagram-node').instagram();
var hdl = function(err, result, pagination, remaining, limit) {
// Your implementation here
console.log(remaining); // 5000!
console.log(limit) :// 5000!
if(pagination.next) {
pagination.next(hdl); // Will get second page results
}
};
ig.user_media_recent('123456', hdl);
How can fix problem?
It is likely I'm missing a step, but I'm getting a 404 when I call ig.user and ig.user_media_recent with the following code:
var ig = require('instagram-node').instagram();
ig.use({ client_id: 'YES',
client_secret: 'YES' });
ig.user_media_recent('calvinklein', function(err, result, pagination, remaining, limit) {
console.log(err);
console.log(result);
});
I'm trying to do this without a user authentication step -- I just want to pull in a specific user's public photos. I will dig into the Instagram API more to see if that's possible, but if I'm missing a step, please let me know. Thank you.
Hi,
I'm using your library (thanks for your work!), I was stuck fora couple trying to make del_subscription function work ^^.
You should add in the documentation that the auth_token should not be provided in ig.use() when you call subscription function.
Indeed it will make an http request without client_secret nor client_id which will lead to an error.
That's would be great it would avoid people blocking on htis little thing !
Thanks
Alexandre
I'm can't seem to figure out how to sign regular requests like fetching a user's media:
Instagram.user_media_recent(account.get("user_id"), {
"access_token" : account.get("access_token")
sign_request: {
client_secret : "xxx"
}
}, handle);
}
I want take just the fotos from a tag of today
I create this filter on ig.tag_media_recent or with the pagination?
var hdl = function(err, medias, pagination, limit) {
if(err){
console.log(err);
} else {
if(pagination.next) {
console.log('Variavel pagination: %j', pagination);
pagination.next(hdl); }
}
};
ig.tag_media_recent(hashtag, hdl);
I do not have a FourSquare ID, but I do have a Facebook ID. I'm assuming I use the "ig.location_search" function, but not sure how to pass in the Facebook ID, or if it's even possible.
Any idea?
Thank you!
This is probably not an issue per se, but I'm curious whether I'm missing something, or whether it's just not possible to get ALL the comments associated with a post using the user_self_media_recent
method. Out of the box, for whatever reason, comments are capped at 8 with that method. Do I need to just make another api call to ig.comments
to control the count?
In other news: instagram-node is great! I only wish IG was still allowing POST/DELETE requests. Ahhhh!
When I am using tag_media_recent endpoint and I use min_tag_id parameter, it returns this error:
{"pagination":{"next_max_tag_id":"1410528728840665","deprecation_warning":"next_max_id and min_id are deprecated for this endpoint; use min_tag_id and max_tag_id instead","next_max_id":"1410528728840665","next_min_id":"1410528776932183","min_tag_id":"1410528776932183","next_url":"https://api.instagram.com/v1/tags/birthday/media/recent?count=100\u0026client_id=XXX\u0026max_tag_id=1410528728840665\u0026client_secret=XXX"},"meta":{"code":200},"data":[{"attribution":null,"videos":
Can you fix it please?
Simple example from doc.
var ig = require('instagram-node').instagram({});
// Api access tokens
var accessTokens = [
'd217de8c2728441dadf81e308ce****d3a',
'cd8024a3fd6e4718abdf2e8f8***6ca',
'66e8765c5a594e84972e3***82bdf6b',
'3b0286915f864165bc25***309e9f39'
];
ig.use({
access_token: accessTokens[_.random(0, accessTokens.length-1)]
});
ig.tag_media_recent('spb', function(err, medias, pagination, remaining, limit) {
if (err) throw err;
console.log(medias);
});
Error: OAuthAccessTokenException: The access_token provided is invalid.
My access tokens 100% working
What do you mean by 200 data points per seconds ? The maximum pictures that I am retrieving is 20 per request. How do you get 200 per second?
Hi guys,
I have a problem with the scopes, i keep getting this error:
code: 400,
error_type: 'OAuthPermissionsException',
error_message: 'This request requires scope=likes, but this access token is not authorized with this scope. The user must re-authorize your application with scope=likes to be granted write permissions.',
even though i am setting the scopes likes this in auth and reauth routes to get redirect uri:
instagram.get_authorization_url(reauth_cb, { scope: ['basic', 'comments', 'relationships', 'likes'] });
It seems like there is no updating of the callback url, I even checked the url and it has the scopes added correctly on Instagram but the response it still the same, should i have to do something in "Manage clients" section in Instagram developers, ask for permission to use this scopes, or something else?
Regards
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.