chatbot_helper-telegram 0.1.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 (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +129 -0
  3. data/.travis.yml +14 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +128 -0
  7. data/Rakefile +10 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +8 -0
  10. data/chatbot_helper-telegram.gemspec +43 -0
  11. data/lib/chatbot_helper/exceptions.rb +27 -0
  12. data/lib/chatbot_helper/telegram.rb +47 -0
  13. data/lib/chatbot_helper/telegram/animation.rb +22 -0
  14. data/lib/chatbot_helper/telegram/audio.rb +16 -0
  15. data/lib/chatbot_helper/telegram/base_resource.rb +254 -0
  16. data/lib/chatbot_helper/telegram/callback_game.rb +11 -0
  17. data/lib/chatbot_helper/telegram/callback_query.rb +29 -0
  18. data/lib/chatbot_helper/telegram/chat.rb +16 -0
  19. data/lib/chatbot_helper/telegram/chat_member.rb +18 -0
  20. data/lib/chatbot_helper/telegram/chosen_inline_result.rb +29 -0
  21. data/lib/chatbot_helper/telegram/collection_resource.rb +50 -0
  22. data/lib/chatbot_helper/telegram/contact.rb +16 -0
  23. data/lib/chatbot_helper/telegram/document.rb +22 -0
  24. data/lib/chatbot_helper/telegram/file.rb +16 -0
  25. data/lib/chatbot_helper/telegram/force_reply.rb +16 -0
  26. data/lib/chatbot_helper/telegram/game.rb +35 -0
  27. data/lib/chatbot_helper/telegram/inline_keyboard_button.rb +36 -0
  28. data/lib/chatbot_helper/telegram/inline_keyboard_markup.rb +16 -0
  29. data/lib/chatbot_helper/telegram/inline_query.rb +24 -0
  30. data/lib/chatbot_helper/telegram/keyboard_button.rb +69 -0
  31. data/lib/chatbot_helper/telegram/location.rb +12 -0
  32. data/lib/chatbot_helper/telegram/message.rb +55 -0
  33. data/lib/chatbot_helper/telegram/message_entity.rb +23 -0
  34. data/lib/chatbot_helper/telegram/photo_size.rb +25 -0
  35. data/lib/chatbot_helper/telegram/reply_keyboard_markup.rb +20 -0
  36. data/lib/chatbot_helper/telegram/reply_keyboard_remove.rb +17 -0
  37. data/lib/chatbot_helper/telegram/response_parameters.rb +13 -0
  38. data/lib/chatbot_helper/telegram/sticker.rb +22 -0
  39. data/lib/chatbot_helper/telegram/toolbox.rb +27 -0
  40. data/lib/chatbot_helper/telegram/update.rb +28 -0
  41. data/lib/chatbot_helper/telegram/user.rb +16 -0
  42. data/lib/chatbot_helper/telegram/user_profile_photos.rb +20 -0
  43. data/lib/chatbot_helper/telegram/venue.rb +22 -0
  44. data/lib/chatbot_helper/telegram/version.rb +5 -0
  45. data/lib/chatbot_helper/telegram/video.rb +22 -0
  46. data/lib/chatbot_helper/telegram/voice.rb +16 -0
  47. metadata +176 -0
@@ -0,0 +1,22 @@
1
+ module ChatbotHelper
2
+ module Telegram
3
+ # The animation resource which represents a Telegram bot API animation
4
+ class Animation < ChatbotHelper::Telegram::BaseResource
5
+ class << self
6
+ def required_fields
7
+ %w[file_id]
8
+ end
9
+
10
+ def optional_fields
11
+ %w[file_name mime_type mime_type]
12
+ end
13
+
14
+ def optional_objects
15
+ [
16
+ { name: 'thumb', type: ChatbotHelper::Telegram::PhotoSize }
17
+ ]
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ module ChatbotHelper
2
+ module Telegram
3
+ # The audio resource which represents a Telegram bot API audio
4
+ class Audio < ChatbotHelper::Telegram::BaseResource
5
+ class << self
6
+ def required_fields
7
+ %w[file_id duration]
8
+ end
9
+
10
+ def optional_fields
11
+ %w[performer title mime_type file_size]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,254 @@
1
+ module ChatbotHelper
2
+ module Telegram
3
+ # A base resource class for Telegram bot API resources.
4
+ class BaseResource
5
+ class << self
6
+ # Returns an array of words which represent the required fields
7
+ # for this resource
8
+ #
9
+ # Fields are primitive data types like +String+, +Integer+, +Boolean+
10
+ # and +Float+ or arrays of primitive data types.
11
+ # If you have more complex types like +Object+ or arrays of +Object+s,
12
+ # see {required_objects}, {optional_objects}, {required_arrays} and
13
+ # {optional_arrays}.
14
+ #
15
+ # @return [Array<String>] The required fields for this resource
16
+ def required_fields
17
+ %w[]
18
+ end
19
+
20
+ # Returns an array of words which represent the optional fields
21
+ # for this resource
22
+ #
23
+ # Fields are primitive data types like +String+, +Integer+, +Boolean+
24
+ # and +Float+ or arrays of primitive data types.
25
+ # If you have more complex types like +Object+ or arrays of +Object+s,
26
+ # see {required_objects}, {optional_objects}, {required_arrays} and
27
+ # {optional_arrays}.
28
+ #
29
+ # @return [Array<String>] The optional fields for this resource
30
+ def optional_fields
31
+ %w[]
32
+ end
33
+
34
+ # Returns an array of hashes which represent the required objects
35
+ # for this resource
36
+ #
37
+ # The hashes must follow the following structure:
38
+ #
39
+ # +{ name: 'field_name', type: 'ChatbotHelper::Telegram::FieldType' }+
40
+ #
41
+ # where +type+ represents the type of the resulting object which must
42
+ # be a subclass of +ChatbotHelper::Telegram::BaseResource+
43
+ #
44
+ # @return [Array<Hash>] The required objects for this resource
45
+ def required_objects
46
+ []
47
+ end
48
+
49
+ # Returns an array of hashes which represent the optional objects
50
+ # for this resource
51
+ #
52
+ # The hashes must follow the following structure:
53
+ #
54
+ # +{ name: 'field_name', type: 'ChatbotHelper::Telegram::FieldType' }+
55
+ #
56
+ # where +type+ represents the type of the resulting object which must
57
+ # be a subclass of +ChatbotHelper::Telegram::BaseResource+
58
+ #
59
+ # @return [Array<Hash>] The optional objects for this resource
60
+ def optional_objects
61
+ []
62
+ end
63
+
64
+ # Returns an array of hashes which represent the required arrays
65
+ # for this resource
66
+ #
67
+ # The hashes must follow the following structure:
68
+ #
69
+ # +{ name: 'field_name', type: 'ChatbotHelper::Telegram::FieldType' }+
70
+ #
71
+ # where +type+ represents the type of the resulting objects in the
72
+ # array, which must be a subclass of
73
+ # +ChatbotHelper::Telegram::BaseResource+
74
+ #
75
+ # Arrays are arrays of complex objects. If you have arrays of primitive
76
+ # data types see {required_fields} and {optional_fields}.
77
+ #
78
+ # @return [Array<Hash>] The required arrays for this resource
79
+ def required_arrays
80
+ []
81
+ end
82
+
83
+ # Returns an array of hashes which represent the optional arrays
84
+ # for this resource
85
+ #
86
+ # The hashes must follow the following structure:
87
+ #
88
+ # +{ name: 'field_name', type: 'ChatbotHelper::Telegram::FieldType' }+
89
+ #
90
+ # where +type+ represents the type of the resulting objects in the
91
+ # array, which must be a subclass of
92
+ # +ChatbotHelper::Telegram::BaseResource+
93
+ #
94
+ # Arrays are arrays of complex objects. If you have arrays of primitive
95
+ # data types see {required_fields} and {optional_fields}.
96
+ #
97
+ # @return [Array<Hash>] The optional arrays for this resource
98
+ def optional_arrays
99
+ []
100
+ end
101
+
102
+ # Checks a given Hash and returns true iff it is a valid bot Resource as
103
+ # defined in the Telegram bot documentation. Returns false otherwise.
104
+ #
105
+ # See https://core.telegram.org/bots/api for more information
106
+ # about the resource structures.
107
+ #
108
+ # @param resource [Hash] The resource representing the Telegram bot API resource as a hash with stringified keys
109
+ # @return [Boolean] True iff the given resource represents this resource as described in the Telegram bot API.
110
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
111
+ # rubocop:disable Metrics/CyclomaticComplexity
112
+ def valid_resource?(resource)
113
+ return false if resource.nil? || !resource.respond_to?('[]')
114
+
115
+ required_fields.each do |f|
116
+ return false if resource[f].nil?
117
+ end
118
+
119
+ required_objects.each do |o|
120
+ return false unless o[:type].valid_resource?(resource[o[:name]])
121
+ end
122
+
123
+ required_arrays.each do |a|
124
+ arr = resource[a[:name]]
125
+ return false unless arr.respond_to?('each')
126
+ arr.each do |el|
127
+ return false unless a[:type].valid_resource?(el)
128
+ end
129
+ end
130
+
131
+ # All tests passed. Return true...
132
+ true
133
+ end
134
+
135
+ # Checks a given Hash and returns true iff it is a valid bot Resource as
136
+ # defined in the Telegram bot documentation. Raises an exception
137
+ # otherwise.
138
+ #
139
+ # See https://core.telegram.org/bots/api for more information
140
+ # about the resource structures.
141
+ #
142
+ # @param resource [Hash] The resource representing the Telegram bot API resource as a hash with stringified keys
143
+ # @return [Boolean] True iff the given resource represents this resource as described in the Telegram bot API.
144
+ def valid_resource!(resource)
145
+ if valid_resource?(resource)
146
+ true
147
+ else
148
+ m = 'The given resource is not valid or does not follow its '\
149
+ 'specification from the Telegram bot API'
150
+ raise ChatbotHelper::Exceptions::InvalidResource.new(m), m
151
+ end
152
+ end
153
+ end
154
+
155
+ attr_reader :hash
156
+
157
+ # Initializes a new resource object with the given json String or hash.
158
+ #
159
+ # Either +hash+ or +string+ should be set but not both. It is recommended
160
+ # to pass +string+ instead of an already deserialized hash (+hash+) to the
161
+ # initializer.
162
+ #
163
+ # @param hash [Hash] A hash which represents this resource as described in the telegram bot api. Defaults to nil.
164
+ # @param string [String] A json String which represents this resource as described in the telegram bot api. Defaults to nil.
165
+ def initialize(hash: nil, string: nil)
166
+ @toolbox = ChatbotHelper::Telegram::Toolbox
167
+ @hash = hash.nil? ? @toolbox.parse_json(string) : @toolbox.parse_json(@toolbox.generate_json(hash))
168
+
169
+ # Validate resource
170
+ self.class.valid_resource!(@hash)
171
+
172
+ # Implement getters
173
+ implement_field_accessors
174
+ implement_object_accessors
175
+ implement_array_accessors
176
+ end
177
+
178
+ def to_s
179
+ @toolbox.generate_json(@hash)
180
+ end
181
+
182
+ alias to_json to_s
183
+
184
+ def ==(other)
185
+ other.is_a?(ChatbotHelper::Telegram::BaseResource) ?
186
+ @hash == other.hash :
187
+ @hash == other
188
+ end
189
+
190
+ alias eql? ==
191
+
192
+ protected
193
+
194
+ def implement_field_accessors
195
+ self.class.required_fields.each do |f|
196
+ define_singleton_method(f) do
197
+ return @hash[f]
198
+ end
199
+ end
200
+
201
+ self.class.optional_fields.each do |f|
202
+ define_singleton_method(f) do
203
+ return @hash[f]
204
+ end
205
+ end
206
+ end
207
+
208
+ def implement_object_accessors
209
+ self.class.required_objects.each do |o|
210
+ res = o[:type].new(hash: @hash[o[:name]])
211
+ define_singleton_method(o[:name]) do
212
+ return res
213
+ end
214
+ end
215
+
216
+ # Optional objects mus be either nil or a valid resource
217
+ self.class.optional_objects.each do |o|
218
+ res = nil
219
+ res_val = @hash[o[:name]]
220
+ res = o[:type].new(hash: res_val) unless res_val.nil?
221
+ define_singleton_method(o[:name]) do
222
+ return res
223
+ end
224
+ end
225
+ end
226
+
227
+ def implement_array_accessors
228
+ self.class.required_arrays.each do |a|
229
+ elements = []
230
+ @hash[a[:name]].each do |el|
231
+ elements << a[:type].new(hash: el)
232
+ end
233
+ define_singleton_method(a[:name]) do
234
+ return elements
235
+ end
236
+ end
237
+
238
+ # Optional arrays must be either nil or arrays of valid resources
239
+ self.class.optional_arrays.each do |a|
240
+ elements = []
241
+ arr_val = @hash[a[:name]]
242
+ unless arr_val.nil?
243
+ arr_val.each do |el|
244
+ elements << a[:type].new(hash: el)
245
+ end
246
+ end
247
+ define_singleton_method(a[:name]) do
248
+ return elements
249
+ end
250
+ end
251
+ end
252
+ end
253
+ end
254
+ end
@@ -0,0 +1,11 @@
1
+ module ChatbotHelper
2
+ module Telegram
3
+ # The callback_button resource which represents a Telegram bot API
4
+ # callback_button
5
+ #
6
+ # Note: As of now this is just a placeholder like described in the
7
+ # Telegram bot API documentation.
8
+ class CallbackGame < ChatbotHelper::Telegram::BaseResource
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,29 @@
1
+ module ChatbotHelper
2
+ module Telegram
3
+ # The callback_query resource which represents a Telegram bot API
4
+ # callback_query
5
+ class CallbackQuery < ChatbotHelper::Telegram::BaseResource
6
+ class << self
7
+ def required_fields
8
+ %w[id chat_instance]
9
+ end
10
+
11
+ def optional_fields
12
+ %w[inline_message_id data game_short_name]
13
+ end
14
+
15
+ def required_objects
16
+ [
17
+ { name: 'from', type: ChatbotHelper::Telegram::User }
18
+ ]
19
+ end
20
+
21
+ def optional_objects
22
+ [
23
+ { name: 'message', type: ChatbotHelper::Telegram::Message }
24
+ ]
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,16 @@
1
+ module ChatbotHelper
2
+ module Telegram
3
+ # The chat resource which represents a Telegram bot API chat
4
+ class Chat < ChatbotHelper::Telegram::BaseResource
5
+ class << self
6
+ def required_fields
7
+ %w[id type]
8
+ end
9
+
10
+ def optional_fields
11
+ %w[title username first_name last_name all_members_are_administrators]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ module ChatbotHelper
2
+ module Telegram
3
+ # The chat_member resource which represents a Telegram bot API chat_member
4
+ class ChatMember < ChatbotHelper::Telegram::BaseResource
5
+ class << self
6
+ def required_fields
7
+ %w[status]
8
+ end
9
+
10
+ def required_objects
11
+ [
12
+ { name: 'user', type: ChatbotHelper::Telegram::User }
13
+ ]
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,29 @@
1
+ module ChatbotHelper
2
+ module Telegram
3
+ # The chosen_inline_result resource which represents a Telegram bot API
4
+ # chosen_inline_result
5
+ class ChosenInlineResult < ChatbotHelper::Telegram::BaseResource
6
+ class << self
7
+ def required_fields
8
+ %w[result_id query]
9
+ end
10
+
11
+ def optional_fields
12
+ %w[inline_message_id]
13
+ end
14
+
15
+ def required_objects
16
+ [
17
+ { name: 'from', type: ChatbotHelper::Telegram::User }
18
+ ]
19
+ end
20
+
21
+ def optional_objects
22
+ [
23
+ { name: 'location', type: ChatbotHelper::Telegram::Location },
24
+ ]
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,50 @@
1
+ module ChatbotHelper
2
+ module Telegram
3
+ # A base collection resource class
4
+ class CollectionResource < ChatbotHelper::Telegram::BaseResource
5
+ class << self
6
+
7
+ # Returns the type of the elements in this collection.
8
+ #
9
+ # Subclasses *must* override this and provide a type for the collection
10
+ # which should be a subclass of +ChatbotHelper::Telegram::BaseResource+
11
+ # or something similar.
12
+ #
13
+ # @return [BaseResource] The type of the elements in this collection
14
+ def collection_type
15
+ m = 'Subclasses of CollectionResource must implement '\
16
+ 'self.collection_type'
17
+ raise NotImplementedError, m
18
+ end
19
+
20
+ def valid_resource?(resource)
21
+ return false if resource.nil? || !resource.respond_to?('each')
22
+
23
+ resource.each do |r|
24
+ return false unless collection_type.valid_resource?(r)
25
+ end
26
+
27
+ # We are finished. Return true...
28
+ true
29
+ end
30
+ end
31
+
32
+ attr_reader :elements
33
+
34
+ def initialize(hash: nil, string: nil)
35
+ super(hash: hash, string: string)
36
+
37
+ @elements = []
38
+ @hash.each do |r|
39
+ @elements << self.class.collection_type.new(hash: r)
40
+ end
41
+ end
42
+
43
+ include Enumerable
44
+
45
+ def each(&block)
46
+ @elements.each(&block)
47
+ end
48
+ end
49
+ end
50
+ end