twitter 6.2.0 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -7
  3. data/LICENSE.md +1 -1
  4. data/README.md +9 -12
  5. data/lib/twitter.rb +5 -0
  6. data/lib/twitter/client.rb +5 -5
  7. data/lib/twitter/creatable.rb +5 -1
  8. data/lib/twitter/cursor.rb +12 -2
  9. data/lib/twitter/direct_message.rb +2 -0
  10. data/lib/twitter/direct_message_event.rb +44 -0
  11. data/lib/twitter/direct_messages/welcome_message.rb +17 -0
  12. data/lib/twitter/direct_messages/welcome_message_rule.rb +12 -0
  13. data/lib/twitter/direct_messages/welcome_message_rule_wrapper.rb +36 -0
  14. data/lib/twitter/direct_messages/welcome_message_wrapper.rb +42 -0
  15. data/lib/twitter/enumerable.rb +14 -3
  16. data/lib/twitter/error.rb +48 -6
  17. data/lib/twitter/null_object.rb +15 -1
  18. data/lib/twitter/premium_search_results.rb +67 -0
  19. data/lib/twitter/profile.rb +2 -2
  20. data/lib/twitter/rate_limit.rb +2 -2
  21. data/lib/twitter/rest/account_activity.rb +99 -0
  22. data/lib/twitter/rest/api.rb +6 -0
  23. data/lib/twitter/rest/direct_messages.rb +131 -42
  24. data/lib/twitter/rest/direct_messages/welcome_messages.rb +90 -0
  25. data/lib/twitter/rest/favorites.rb +2 -2
  26. data/lib/twitter/rest/lists.rb +1 -0
  27. data/lib/twitter/rest/premium_search.rb +34 -0
  28. data/lib/twitter/rest/request.rb +39 -13
  29. data/lib/twitter/rest/search.rb +4 -3
  30. data/lib/twitter/rest/timelines.rb +1 -0
  31. data/lib/twitter/rest/tweets.rb +2 -31
  32. data/lib/twitter/rest/upload_utils.rb +68 -0
  33. data/lib/twitter/rest/utils.rb +24 -7
  34. data/lib/twitter/search_results.rb +4 -3
  35. data/lib/twitter/streaming/client.rb +5 -1
  36. data/lib/twitter/streaming/connection.rb +16 -3
  37. data/lib/twitter/streaming/message_parser.rb +1 -1
  38. data/lib/twitter/streaming/response.rb +1 -0
  39. data/lib/twitter/tweet.rb +10 -1
  40. data/lib/twitter/utils.rb +4 -2
  41. data/lib/twitter/version.rb +2 -2
  42. data/twitter.gemspec +3 -4
  43. metadata +16 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6c1797367fcb91dca015c7a77acd6273beb4c49e929c98d2d3a913ea37009496
4
- data.tar.gz: 3c4a9f1fca5d3e99b9be0cb8993c4f274cb309b8fc19b2f3cf45838622484bce
3
+ metadata.gz: 578178613b24f694731c9b87c940488762c35a0f4027b57bbd518bd9f914469c
4
+ data.tar.gz: 4ad56cc9e3c49d60cdc9f60777f37070cd6d933cd53bb2b2a9e82fe6f6f5f193
5
5
  SHA512:
6
- metadata.gz: 887f6a6acfb58cd602fe1507c66e12fcb53c5b7479054a91e0ca68ee0c2a227c620b8bab614d256e4dfb31015cdc5c85fe8bdf9f05e9f48b8c38c8d945fbbf1e
7
- data.tar.gz: 631417a20ae3bca7970e05f6a63c6049af3c613b0f078a6d178d81f13750ff4a885514aa882be050a94f3909dc24df8df084fbc816bec280a9e7963fb7ab3750
6
+ metadata.gz: e9e85b61e8f806fda08720a1b3290370bf1824bd5afba0f2afce2e3d29956dafaa60ae500299349863e320074d4c8944046dd98b065d7f9900c7eb4e896fa05f
7
+ data.tar.gz: a10adbd38f44ba009ca21230a3a439f3b246bc84779aa9f80161643efb36e6abebeeb0d648257d1a29ccb1a65b06de445eac523aff36137e045cb40beae0246c
@@ -1,25 +1,37 @@
1
- 6.2.0
1
+ 7.0.0
2
2
  ------
