Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grabbing tagged instagram photos in real time

I'm trying to download photos posted with specific tag in real time. I found real time api pretty useless so I'm using long polling strategy. Below is pseudocode with comments of sublte bugs in it

newMediaCount = getMediaCount();
delta = newMediaCount - mediaCount;
if (delta > 0) {
    // if mediaCount changed by now, realDelta > delta, so realDelta - delta photos won't be grabbed and on next poll if mediaCount didn't change again realDelta - delta would be duplicated else ...
    // if photo posted from private account last photo will be duplicated as counter changes but nothing is added to recent
    recentMedia = getRecentMedia(delta);
    // persist recentMedia
    mediaCount = newMediaCount;
}

Second issue can be addressed with Set of some sort I gueess. But first really bothers me. I've moved two calls to instagram api as close as possible but is this enough?

Edit

As Amir suggested I've rewritten the code with use of min/max_tag_ids. But it still skips photos. I couldn't find better way to test this than save images on disk for some time and compare result to instagram.com/explore/tags/.

public class LousyInstagramApiTest {

   @Test
    public void testFeedContinuity() throws Exception {
        Instagram instagram = new Instagram(Settings.getClientId());
        final String TAG_NAME = "portrait";
        String id = instagram.getRecentMediaTags(TAG_NAME).getPagination().getMinTagId();
        HashtagEndpoint endpoint = new HashtagEndpoint(instagram, TAG_NAME, id);

        for (int i = 0; i < 10; i++) {
            Thread.sleep(3000);
            endpoint.recentFeed().forEach(d -> {
                try {
                    URL url = new URL(d.getImages().getLowResolution().getImageUrl());
                    BufferedImage img = ImageIO.read(url);
                    ImageIO.write(img, "png", new File("D:\\tmp\\" + d.getId() + ".png"));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
    }
}

class HashtagEndpoint {
    private final Instagram instagram;
    private final String hashtag;
    private String minTagId;

    public HashtagEndpoint(Instagram instagram, String hashtag, String minTagId) {
        this.instagram = instagram;
        this.hashtag = hashtag;
        this.minTagId = minTagId;
    }

    public List<MediaFeedData> recentFeed() throws InstagramException {
        TagMediaFeed feed = instagram.getRecentMediaTags(hashtag, minTagId, null);
        List<MediaFeedData> dataList = feed.getData();
        if (dataList.size() == 0) return Collections.emptyList();

        String maxTagId = feed.getPagination().getNextMaxTagId();
        if (maxTagId != null && maxTagId.compareTo(minTagId) > 0) dataList.addAll(paginateFeed(maxTagId));
        Collections.reverse(dataList);
//        dataList.removeIf(d -> d.getId().compareTo(minTagId) < 0);

        minTagId = feed.getPagination().getMinTagId();
        return dataList;
    }

    private Collection<? extends MediaFeedData> paginateFeed(String maxTagId) throws InstagramException {
        System.out.println("pagination required");

        List<MediaFeedData> dataList = new ArrayList<>();
        do {
            TagMediaFeed feed = instagram.getRecentMediaTags(hashtag, null, maxTagId);
            maxTagId = feed.getPagination().getNextMaxTagId();
            dataList.addAll(feed.getData());
        } while (maxTagId.compareTo(minTagId) > 0);
        return dataList;
    }

}
like image 976
user2418306 Avatar asked Apr 25 '15 21:04

user2418306


People also ask

How do I make tagged photos appear on my timeline on Instagram?

Tap your profile picture in the bottom right to go to your profile. Tap in the top left. Click Privacy and Security. Below Photos of You, select Add Automatically or Add Manually.

Is there a way to see tagged photos on Instagram?

Tap the Pictures of You icon above your photo grid. This displays all Instagram posts you're tagged in. On a computer, click Tagged at the upper-right corner of your post grid. If you don't see a photo you're tagged in, you'll just need to approve or unhide it.

How do I manually accept tagged photos on Instagram?

Tap or your profile picture in the bottom right to go to your profile. Tap in the top right, then tap Settings. Tap Privacy, then tap Posts. Tap Manually Approve Tags, then tap Edit next to Tagged Posts.

How do I hide my tagged photos on Instagram 2022?

Tap Menu (three horizontal lines) in the top right, then tap Settings. Tap Privacy, then tap Tags> Manually Approve Tags. Next to Tagged Posts tap Edit. Select the photos or videos you'd like to hide from your profile, then tap Hide.


1 Answers

Using the Tag endpoints to get the recent media with a desired tag, it returns a min_tag_id in its pagination info, which is tied to the most recently tagged media at the time of your call. As the API also accepts a min_tag_id parameter, you can pass that number from your last query to only receive those media that are tagged after your last query.

So based on whatever polling mechanism you have, you just call the API to get the new recent media if any based on last received min_tag_id.

You will also need to pass a large count parameter and follow the pagination of the response to receive all data without losing anything when the speed of tagging is faster than your polling.

Update:
Based on your updated code:

public List<MediaFeedData> recentFeed() throws InstagramException {
    TagMediaFeed feed = instagram.getRecentMediaTags(hashtag, minTagId, null, 100000);
    List<MediaFeedData> dataList = feed.getData();
    if (dataList.size() == 0) return Collections.emptyList();

    // follow the pagination
    MediaFeed recentMediaNextPage = instagram.getRecentMediaNextPage(feed.getPagination());
    while (recentMediaNextPage.getPagination() != null) {
        dataList.addAll(recentMediaNextPage.getData());
        recentMediaNextPage = instagram.getRecentMediaNextPage(recentMediaNextPage.getPagination());
    }

    Collections.reverse(dataList);

    minTagId = feed.getPagination().getMinTagId();
    return dataList;
}
like image 93
Amir Rahimi Farahani Avatar answered Sep 22 '22 12:09

Amir Rahimi Farahani