diff --git a/lib/twitter/streaming/client.rb b/lib/twitter/streaming/client.rb index 4e53d3aa3..a986081f3 100644 --- a/lib/twitter/streaming/client.rb +++ b/lib/twitter/streaming/client.rb @@ -27,7 +27,7 @@ def initialize(options={}, &block) # @option options [String] :follow A comma separated list of user IDs, indicating the users to return statuses for in the stream. # @option options [String] :track Includes additional Tweets matching the specified keywords. Phrases of keywords are specified by a comma-separated list. # @option options [String] :locations Includes additional Tweets falling within the specified bounding boxes. - # @yield [Twitter::Tweet, Twitter::Streaming::Event, Twitter::DirectMessage, Twitter::Streaming::FriendList, Twitter::Streaming::DeletedTweet] A stream of Twitter objects. + # @yield [Twitter::Tweet, Twitter::Streaming::Event, Twitter::DirectMessage, Twitter::Streaming::FriendList, Twitter::Streaming::DeletedTweet, Twitter::Streaming::StallWarning] A stream of Twitter objects. def filter(options={}, &block) request(:post, 'https://stream.twitter.com:443/1.1/statuses/filter.json', options, &block) end @@ -39,7 +39,7 @@ def filter(options={}, &block) # @note This endpoint requires special permission to access. # @param options [Hash] A customizable set of options. # @option options [Integer] :count The number of messages to backfill. - # @yield [Twitter::Tweet, Twitter::Streaming::Event, Twitter::DirectMessage, Twitter::Streaming::FriendList, Twitter::Streaming::DeletedTweet] A stream of Twitter objects. + # @yield [Twitter::Tweet, Twitter::Streaming::Event, Twitter::DirectMessage, Twitter::Streaming::FriendList, Twitter::Streaming::DeletedTweet, Twitter::Streaming::StallWarning] A stream of Twitter objects. def firehose(options={}, &block) request(:get, 'https://stream.twitter.com:443/1.1/statuses/firehose.json', options, &block) end @@ -48,7 +48,7 @@ def firehose(options={}, &block) # # @see https://dev.twitter.com/docs/api/1.1/get/statuses/sample # @see https://dev.twitter.com/docs/streaming-apis/parameters - # @yield [Twitter::Tweet, Twitter::Streaming::Event, Twitter::DirectMessage, Twitter::Streaming::FriendList, Twitter::Streaming::DeletedTweet] A stream of Twitter objects. + # @yield [Twitter::Tweet, Twitter::Streaming::Event, Twitter::DirectMessage, Twitter::Streaming::FriendList, Twitter::Streaming::DeletedTweet, Twitter::Streaming::StallWarning] A stream of Twitter objects. def sample(options={}, &block) request(:get, 'https://stream.twitter.com:443/1.1/statuses/sample.json', options, &block) end @@ -62,7 +62,7 @@ def sample(options={}, &block) # @param options [Hash] A customizable set of options. # @option options [String] :with Specifies whether to return information for just the users specified in the follow parameter, or include messages from accounts they follow. # @option options [String] :replies Specifies whether stall warnings should be delivered. - # @yield [Twitter::Tweet, Twitter::Streaming::Event, Twitter::DirectMessage, Twitter::Streaming::FriendList, Twitter::Streaming::DeletedTweet] A stream of Twitter objects. + # @yield [Twitter::Tweet, Twitter::Streaming::Event, Twitter::DirectMessage, Twitter::Streaming::FriendList, Twitter::Streaming::DeletedTweet, Twitter::Streaming::StallWarning] A stream of Twitter objects. def site(*args, &block) arguments = Arguments.new(args) user_ids = collect_user_ids(arguments) @@ -79,7 +79,7 @@ def site(*args, &block) # @option options [String] :replies Specifies whether stall warnings should be delivered. # @option options [String] :track Includes additional Tweets matching the specified keywords. Phrases of keywords are specified by a comma-separated list. # @option options [String] :locations Includes additional Tweets falling within the specified bounding boxes. - # @yield [Twitter::Tweet, Twitter::Streaming::Event, Twitter::DirectMessage, Twitter::Streaming::FriendList, Twitter::Streaming::DeletedTweet] A stream of Twitter objects. + # @yield [Twitter::Tweet, Twitter::Streaming::Event, Twitter::DirectMessage, Twitter::Streaming::FriendList, Twitter::Streaming::DeletedTweet, Twitter::Streaming::StallWarning] A stream of Twitter objects. def user(options={}, &block) request(:get, 'https://userstream.twitter.com:443/1.1/user.json', options, &block) end diff --git a/lib/twitter/streaming/message_parser.rb b/lib/twitter/streaming/message_parser.rb index b6efb1a8d..ceae3fc6f 100644 --- a/lib/twitter/streaming/message_parser.rb +++ b/lib/twitter/streaming/message_parser.rb @@ -2,6 +2,7 @@ require 'twitter/streaming/deleted_tweet' require 'twitter/streaming/event' require 'twitter/streaming/friend_list' +require 'twitter/streaming/stall_warning' require 'twitter/tweet' module Twitter @@ -17,10 +18,10 @@ def self.parse(data) DirectMessage.new(data[:direct_message]) elsif data[:friends] FriendList.new(data[:friends]) - elsif data[:delete] - if data[:delete][:status] - DeletedTweet.new(data[:delete][:status]) - end + elsif data[:delete] && data[:delete][:status] + DeletedTweet.new(data[:delete][:status]) + elsif data[:warning] + StallWarning.new(data[:warning]) end end diff --git a/lib/twitter/streaming/stall_warning.rb b/lib/twitter/streaming/stall_warning.rb new file mode 100644 index 000000000..c4e853cea --- /dev/null +++ b/lib/twitter/streaming/stall_warning.rb @@ -0,0 +1,7 @@ +module Twitter + module Streaming + class StallWarning < Twitter::Base + attr_reader :code, :message, :percent_full + end + end +end diff --git a/spec/fixtures/track_streaming_user.json b/spec/fixtures/track_streaming_user.json index a6ce12f78..6c3c9ce75 100644 --- a/spec/fixtures/track_streaming_user.json +++ b/spec/fixtures/track_streaming_user.json @@ -3,3 +3,4 @@ {"direct_message":{"id":389327745617891328,"id_str":"389327745617891328","text":"hello bot","sender":{"id":10083602,"id_str":"10083602","name":"Adam Bird","screen_name":"adambird","location":"Nottingham, UK","url":"http:\/\/about.me\/adambird", "description":"CEO @onediaryapp, ex @esendex CTO and co-founder, still cycling","protected":false,"followers_count":1286,"friends_count":850,"listed_count":51,"created_at":"Fri Nov 09 00:35:12 +0000 2007","favourites_count":93,"utc_offset":3600,"time_zone":"London","geo_enabled":true,"verified":false,"statuses_count":13480,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"C0DEED","profile_background_image_url":"http:\/\/abs.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_image_url_https":"https:\/\/abs.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/378800000477232297\/23d85bb78f71534eea1e1133fb771f86_normal.jpeg","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/378800000477232297\/23d85bb78f71534eea1e1133fb771f86_normal.jpeg","profile_link_color":"0084B4","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"default_profile":true,"default_profile_image":false,"following":false,"follow_request_sent":false,"notifications":false},"sender_id":10083602,"sender_id_str":"10083602","sender_screen_name":"adambird","recipient":{"id":1292911088,"id_str":"1292911088","name":"One Diary Bot","screen_name":"onediarybot","location":"","url":"http:\/\/www.onediary.com","description":"I'm the One Diary bot, here to help you with your life including personal cycling weather forecasts.","protected":false,"followers_count":113,"friends_count":148,"listed_count":1,"created_at":"Sat Mar 23 23:52:18 +0000 2013","favourites_count":0,"utc_offset":"","time_zone":"","geo_enabled":false,"verified":false,"statuses_count":7919,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"C0DEED","profile_background_image_url":"http:\/\/abs.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_image_url_https":"https:\/\/abs.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/3651575369\/090551d8dd92080198f707769239ff43_normal.jpeg","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/3651575369\/090551d8dd92080198f707769239ff43_normal.jpeg","profile_link_color":"0084B4","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"default_profile":true,"default_profile_image":false,"following":false,"follow_request_sent":false,"notifications":false},"recipient_id":1292911088,"recipient_id_str":"1292911088","recipient_screen_name":"onediarybot","created_at":"Sun Oct 13 09:52:22 +0000 2013","entities":{"hashtags":[],"symbols":[],"urls":[],"user_mentions":[]}}} {"event":"follow","source":{"id":10083602,"id_str":"10083602","name":"Adam Bird","screen_name":"adambird","location":"Nottingham, UK","url":"http://t.co/M1eaIKDQyz","description":"CEO @onediaryapp, ex @esendex CTO and co-founder, still cycling","protected":false,"followers_count":1295,"friends_count":850,"listed_count":53,"created_at":"Fri Nov 09 00:35:12 +0000 2007","favourites_count":93,"utc_offset":0,"time_zone":"London","geo_enabled":true,"verified":false,"statuses_count":13507,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"C0DEED","profile_background_image_url":"http://abs.twimg.com/images/themes/theme1/bg.png","profile_background_image_url_https":"https://abs.twimg.com/images/themes/theme1/bg.png","profile_background_tile":false,"profile_image_url":"http://pbs.twimg.com/profile_images/378800000477232297/23d85bb78f71534eea1e1133fb771f86_normal.jpeg","profile_image_url_https":"https://pbs.twimg.com/profile_images/378800000477232297/23d85bb78f71534eea1e1133fb771f86_normal.jpeg","profile_link_color":"0084B4","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"default_profile":true,"default_profile_image":false,"following":false,"follow_request_sent":false,"notifications":false},"target":{"id":1292911088,"id_str":"1292911088","name":"One Diary Bot","screen_name":"onediarybot","location":null,"url":"http://t.co/etHGc0xHX4","description":"I'm the One Diary bot, here to help you with your life including personal cycling weather forecasts.","protected":false,"followers_count":123,"friends_count":157,"listed_count":1,"created_at":"Sat Mar 23 23:52:18 +0000 2013","favourites_count":0,"utc_offset":null,"time_zone":null,"geo_enabled":false,"verified":false,"statuses_count":9637,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"C0DEED","profile_background_image_url":"http://abs.twimg.com/images/themes/theme1/bg.png","profile_background_image_url_https":"https://abs.twimg.com/images/themes/theme1/bg.png","profile_background_tile":false,"profile_image_url":"http://pbs.twimg.com/profile_images/3651575369/090551d8dd92080198f707769239ff43_normal.jpeg","profile_image_url_https":"https://pbs.twimg.com/profile_images/3651575369/090551d8dd92080198f707769239ff43_normal.jpeg","profile_link_color":"0084B4","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"default_profile":true,"default_profile_image":false,"following":false,"follow_request_sent":false,"notifications":false},"created_at":"Sun Oct 27 20:35:25 +0000 2013"} {"delete":{"status":{"id":272691609211117568,"user_id":478569062,"id_str":"272691609211117568","user_id_str":"478569062","deleted":true}}} +{"warning":{"code":"FALLING_BEHIND","message":"Your connection is falling behind and messages are being queued for delivery to you. Your queue is now over 60% full. You will be disconnected when the queue is full.","percent_full":60}} diff --git a/spec/twitter/streaming/client_spec.rb b/spec/twitter/streaming/client_spec.rb index 9bb799370..2de3a9d4e 100644 --- a/spec/twitter/streaming/client_spec.rb +++ b/spec/twitter/streaming/client_spec.rb @@ -77,7 +77,7 @@ def stream(request, response) @client.user do |item| items << item end - expect(items.size).to eq(5) + expect(items.size).to eq(6) expect(items[0]).to be_a Twitter::Streaming::FriendList expect(items[0]).to eq([488736931,311444249]) expect(items[1]).to be_a Twitter::Tweet @@ -88,6 +88,8 @@ def stream(request, response) expect(items[3].name).to eq(:follow) expect(items[4]).to be_a Twitter::Streaming::DeletedTweet expect(items[4].id).to eq(272691609211117568) + expect(items[5]).to be_a Twitter::Streaming::StallWarning + expect(items[5].code).to eq("FALLING_BEHIND") end end diff --git a/spec/twitter/streaming/deleted_tweet_spec.rb b/spec/twitter/streaming/deleted_tweet_spec.rb index d937f0505..2db9520f4 100644 --- a/spec/twitter/streaming/deleted_tweet_spec.rb +++ b/spec/twitter/streaming/deleted_tweet_spec.rb @@ -20,11 +20,4 @@ end end - describe "#user_id" do - it "returns the user ID" do - deleted_tweet = Twitter::Streaming::DeletedTweet.new(:id => 1, :user_id => 1) - expect(deleted_tweet.user_id).to eq(1) - end - end - end diff --git a/spec/twitter/streaming/message_parser_spec.rb b/spec/twitter/streaming/message_parser_spec.rb index 7d19e8d70..e4dbb6f1a 100644 --- a/spec/twitter/streaming/message_parser_spec.rb +++ b/spec/twitter/streaming/message_parser_spec.rb @@ -43,6 +43,12 @@ expect(object).to be_a Twitter::Streaming::DeletedTweet expect(object.id).to eq(1) end + it "returns a stall warning if the data has a warning" do + data = {:warning => {:code => "FALLING_BEHIND"}} + object = subject.parse(data) + expect(object).to be_a Twitter::Streaming::StallWarning + expect(object.code).to eq("FALLING_BEHIND") + end end end