Class: XNM::Telegram::GroupingAdapter
- Inherits:
-
Object
- Object
- XNM::Telegram::GroupingAdapter
- Defined in:
- lib/xnm/telegram/GroupingAdapter.rb
Overview
This class handles translating the sometimes a bit interesting Telegram API data to more usable types. It also handles the translation of User-IDs to the Usernames, and provides “Grouping IDs” to make it easier to edit, reply to, and delete messages It also exposes a much neater way of constructing inline keyboards.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#groupIDList ⇒ Object
readonly
Returns the value of attribute groupIDList.
-
#testLastData ⇒ Object
readonly
Returns the value of attribute testLastData.
-
#testLastUID ⇒ Object
readonly
Returns the value of attribute testLastUID.
-
#usernameList ⇒ Object
Returns the value of attribute usernameList.
Instance Method Summary collapse
-
#_handle_delete(data, uID) ⇒ Object
Deletes a message marked by a given GID.
-
#_handle_edit(data, uID) ⇒ Object
Edits an already known message.
-
#_handle_send(data, uID) ⇒ Object
Processes messages received through MQTT/Custom input It takes care of setting a few good defaults (like parse_mode), deletes any old messages of the same GroupID (if requested), and stores the new Message ID for later processing Tested in ts_mqtt/test_send.
-
#_process_inline_keyboard(keyboardLayout, gID = nil) ⇒ Object
Tested in ts_group_adapter/test_keyboard_build.
- #_reset ⇒ Object
-
#handle_callback_query(cbq) ⇒ Object
Handle an incoming callback query (inline keyboard button press) as received from the HTTP Core.
-
#handle_message(msg) ⇒ Object
Handle an incoming message packet from the HTTP core.
-
#handle_packet(packet) ⇒ Object
Handle incoming HTTP Core packets.
-
#initialize(httpCore) ⇒ GroupingAdapter
constructor
A new instance of GroupingAdapter.
- #on_callback_pressed(data, uID) ⇒ Object
- #on_command(data, uID) ⇒ Object
- #on_message(data, uID) ⇒ Object
- #on_reply(data, uID) ⇒ Object
Constructor Details
#initialize(httpCore) ⇒ GroupingAdapter
Returns a new instance of GroupingAdapter.
19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/xnm/telegram/GroupingAdapter.rb', line 19 def initialize(httpCore) # Check if we already have a HTTPCore, else create one @httpCore = if(httpCore.is_a? Telegram::HTTPCore) httpCore; else Telegram::HTTPCore.new(httpCore); end @httpCore.attach_receptor(self); _reset(); end |
Instance Attribute Details
#groupIDList ⇒ Object (readonly)
Returns the value of attribute groupIDList.
14 15 16 |
# File 'lib/xnm/telegram/GroupingAdapter.rb', line 14 def groupIDList @groupIDList end |
#testLastData ⇒ Object (readonly)
Returns the value of attribute testLastData.
17 18 19 |
# File 'lib/xnm/telegram/GroupingAdapter.rb', line 17 def testLastData @testLastData end |
#testLastUID ⇒ Object (readonly)
Returns the value of attribute testLastUID.
16 17 18 |
# File 'lib/xnm/telegram/GroupingAdapter.rb', line 16 def testLastUID @testLastUID end |
#usernameList ⇒ Object
Returns the value of attribute usernameList.
13 14 15 |
# File 'lib/xnm/telegram/GroupingAdapter.rb', line 13 def usernameList @usernameList end |
Instance Method Details
#_handle_delete(data, uID) ⇒ Object
Deletes a message marked by a given GID
166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/xnm/telegram/GroupingAdapter.rb', line 166 def _handle_delete(data, uID) # Resolve a saved Username to a User-ID uID = @usernameList[uID] if(@usernameList.key? uID) return if (uID = uID.to_i) == 0; # Return unless the username was known # Fetch the real message ID held by a grouping ID return unless mID = @groupIDList[uID][data] @groupIDList[uID].delete(data); # Clear that ID from the list # Perform the actual delete @httpCore.perform_post("deleteMessage", {chat_id: uID, message_id: mID}); end |
#_handle_edit(data, uID) ⇒ Object
Edits an already known message. Takes arguments similar to _handle_send
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/xnm/telegram/GroupingAdapter.rb', line 133 def _handle_edit(data, uID) # Resolve a saved Username to a User-ID uID = @usernameList[uID] if(@usernameList.key? uID) return if (uID = uID.to_i) == 0; # Return if a unknown Username was used # Fetch the target MessageID - Return if none is present return unless mID = @groupIDList[uID][data[:gid]] # Lay out all mandatory arguments for the edit POST outData = { chat_id: uID, message_id: mID, }; # If a inline keyboard was given, parse that. if(ilk = data[:inline_keyboard]) outData[:reply_markup] = _process_inline_keyboard(ilk, data[:gid]); end if(data[:text]) # Check if text was given outData[:text] = data[:text]; # Send the POST request editing the message text @httpCore.perform_post("editMessageText", outData); else # Otherwise, only edit the reply markup (keyboard etc.) @httpCore.perform_post("editMessageReplyMarkup", outData); end end |
#_handle_send(data, uID) ⇒ Object
Processes messages received through MQTT/Custom input It takes care of setting a few good defaults (like parse_mode), deletes any old messages of the same GroupID (if requested), and stores the new Message ID for later processing Tested in ts_mqtt/test_send
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/xnm/telegram/GroupingAdapter.rb', line 86 def _handle_send(data, uID) # Resolve a saved Username to a User-ID uID = @usernameList[uID] if(@usernameList.key? uID) return if (uID = uID.to_i) == 0; # Return if a unknown Username was used gID = data[:gid]; # Check if a GroupID is present and a former message is known if(gID and @groupIDList[uID][gID]) if(data[:replace]) _handle_delete(gID, uID) elsif(data[:overwrite]) _handle_edit(data, uID); return; # After editing, no new message should be sent! end end # Lay out all mandatory parameters for sendMessage request outData = { chat_id: uID, parse_mode: (data[:parse_mode] or "Markdown"), # Markdown parse mode is just nice text: data[:text] } # Check if the message is meant to be sent without notification if(data[:silent]) outData[:disable_notification] = true; end # Check if an inline keyboard layout is given, and parse that. if((ilk = data[:inline_keyboard])) outData[:reply_markup] = _process_inline_keyboard(ilk, gID); end reply = @httpCore.perform_post("sendMessage", outData); return unless reply[:ok] # Something was wrong about our message layout # TODO Add a proper error handler here. # If a GroupID was given, save the sent message's ID @groupIDList[uID][gID] = reply[:result][:message_id] if(gID); end |
#_process_inline_keyboard(keyboardLayout, gID = nil) ⇒ Object
Tested in ts_group_adapter/test_keyboard_build
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/xnm/telegram/GroupingAdapter.rb', line 41 def _process_inline_keyboard(keyboardLayout, gID = nil) # Return unless we have a structure we can form into a keyboard return nil unless (keyboardLayout.is_a? Array or keyboardLayout.is_a? Hash) # Make sure the structure of keyboardLayout is [{}] or [[]] if(keyboardLayout.is_a? Hash) keyboardLayout = [keyboardLayout] elsif(not (keyboardLayout[0].is_a? Array or keyboardLayout[0].is_a? Hash)) keyboardLayout = [keyboardLayout] end outData = Array.new(); # Iterate through the rows of keyboards keyboardLayout.each do |row| newRow = Array.new(); # Create the INLINE KEY button elements row.each do |key, val| cbd = {i: gID, k: (val or key)}; newRow << {text: key, callback_data: cbd.to_json} end # Add the new row to the array of rows outData << newRow; end # Return the ready reply_markup element return {inline_keyboard: outData}; end |
#_reset ⇒ Object
31 32 33 34 35 36 37 38 |
# File 'lib/xnm/telegram/GroupingAdapter.rb', line 31 def _reset() # Hash {username => ChatID} @usernameList = Hash.new(); # Hash {ChatID => {GroupID => MessageID}} @groupIDList = Hash.new do |hash, key| hash[key] = Hash.new; end end |
#handle_callback_query(cbq) ⇒ Object
Handle an incoming callback query (inline keyboard button press) as received from the HTTP Core
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/xnm/telegram/GroupingAdapter.rb', line 228 def handle_callback_query(cbq) # Send out a callback query reply (i.e. Telegram now knows we saw it) @httpCore.perform_post("answerCallbackQuery", {callback_query_id: cbq[:id]}); # Resolve the username, if we know it. uID = msg[:message][:chat][:id]; if(newUID = @usernameList.key(uID)) uID = newUID end # Try to parse the data. This gem sets inline keyboard reply data to # a small JSON, which identifies the GID and the key that was pressed. begin data = JSON.parse(cbq[:data], symbolize_names: true); rescue return; end data = { gid: data[:i], key: data[:k], } # If the key ID starts with a command slash, treat it like a normal # command. Has the benefit of making it super easy to execute already # implemented actions as a inline keyboard if(data[:key] =~ /^\//) on_command({text: data[:key], gid: data[:gid]}, uID); end on_callback_pressed(data, uID); end |
#handle_message(msg) ⇒ Object
Handle an incoming message packet from the HTTP core
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/xnm/telegram/GroupingAdapter.rb', line 195 def (msg) uID = msg[:chat][:id]; # Resolve the User-ID, if it's known. if(newUID = @usernameList.key(uID)) uID = newUID end data = Hash.new(); # Only accept messages that contain text (things like keyboard replies # are handled elsewhere). return unless(data[:text] = msg[:text]) # See if this message was a reply, and if we know said reply under a group-id if(replyMSG = msg[:reply_to_message]) data[:reply_gid] = @groupIDList[uID].key(replyMSG[:message_id]); end # Distinguish the type of message. If it starts with a command-slash, # it will be excempt from normal processing. # If it has a reply message ID that we know, handle it as a reply. # Otherwise, simply send it off as a normal message. if(data[:text] =~ /^\//) on_command(data, uID) elsif(data[:reply_gid]) on_reply(data, uID) else (data, uID) end end |
#handle_packet(packet) ⇒ Object
Handle incoming HTTP Core packets. Just send them to the appropriate handler function
262 263 264 265 266 267 268 269 270 |
# File 'lib/xnm/telegram/GroupingAdapter.rb', line 262 def handle_packet(packet) if(msg = packet[:message]) (msg); end if(cbq = packet[:callback_query]) handle_callback_query(cbq); end end |
#on_callback_pressed(data, uID) ⇒ Object
190 191 |
# File 'lib/xnm/telegram/GroupingAdapter.rb', line 190 def on_callback_pressed(data, uID) end |
#on_command(data, uID) ⇒ Object
184 185 |
# File 'lib/xnm/telegram/GroupingAdapter.rb', line 184 def on_command(data, uID) end |
#on_message(data, uID) ⇒ Object
179 180 181 182 |
# File 'lib/xnm/telegram/GroupingAdapter.rb', line 179 def (data, uID) @testLastUID = uID; @testLastData = data; end |
#on_reply(data, uID) ⇒ Object
187 188 |
# File 'lib/xnm/telegram/GroupingAdapter.rb', line 187 def on_reply(data, uID) end |