sferik / twitter-ruby

A Ruby interface to the Twitter API.
http://www.rubydoc.info/gems/twitter
MIT License
4.59k stars 1.31k forks source link

How to find all replies to a particular tweet? #299

Closed anand9 closed 12 years ago

stve commented 12 years ago

I don't think there's an easy way to retrieve a list of replies. Twitter does have a status_activity call which will give you some context around an individual tweet:

Twitter.status_activity(id)

That will give you a retweeters_count, favoriters_count, and a replies_count as well as corresponding arrays of user id's for each list. Given a list of repliers, you could access their timeline and search for statuses where in_reply_to_status_id is the status you are looking for replies on. Seems like there should be an easier way.

cc/ @sferik

stve commented 12 years ago

Please continue discussion on the mailing list. Thanks.

sferik commented 12 years ago

I was about to politely suggest that you ask this question on the mailing list (as I just did with #298), however I'm willing to interpret this as a feature request instead of a support request.

It's worth noting this has been a long-standing request to Twitter Inc, dating back to 2008. While there is still no official solution, apparently there is an undocumented resource at GET /1/related_results/show/:id.{format}. This is actually a pretty exciting discovery! Before you asked this question, I had no idea this resource existed but I knew something like it had to exist in order for Twitter Inc to build #newtwitter.

I would like to add support for this resource in the next version of the gem.

That said, there are some peculiar things about this resource. For one, it is only accessible for a relatively short period of time. Twitter must be storing the related results in a temporary cache that expires after a few days. If you try making a request for replies from an older tweet, you'll always get an empty array, even if replies exist. This is probably one of the reasons why this is an unofficial resource. I've included a couple example responses below, for posterity.

curl https://api.twitter.com/1/related_results/show/230532343104933888.json
[
  {
    "annotations": {
      "FromUser": "brianmario"
    }, 
    "groupName": "TweetsWithConversation", 
    "resultType": "Tweet", 
    "results": [
      {
        "annotations": {
          "ConversationRole": "Fork"
        }, 
        "kind": "Tweet", 
        "score": 1.0, 
        "value": {
          "contributors": null, 
          "coordinates": null, 
          "created_at": "Wed Aug 01 05:39:45 +0000 2012", 
          "favorited": false, 
          "geo": null, 
          "id": 230538286169481217, 
          "id_str": "230538286169481217", 
          "in_reply_to_screen_name": "brianmario", 
          "in_reply_to_status_id": 230532343104933888, 
          "in_reply_to_status_id_str": "230532343104933888", 
          "in_reply_to_user_id": 9994542, 
          "in_reply_to_user_id_str": "9994542", 
          "place": null, 
          "retweet_count": 0, 
          "retweeted": false, 
          "source": "web", 
          "text": "@brianmario I mean, in a nutshell.", 
          "truncated": false, 
          "user": {
            "contributors_enabled": false, 
            "created_at": "Fri Jun 29 00:30:31 +0000 2007", 
            "default_profile": false, 
            "default_profile_image": false, 
            "description": "One tiny spark. GitHub lady scro. ", 
            "favourites_count": 1983, 
            "follow_request_sent": false, 
            "followers_count": 1431, 
            "following": true, 
            "friends_count": 355, 
            "geo_enabled": true, 
            "id": 7141792, 
            "id_str": "7141792", 
            "is_translator": false, 
            "lang": "en", 
            "listed_count": 80, 
            "location": "San Francisco", 
            "name": "Luckiest Monkey", 
            "notifications": false, 
            "profile_background_color": "231b10", 
            "profile_background_image_url": "http://a0.twimg.com/profile_background_images/6550431/honeycomb2.png", 
            "profile_background_image_url_https": "https://si0.twimg.com/profile_background_images/6550431/honeycomb2.png", 
            "profile_background_tile": true, 
            "profile_image_url": "http://a0.twimg.com/profile_images/1184180378/melissa09_normal.jpg", 
            "profile_image_url_https": "https://si0.twimg.com/profile_images/1184180378/melissa09_normal.jpg", 
            "profile_link_color": "0d7185", 
            "profile_sidebar_border_color": "463216", 
            "profile_sidebar_fill_color": "ffffff", 
            "profile_text_color": "723f1d", 
            "profile_use_background_image": true, 
            "protected": false, 
            "screen_name": "luckiestmonkey", 
            "show_all_inline_media": true, 
            "statuses_count": 8537, 
            "time_zone": "Tijuana", 
            "url": "http://30.media.tumblr.com/tumblr_lle40l5rH31qewazuo1_500.gif", 
            "utc_offset": -28800, 
            "verified": false
          }
        }
      }, 
      {
        "annotations": {
          "ConversationRole": "Fork"
        }, 
        "kind": "Tweet", 
        "score": 1.0, 
        "value": {
          "contributors": null, 
          "coordinates": null, 
          "created_at": "Wed Aug 01 05:28:36 +0000 2012", 
          "favorited": false, 
          "geo": null, 
          "id": 230535480033288192, 
          "id_str": "230535480033288192", 
          "in_reply_to_screen_name": "brianmario", 
          "in_reply_to_status_id": 230532343104933888, 
          "in_reply_to_status_id_str": "230532343104933888", 
          "in_reply_to_user_id": 9994542, 
          "in_reply_to_user_id_str": "9994542", 
          "place": null, 
          "possibly_sensitive": false, 
          "possibly_sensitive_editable": true, 
          "retweet_count": 0, 
          "retweeted": false, 
          "source": "<a href=\"http://twicca.r246.jp/\" rel=\"nofollow\">twicca</a>", 
          "text": "Art. Cc: @prescriptionpat RT @brianmario: Yep. @ Powell St. BART Station http://t.co/qRFMSJe7", 
          "truncated": false, 
          "user": {
            "contributors_enabled": false, 
            "created_at": "Tue Apr 27 02:22:48 +0000 2010", 
            "default_profile": false, 
            "default_profile_image": false, 
            "description": "Hot sauce connoisseur ", 
            "favourites_count": 1381, 
            "follow_request_sent": false, 
            "followers_count": 236, 
            "following": false, 
            "friends_count": 254, 
            "geo_enabled": false, 
            "id": 137550548, 
            "id_str": "137550548", 
            "is_translator": false, 
            "lang": "en", 
            "listed_count": 14, 
            "location": "Central Coast California", 
            "name": "Matt", 
            "notifications": false, 
            "profile_background_color": "000000", 
            "profile_background_image_url": "http://a0.twimg.com/profile_background_images/412088134/DSC00682.JPG", 
            "profile_background_image_url_https": "https://si0.twimg.com/profile_background_images/412088134/DSC00682.JPG", 
            "profile_background_tile": false, 
            "profile_image_url": "http://a0.twimg.com/profile_images/2428800270/profile_normal.png", 
            "profile_image_url_https": "https://si0.twimg.com/profile_images/2428800270/profile_normal.png", 
            "profile_link_color": "009999", 
            "profile_sidebar_border_color": "EEEEEE", 
            "profile_sidebar_fill_color": "EFEFEF", 
            "profile_text_color": "333333", 
            "profile_use_background_image": true, 
            "protected": false, 
            "screen_name": "MattinSLO", 
            "show_all_inline_media": true, 
            "statuses_count": 3490, 
            "time_zone": "Pacific Time (US & Canada)", 
            "url": "http://twitter.com/Mattinslo", 
            "utc_offset": -28800, 
            "verified": false
          }
        }
      }
    ], 
    "score": 1.0
  }
]

Here's another example where "ConversationRole": "Descendant" (I'm not sure exactly what this means but I wanted to capture the difference here):