3
+ * [Add `Twitter::DirectMessageEvent`](https://github.com/sferik/twitter/commit/38f6aaa482dcd5f4982abd811dbe6e21e36c2ae8) ([@FabienChaynes](https://twitter.com/FabienChaynes))
4
+ * [Create `Twitter::DirectMessageEvent` with media](https://github.com/sferik/twitter/commit/21478530ec6f8a798717a5ab8b197b895db3bc28) ([@FabienChaynes](https://twitter.com/FabienChaynes))
5
+ * [Support for DM welcome messages](https://github.com/sferik/twitter/pull/950) ([@FabienChaynes](https://twitter.com/FabienChaynes))
6
+ * [Support for closing `Twitter::Streaming::Connection`](https://github.com/sferik/twitter/commit/89e3543aa06e00eeab7eaf5bdd3a33a6112356b1) ([@okkez](https://twitter.com/okkez))
7
+ * [Add `Twitter::REST::Client#create_direct_message_event`](https://github.com/sferik/twitter/commit/b45d545c7ebfd28e4d908037dd3fde04e3c307cf) ([@cyu](https://twitter.com/cyu))
8
+ * [Add `Twitter::REST::Client#premium_search`](https://github.com/sferik/twitter/pull/953)
9
+ * [Add `Twitter::REST::AccountActivity`](https://github.com/sferik/twitter/pull/939)
10
+ * [Update all direct message methods to return `Twitter::DirectMessageEvent`](https://github.com/sferik/twitter/commit/0833471366a33657cd2920850e3928db010eecab) ([@flikglick](https://twitter.com/flikglick))
11
+ * [Correctly handle different `Twitter::Error::AlreadyRetweeted` error messages](https://github.com/sferik/twitter/commit/c9bf100eedc89aee43689c17f160025e0f40cfb4) ([@knu](https://twitter.com/knu))
12
+ * [Fix proxy setting sample](https://github.com/sferik/twitter/commit/91c037cfb26ac0c9d3099cdeec42d65fe8716b78) ([@nicklegr](https://twitter.com/nicklegr))
13
+ * [Add Active Support `presence` methods on `Twitter::NullObject`](https://github.com/sferik/twitter/commit/07a5d7b60f335aefd583dae85ba959235bc9f55f) ([@davebrace](https://twitter.com/davebrace))
14
+ * [Upload GIFs over 5MB in chunks](https://github.com/sferik/twitter/commit/ba6a3062782b37cf83b9813c5128c87d4971ab9c) ([@wild_dmitry](https://twitter.com/wild_dmitry))
15
+ * [Track rate limit when searching tweets](https://github.com/sferik/twitter/commit/067e751d58b7bb0bfbe8a5531a4288f4c966b301) ([@dsalahutdinov1](https://twitter.com/dsalahutdinov1))
16
+ * [Add `quote_count` and `reply_count` attributes to `Twitter::Tweet`](https://github.com/sferik/twitter/commit/844818cad07ce490ccb9d8542ebb6b4fc7a61cb4)
17
+ * [Drop support for Ruby 2.0, 2.1, and 2.2](https://github.com/sferik/twitter/commit/95861ec83e582c2a88499b97d9d5388a96d0abf0)
3
18
 
19
+ 6.2.0
20
+ ------
4
21
  Not yet documented, sorry. For now, please use git to compare tags:
5
22
  https://github.com/sferik/twitter/compare/v6.1.0...v6.2.0
6
23
 
7
24
  6.1.0
8
25
  ------
9
-
10
26
  Not yet documented, sorry. For now, please use git to compare tags:
11
27
  https://github.com/sferik/twitter/compare/v6.0.0...v6.1.0
12
28
 
13
-
14
29
  6.0.0
15
30
  ------
16
-
17
- Not yet documented, sorry. For now, please use git to compare tags:
18
- https://github.com/sferik/twitter/compare/v5.16.0...v6.0.0
31
+ * [Drop support for Ruby 1.8.7 and Ruby 1.9.3](https://github.com/sferik/twitter/commit/27980f45fb357e34b86e46cb9134d86ed29b3ce3)
19
32
 
20
33
  5.16.0
21
34
  ------
22
-
23
35
  * [Add Twitter::Trend#tweet_volume](https://github.com/sferik/twitter/commit/e797b62e5e6a768e8aeafde6186e1f5310e6bfc6)
24
36
  * [Add new settings to Twitter::Settings](https://github.com/sferik/twitter/commit/d047ce00034d26a99927076c28679ce08fd69308)
25
37
  * [Fix `Version.to_a`](https://github.com/sferik/twitter/commit/0cd119abf64e6c2b7fd861b0df65b7cb41d892b4)
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2006-2016 Erik Michaels-Ober, John Nunemaker, Wynn Netherland, Steve Richert, Steve Agalloco
1
+ Copyright (c) 2006-2020 Erik Berlin, John Nunemaker, Wynn Netherland, Steve Richert, Steve Agalloco
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,16 +1,14 @@
1
1
  # The Twitter Ruby Gem
2
2
 
3
- [![Gem Version](http://img.shields.io/gem/v/twitter.svg)][gem]
4
- [![Build Status](http://img.shields.io/travis/sferik/twitter.svg)][travis]
5
- [![Dependency Status](http://img.shields.io/gemnasium/sferik/twitter.svg)][gemnasium]
6
- [![Code Climate](http://img.shields.io/codeclimate/github/sferik/twitter.svg)][codeclimate]
7
- [![Coverage Status](http://img.shields.io/coveralls/sferik/twitter.svg)][coveralls]
3
+ [![Gem Version](https://badge.fury.io/rb/twitter.svg)][gem]
4
+ [![Build Status](https://travis-ci.org/sferik/twitter.svg?branch=master)][travis]
5
+ [![Maintainability](https://api.codeclimate.com/v1/badges/09362621ad91e8f599b3/maintainability)][maintainability]
6
+ [![Coverage Status](https://coveralls.io/repos/github/sferik/twitter/badge.svg?branch=master)][coveralls]
8
7
  [![Inline docs](http://inch-ci.org/github/sferik/twitter.svg?style=shields)][inchpages]
9
8
 
10
9
  [gem]: https://rubygems.org/gems/twitter
11
10
  [travis]: https://travis-ci.org/sferik/twitter
12
- [gemnasium]: https://gemnasium.com/sferik/twitter
13
- [codeclimate]: https://codeclimate.com/github/sferik/twitter
11
+ [maintainability]: https://codeclimate.com/github/sferik/twitter/maintainability
14
12
  [coveralls]: https://coveralls.io/r/sferik/twitter
15
13
  [inchpages]: http://inch-ci.org/github/sferik/twitter
16
14
 
@@ -231,11 +229,10 @@ command:
231
229
  This library aims to support and is [tested against][travis] the following Ruby
232
230
  versions:
233
231
 
234
- * Ruby 2.0.0
235
- * Ruby 2.1
236
- * Ruby 2.2
237
- * Ruby 2.3
238
- * JRuby 9.1.6.0
232
+ * Ruby 2.4
233
+ * Ruby 2.5
234
+ * Ruby 2.6
235
+ * Ruby 2.7
239
236
 
240
237
  If something doesn't work on one of these versions, it's a bug.
241
238
 
@@ -20,6 +20,7 @@ require 'twitter/relationship'
20
20
  require 'twitter/rest/client'
21
21
  require 'twitter/saved_search'
22
22
  require 'twitter/search_results'
23
+ require 'twitter/premium_search_results'
23
24
  require 'twitter/settings'
24
25
  require 'twitter/size'
25
26
  require 'twitter/source_user'
@@ -29,3 +30,7 @@ require 'twitter/target_user'
29
30
  require 'twitter/trend'
30
31
  require 'twitter/tweet'
31
32
  require 'twitter/user'
33
+ require 'twitter/direct_messages/welcome_message'
34
+ require 'twitter/direct_messages/welcome_message_rule'
35
+ require 'twitter/direct_messages/welcome_message_rule_wrapper'
36
+ require 'twitter/direct_messages/welcome_message_wrapper'
@@ -5,7 +5,7 @@ require 'twitter/version'
5
5
  module Twitter
6
6
  class Client
7
7
  include Twitter::Utils
8
- attr_accessor :access_token, :access_token_secret, :consumer_key, :consumer_secret, :proxy, :timeouts
8
+ attr_accessor :access_token, :access_token_secret, :consumer_key, :consumer_secret, :proxy, :timeouts, :dev_environment
9
9
  attr_writer :user_agent
10
10
 
11
11
  # Initializes a new Client object
@@ -21,7 +21,7 @@ module Twitter
21
21
 
22
22
  # @return [Boolean]
23
23
  def user_token?
24
- !(blank?(access_token) || blank?(access_token_secret))
24
+ !(blank_string?(access_token) || blank_string?(access_token_secret))
25
25
  end
26
26
 
27
27
  # @return [String]
@@ -41,13 +41,13 @@ module Twitter
41
41
 
42
42
  # @return [Boolean]
43
43
  def credentials?
44
- credentials.values.none? { |v| blank?(v) }
44
+ credentials.values.none? { |v| blank_string?(v) }
45
45
  end
46
46
 
47
47
  private
48
48
 
49
- def blank?(s)
50
- s.respond_to?(:empty?) ? s.empty? : !s
49
+ def blank_string?(string)
50
+ string.respond_to?(:empty?) ? string.empty? : !string
51
51
  end
52
52
  end
53
53
  end
@@ -9,7 +9,11 @@ module Twitter
9
9
  #
10
10
  # @return [Time]
11
11
  def created_at
12
- Time.parse(@attrs[:created_at]).utc unless @attrs[:created_at].nil?
12
+ time = @attrs[:created_at]
13
+ return if time.nil?
14
+
15
+ time = Time.parse(time) unless time.is_a?(Time)
16
+ time.utc
13
17
  end
14
18
  memoize :created_at
15
19
 
@@ -16,8 +16,9 @@ module Twitter
16
16
  # @param key [String, Symbol] The key to fetch the data from the response
17
17
  # @param klass [Class] The class to instantiate objects in the response
18
18
  # @param request [Twitter::REST::Request]
19
+ # @param limit [Integer] After reaching the limit, we stop fetching next page
19
20
  # @return [Twitter::Cursor]
20
- def initialize(key, klass, request)
21
+ def initialize(key, klass, request, limit = nil)
21
22
  @key = key.to_sym
22
23
  @klass = klass
23
24
  @client = request.client
@@ -25,6 +26,7 @@ module Twitter
25
26
  @path = request.path
26
27
  @options = request.options
27
28
  @collection = []
29
+ @limit = limit
28
30
  self.attrs = request.perform
29
31
  end
30
32
 
@@ -32,15 +34,23 @@ module Twitter
32
34
 
33
35
  # @return [Integer]
34
36
  def next_cursor
35
- @attrs[:next_cursor] || -1
37
+ @attrs[:next_cursor]
36
38
  end
37
39
  alias next next_cursor
38
40
 
39
41
  # @return [Boolean]
40
42
  def last?
43
+ return false if next_cursor.is_a?(String)
44
+ return true if next_cursor.nil?
45
+
41
46
  next_cursor.zero?
42
47
  end
43
48
 
49
+ # @return [Boolean]
50
+ def reached_limit?
51
+ @limit && @limit <= attrs[@key].count
52
+ end
53
+
44
54
  # @return [Hash]
45
55
  def fetch_next_page
46
56
  response = Twitter::REST::Request.new(@client, @request_method, @path, @options.merge(cursor: next_cursor)).perform
@@ -8,6 +8,8 @@ module Twitter
8
8
  include Twitter::Entities
9
9
  # @return [String]
10
10
  attr_reader :text
11
+ attr_reader :sender_id
12
+ attr_reader :recipient_id
11
13
  alias full_text text
12
14
  object_attr_reader :User, :recipient
13
15
  object_attr_reader :User, :sender
@@ -0,0 +1,44 @@
1
+ require 'twitter/creatable'
2
+ require 'twitter/entities'
3
+ require 'twitter/identity'
4
+
5
+ module Twitter
6
+ class DirectMessageEvent < Twitter::Identity
7
+ include Twitter::Creatable
8
+ include Twitter::Entities
9
+
10
+ attr_reader :created_timestamp
11
+
12
+ object_attr_reader :DirectMessage, :direct_message
13
+
14
+ def initialize(attrs)
15
+ attrs = read_from_response(attrs)
16
+ text = attrs.dig(:message_create, :message_data, :text)
17
+ urls = attrs.dig(:message_create, :message_data, :entities, :urls)
18
+
19
+ text.gsub!(urls[0][:url], urls[0][:expanded_url]) if urls.any?
20
+
21
+ attrs[:direct_message] = build_direct_message(attrs, text)
22
+ super
23
+ end
24
+
25
+ private
26
+
27
+ # @return [Hash] Normalized hash of attrs
28
+ def read_from_response(attrs)
29
+ attrs[:event].nil? ? attrs : attrs[:event]
30
+ end
31
+
32
+ def build_direct_message(attrs, text)
33
+ recipient_id = attrs[:message_create][:target][:recipient_id].to_i
34
+ sender_id = attrs[:message_create][:sender_id].to_i
35
+ {id: attrs[:id].to_i,
36
+ created_at: Time.at(attrs[:created_timestamp].to_i / 1000.0),
37
+ sender: {id: sender_id},
38
+ sender_id: sender_id,
39
+ recipient: {id: recipient_id},
40
+ recipient_id: recipient_id,
41
+ text: text}
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,17 @@
1
+ require 'twitter/creatable'
2
+ require 'twitter/entities'
3
+ require 'twitter/identity'
4
+
5
+ module Twitter
6
+ module DirectMessages
7
+ class WelcomeMessage < Twitter::Identity
8
+ include Twitter::Creatable
9
+ include Twitter::Entities
10
+ # @return [String]
11
+ attr_reader :text
12
+ # @return [String]
13
+ attr_reader :name
14
+ alias full_text text
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,12 @@
1
+ require 'twitter/creatable'
2
+ require 'twitter/identity'
3
+
4
+ module Twitter
5
+ module DirectMessages
6
+ class WelcomeMessageRule < Twitter::Identity
7
+ include Twitter::Creatable
8
+ # @return [Integer]
9
+ attr_reader :welcome_message_id
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,36 @@
1
+ require 'twitter/creatable'
2
+ require 'twitter/identity'
3
+
4
+ module Twitter
5
+ module DirectMessages
6
+ class WelcomeMessageRuleWrapper < Twitter::Identity
7
+ attr_reader :created_timestamp
8
+
9
+ object_attr_reader 'DirectMessages::WelcomeMessageRule', :welcome_message_rule
10
+
11
+ def initialize(attrs)
12
+ attrs = read_from_response(attrs)
13
+
14
+ attrs[:welcome_message_rule] = build_welcome_message_rule(attrs)
15
+ super
16
+ end
17
+
18
+ private
19
+
20
+ # @return [Hash] Normalized hash of attrs
21
+ def read_from_response(attrs)
22
+ return attrs[:welcome_message_rule] unless attrs[:welcome_message_rule].nil?
23
+
24
+ attrs
25
+ end
26
+
27
+ def build_welcome_message_rule(attrs)
28
+ {
29
+ id: attrs[:id].to_i,
30
+ created_at: Time.at(attrs[:created_timestamp].to_i / 1000.0),
31
+ welcome_message_id: attrs[:welcome_message_id].to_i,
32
+ }
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,42 @@
1
+ require 'twitter/creatable'
2
+ require 'twitter/identity'
3
+
4
+ module Twitter
5
+ module DirectMessages
6
+ class WelcomeMessageWrapper < Twitter::Identity
7
+ attr_reader :created_timestamp
8
+
9
+ object_attr_reader 'DirectMessages::WelcomeMessage', :welcome_message
10
+
11
+ def initialize(attrs)
12
+ attrs = read_from_response(attrs)
13
+ text = attrs.dig(:message_data, :text)
14
+ urls = attrs.dig(:message_data, :entities, :urls)
15
+
16
+ text.gsub!(urls[0][:url], urls[0][:expanded_url]) if urls.any?
17
+
18
+ attrs[:welcome_message] = build_welcome_message(attrs, text)
19
+ super
20
+ end
21
+
22
+ private
23
+
24
+ # @return [Hash] Normalized hash of attrs
25
+ def read_from_response(attrs)
26
+ return attrs[:welcome_message] unless attrs[:welcome_message].nil?
27
+
28
+ attrs
29
+ end
30
+
31
+ def build_welcome_message(attrs, text)
32
+ {
33
+ id: attrs[:id].to_i,
34
+ created_at: Time.at(attrs[:created_timestamp].to_i / 1000.0),
35
+ text: text,
36
+ name: attrs[:name],
37
+ entities: attrs.dig(:message_data, :entities),
38
+ }
39
+ end
40
+ end
41
+ end
42
+ end
@@ -3,15 +3,16 @@ module Twitter
3
3
  include ::Enumerable
4
4
 
5
5
  # @return [Enumerator]
6
- def each(start = 0)
6
+ def each(start = 0, &block)
7
7
  return to_enum(:each, start) unless block_given?
8
+
8
9
  Array(@collection[start..-1]).each do |element|
9
10
  yield(element)
10
11
  end
11
- unless last?
12
+ unless finished?
12
13
  start = [@collection.size, start].max
13
14
  fetch_next_page
14
- each(start, &Proc.new)
15
+ each(start, &block)
15
16
  end
16
17
  self
17
18
  end
@@ -22,5 +23,15 @@ module Twitter
22
23
  def last?
23
24
  true
24
25
  end
26
+
27
+ # @return [Boolean]
28
+ def reached_limit?
29
+ false
30
+ end
31
+
32
+ # @return [Boolean]
33
+ def finished?
34
+ last? || reached_limit?
35
+ end
25
36
  end
26
37
  end
@@ -59,6 +59,21 @@ module Twitter
59
59
  # Raised when Twitter returns the HTTP status code 504
60
60
  GatewayTimeout = Class.new(ServerError)
61
61
 
62
+ # Raised when Twitter returns a media related error
63
+ MediaError = Class.new(self)
64
+
65
+ # Raised when Twitter returns an InvalidMedia error
66
+ InvalidMedia = Class.new(MediaError)
67
+
68
+ # Raised when Twitter returns a media InternalError error
69
+ MediaInternalError = Class.new(MediaError)
70
+
71
+ # Raised when Twitter returns an UnsupportedMedia error
72
+ UnsupportedMedia = Class.new(MediaError)
73
+
74
+ # Raised when an operation subject to timeout takes too long
75
+ TimeoutError = Class.new(self)
76
+
62
77
  ERRORS = {
63
78
  400 => Twitter::Error::BadRequest,
64
79
  401 => Twitter::Error::Unauthorized,
@@ -74,14 +89,29 @@ module Twitter
74
89
  504 => Twitter::Error::GatewayTimeout,
75
90
  }.freeze
76
91
 
77
- FORBIDDEN_MESSAGES = {
78
- 'Status is a duplicate.' => Twitter::Error::DuplicateStatus,
79
- 'You have already favorited this status.' => Twitter::Error::AlreadyFavorited,
80
- 'You have already retweeted this tweet.' => Twitter::Error::AlreadyRetweeted,
81
- 'sharing is not permissible for this status (Share validations failed)' => Twitter::Error::AlreadyRetweeted,
92
+ FORBIDDEN_MESSAGES = proc do |message|
93
+ case message
94
+ when /(?=.*status).*duplicate/i
95
+ # - "Status is a duplicate."
96
+ Twitter::Error::DuplicateStatus
97
+ when /already favorited/i
98
+ # - "You have already favorited this status."
99
+ Twitter::Error::AlreadyFavorited
100
+ when /already retweeted|Share validations failed/i
101
+ # - "You have already retweeted this Tweet." (Nov 2017-)
102
+ # - "You have already retweeted this tweet." (?-Nov 2017)
103
+ # - "sharing is not permissible for this status (Share validations failed)" (-? 2017)
104
+ Twitter::Error::AlreadyRetweeted
105
+ end
106
+ end
107
+
108
+ MEDIA_ERRORS = {
109
+ 'InternalError' => Twitter::Error::MediaInternalError,
110
+ 'InvalidMedia' => Twitter::Error::InvalidMedia,
111
+ 'UnsupportedMedia' => Twitter::Error::UnsupportedMedia,
82
112
  }.freeze
83
113
 
84
- # If error code is missing see https://dev.twitter.com/overview/api/response-codes
114
+ # If error code is missing see https://developer.twitter.com/en/docs/basics/response-codes
85
115
  module Code
86
116
  AUTHENTICATION_PROBLEM = 32
87
117
  RESOURCE_NOT_FOUND = 34
@@ -122,6 +152,18 @@ module Twitter
122
152
  new(message, headers, code)
123
153
  end
124
154
 
155
+ # Create a new error from a media error hash
156
+ #
157
+ # @param error [Hash]
158
+ # @param headers [Hash]
159
+ # @return [Twitter::MediaError]
160
+ def from_processing_response(error, headers)
161
+ klass = MEDIA_ERRORS[error[:name]] || self
162
+ message = error[:message]
163
+ code = error[:code]
164
+ klass.new(message, headers, code)
165
+ end
166
+
125
167
  private
126
168
 
127
169
  def parse_error(body)