curl https://api.twitter.com/1/related_results/show/230523765702926336.json 
[
  {
    "annotations": {
      "FromUser": "olivia"
    }, 
    "groupName": "TweetsWithConversation", 
    "resultType": "Tweet", 
    "results": [
      {
        "annotations": {
          "ConversationRole": "Descendant"
        }, 
        "kind": "Tweet", 
        "score": 1.0, 
        "value": {
          "contributors": null, 
          "coordinates": null, 
          "created_at": "Wed Aug 01 04:48:02 +0000 2012", 
          "favorited": false, 
          "geo": null, 
          "id": 230525273714606080, 
          "id_str": "230525273714606080", 
          "in_reply_to_screen_name": "olivia", 
          "in_reply_to_status_id": 230523765702926336, 
          "in_reply_to_status_id_str": "230523765702926336", 
          "in_reply_to_user_id": 25216995, 
          "in_reply_to_user_id_str": "25216995", 
          "place": null, 
          "retweet_count": 0, 
          "retweeted": false, 
          "source": "<a href=\"http://itunes.apple.com/us/app/twitter/id409789998?mt=12\" rel=\"nofollow\">Twitter for Mac</a>", 
          "text": "@olivia solid math.", 
          "truncated": false, 
          "user": {
            "contributors_enabled": false, 
            "created_at": "Mon Nov 20 05:40:10 +0000 2006", 
            "default_profile": false, 
            "default_profile_image": false, 
            "description": "Dabble DB \u2192 Twitter \u2192 Etsy. Thinking big about small shops.", 
            "favourites_count": 1432, 
            "follow_request_sent": false, 
            "followers_count": 6408, 
            "following": true, 
            "friends_count": 580, 
            "geo_enabled": true, 
            "id": 13192, 
            "id_str": "13192", 
            "is_translator": false, 
            "lang": "en", 
            "listed_count": 363, 
            "location": "Galiano Island", 
            "name": "Avi Bryant", 
            "notifications": false, 
            "profile_background_color": "352726", 
            "profile_background_image_url": "http://a0.twimg.com/images/themes/theme5/bg.gif", 
            "profile_background_image_url_https": "https://si0.twimg.com/images/themes/theme5/bg.gif", 
            "profile_background_tile": false, 
            "profile_image_url": "http://a0.twimg.com/profile_images/48591172/avibryant_normal.png", 
            "profile_image_url_https": "https://si0.twimg.com/profile_images/48591172/avibryant_normal.png", 
            "profile_link_color": "D02B55", 
            "profile_sidebar_border_color": "829D5E", 
            "profile_sidebar_fill_color": "99CC33", 
            "profile_text_color": "3E4415", 
            "profile_use_background_image": true, 
            "protected": false, 
            "screen_name": "avibryant", 
            "show_all_inline_media": true, 
            "statuses_count": 7629, 
            "time_zone": "Pacific Time (US & Canada)", 
            "url": "http://avibryant.com", 
            "utc_offset": -28800, 
            "verified": false
          }
        }
      }
    ], 
    "score": 1.0
  }
]

If you're used to looking at Twitter API responses, this one may seem a little unconventional. It's not structured like any other response I've seen. This just means it will take a little more work to build it into the gem but it shouldn't be a major issue. It's just a bit strange.

As excited as I am about this feature, I probably won't have a chance to hack on it until next week at the earliest. If you want to get started on it sooner, feel free to do so.

anand9 commented 12 years ago

cool!! thanks .. i'll wait for the new version :)

aguilarsoto commented 11 years ago

is there a new implementation for this on version 4 of the gem?

stve commented 11 years ago

The endpoint was removed by Twitter in version 1.1 of their API. I'm not sure there's a replacement as their shift back to server-side rendering means it's harder to track down undocumented endpoints such as this one.

aguilarsoto commented 11 years ago

thanks for the quick turn around Steve, that was exactly what I was afraid of.

Marco

Qi2013 commented 11 years ago

Hi @spagalloco, so you mean that the old api is gone? And there is no replacement form twitter? that is too bad :)

stve commented 11 years ago

Unfortunately yes. This endpoint is no longer available in version 1.1 of the API. Many of those endpoints have been removed completely and some that remain now return rendered HTML as opposed to JSON.

Qi2013 commented 11 years ago

@spagalloco thanks a lot for your quick reply. Are there some other ways to get all replies to a tweet?

stve commented 11 years ago

@Qi2013 I described some other techniques above, but there's no easy way unfortunately.