xasin-telegram 0.1.1.dev

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: '08a672d2bfc09cc9300f4079e89d575885db4d50'
4
+ data.tar.gz: c3cc7d5cc307f94739eb6d18ab6c8f69c7d088c6
5
+ SHA512:
6
+ metadata.gz: a5dc1b8a37e4b39036a1bdcfa36ce98c533c0db87944074aae5464364cecf62d8afe9e56c9db39ac67e56990dcd1f87bd612934a3e66c076f734bb791b3599ca
7
+ data.tar.gz: 62cd7a35febfa417839088c9f0806c4a66086f53b1d21b1ed1e75f6e6e7f7ce98de360127f63488cb44f14cfb2094a779be76c2fc26f56edec441ba1e97ca755
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+
2
+ # Xasin's simplifying Telegram gem
3
+ This gem is mainly meant for personal use.
4
+ Many of the existing Ruby gems for Telegram have all the functionality you want,
5
+ but also require a fairly complex setup, and good knowledge of the Telegram API.
6
+
7
+ My gem doesn't include all functionality, but aims to provide a somewhat simpler interface of
8
+ interaction with a small number (or just a single) of users.
9
+ I mainly use it for my own smart home system, to easily send and receive messages, but not much more.
10
+
11
+ ## Single-User mode
12
+ The main element of this gem is the single user mode.
13
+ It discards messages of all users except one, and provides a simple "send" and "on_message" interface:
14
+
15
+ ```Ruby
16
+ require 'xasin/telegram.rb'
17
+
18
+ # The HTTP "core" handles sending raw commands and getting updates, but not much more.
19
+ httpCore = Xasin::Telegram::HTTPCore.new(APIKEY);
20
+
21
+ # The SingleUser class handles the aforementioned sending/receiving of messages.
22
+ # Its first argument is the Chat-ID it should use, which is NOT the user ID
23
+ # To find it out you have to perform an update request to the Telegram API, send a message to your bot,
24
+ # and get the Chat_ID from there.
25
+ # I'm working on a better way >.>
26
+ singleUser = Xasin::Telegram::SingleUser.new(CHAT_ID, httpCore);
27
+
28
+
29
+ # From then, using the user is simple. Only text is required!
30
+ returned_id = singleUser.send_message(TEXT, **args);
31
+
32
+ # The ID that is returned can then be used to edit or delete the message:
33
+ singleUser.edit_message(returned_id, NEW_TEXT);
34
+ singleUser.delete_message(returned_id);
35
+
36
+ # And to receive messages:
37
+ singleUser.on_message do |message|
38
+ # Fetch the text from the message first!
39
+ text = message[:text];
40
+ end
41
+ ```
@@ -0,0 +1,66 @@
1
+
2
+ require 'net/http'
3
+ require 'json'
4
+
5
+ module Xasin
6
+ module Telegram
7
+ class HTTPCore
8
+ def initialize(apikey)
9
+ @apikey = apikey;
10
+
11
+ @lastUpdateID = 0;
12
+ Thread.new do
13
+ receive_loop();
14
+ end.abort_on_exception = true
15
+
16
+ @receptors = Array.new();
17
+ end
18
+
19
+ def perform_post(method, data = nil)
20
+ callAddress = URI "https://api.telegram.org/bot#{@apikey}/#{method}"
21
+
22
+ begin
23
+ if data
24
+ response = Net::HTTP.post_form(callAddress, data);
25
+ else
26
+ response = Net::HTTP.get callAddress
27
+ end
28
+
29
+ response = JSON.parse(response.body, symbolize_names: true);
30
+ rescue
31
+ sleep 0.5;
32
+ retry
33
+ end
34
+
35
+ return response;
36
+ end
37
+
38
+ def receive_loop()
39
+ loop do
40
+ begin
41
+ packet = perform_post("getUpdates", {timeout: 20, offset: @lastUpdateID + 1})
42
+
43
+ next unless packet[:ok];
44
+ next if packet[:result].length == 0;
45
+
46
+ packet[:result].each do |data|
47
+ hUpdateID = data[:update_id].to_i
48
+ @lastUpdateID = [hUpdateID, @lastUpdateID].max
49
+
50
+ @receptors.each do |r|
51
+ r.handle_packet(data);
52
+ end
53
+ end
54
+ rescue
55
+ sleep 1
56
+ retry
57
+ end
58
+ end
59
+ end
60
+
61
+ def attach_receptor(receptorClass)
62
+ @receptors << receptorClass;
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,145 @@
1
+
2
+ require 'mqtt/sub_handler'
3
+
4
+ module Xasin
5
+ module Telegram
6
+ module MQTT
7
+ class Server
8
+ attr_accessor :usernameList
9
+
10
+ def initialize(httpCore, mqtt)
11
+ if(httpCore.is_a? Telegram::HTTPCore)
12
+ @httpCore = httpCore;
13
+ else
14
+ @httpCore = Telegram::HTTPCore.new(httpCore);
15
+ end
16
+ @httpCore.attach_receptor(self);
17
+
18
+ @mqtt = mqtt;
19
+
20
+ # Hash {username => ChatID}
21
+ @usernameList = Hash.new();
22
+ # Hash {ChatID => {GroupID => MessageID}}
23
+ @groupIDList = Hash.new();
24
+
25
+ setup_mqtt();
26
+ end
27
+
28
+ # Processes messages received through MQTT
29
+ # It takes care of setting a few good defaults (like parse_mode),
30
+ # deletes any old messages of the same GroupID (if requested),
31
+ # and stores the new Message ID for later processing
32
+ # @param data [Hash] The raw "message" object received from the Telegram API
33
+ # @param uID [Integer,String] The user-id as received from the MQTT Wildcard.
34
+ # Can be a username defined in @usernameList
35
+ def _handle_send(data, uID)
36
+ # Resolve a saved Username to a User-ID
37
+ uID = @usernameList[uID] if(@usernameList.key? uID)
38
+ uID = uID.to_i;
39
+
40
+ begin
41
+ data = JSON.parse(data, symbolize_names: true);
42
+ rescue
43
+ # Allow for pure-text to be sent (easier on the ESPs)
44
+ data = {text: data}
45
+ end
46
+
47
+ data[:parse_mode] ||= "Markdown";
48
+ data[:chat_id] = uID;
49
+
50
+ reply = @httpCore.perform_post("sendMessage", data);
51
+
52
+ # Check if this message has a grouping ID
53
+ if(gID = data[:GID])
54
+ # If the message has the :single flag, delete the last one
55
+ if(data[:single])
56
+ _handle_delete(gID, uID);
57
+ end
58
+
59
+ # Save this grouping ID
60
+ @groupIDList[uID][gID] = reply[:result][:message_id];
61
+ end
62
+ end
63
+
64
+ def _handle_edit(data, uID)
65
+ # Resolve a saved Username to a User-ID
66
+ uID = @usernameList[uID] if(@usernameList.key? uID)
67
+ uID = uID.to_i;
68
+
69
+ begin
70
+ data = JSON.parse(data, symbolize_names: true);
71
+
72
+ return unless data[:text];
73
+ # Fetch the target Message ID
74
+ return unless mID = @groupIDList[uID][data[:GID]]
75
+
76
+ # Send the POST request editing the message text
77
+ @httpCore.perform_post("editMessageText",
78
+ { text: data[:text],
79
+ chat_id: uID,
80
+ message_id: mID});
81
+ rescue
82
+ end
83
+ end
84
+
85
+ def _handle_delete(data, uID)
86
+ # Resolve a saved Username to a User-ID
87
+ uID = @usernameList[uID] if(@usernameList.key? uID)
88
+ uID = uID.to_i;
89
+
90
+ # Fetch the real message ID held by a grouping ID
91
+ return unless mID = @groupIDList[uID][data]
92
+ @groupIDList[uID].delete(data);
93
+
94
+ @httpCore.perform_post("deleteMessage", {chat_id: uID, message_id: mID});
95
+ end
96
+
97
+ def setup_mqtt()
98
+ @mqtt.subscribe_to "Telegram/+/Send" do |data, tSplit|
99
+ _handle_send(data, tSplit[0]);
100
+ end
101
+
102
+ @mqtt.subscribe_to "Telegram/+/Edit" do |data, tSplit|
103
+ _handle_edit(data, tSplit[0])
104
+ end
105
+
106
+ @mqtt.subscribe_to "Telegram/+/Delete" do |data, tSplit|
107
+ _handle_delete(data, tSplit[0])
108
+ end
109
+
110
+ @mqtt.subscribe_to "Telegram/+/Release" do |data, tSplit|
111
+ # Resolve a saved Username to a User-ID
112
+ uID = tSplit[0];
113
+ uID = @usernameList[uID] if(@usernameList.key? uID)
114
+ uID = uID.to_i;
115
+
116
+ # Delete the stored GID key
117
+ @groupIDList[uID].delete(data);
118
+ end
119
+ end
120
+
121
+ def handle_packet(packet)
122
+ if(msg = packet[:message])
123
+ uID = msg[:chat][:id];
124
+ if(newUID = @usernameList.key(uID))
125
+ uID = newUID
126
+ end
127
+
128
+ data = Hash.new();
129
+ return unless(data[:text] = msg[:text])
130
+
131
+ if(replyMSG = msg[:reply_to_message])
132
+ data[:reply_GID] = @groupIDList[uID].key(replyMSG[:message_id]);
133
+ end
134
+
135
+ if(data[:reply_GID])
136
+ @mqtt.publish_to "Telegram/#{uID}/Reply", data;
137
+ else
138
+ @mqtt.publish_to "Telegram/#{uID}/Received", data;
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,73 @@
1
+
2
+ require_relative "HTTPCore.rb"
3
+
4
+ module Xasin
5
+ module Telegram
6
+ class SingleUser
7
+ attr_reader :httpCore
8
+
9
+ def initialize(userChat, httpCore)
10
+ @httpCore = httpCore.is_a?(Telegram::HTTPCore) ? httpCore : HTTPCore.new(httpCore);
11
+ @httpCore.attach_receptor(self);
12
+
13
+ @userID = userChat;
14
+
15
+ @message_procs = Array.new();
16
+ @inlinebutton_procs = Array.new();
17
+ end
18
+
19
+ def handle_packet(packet)
20
+ if(packet[:message]) then
21
+ return unless packet[:message][:chat][:id] == @userID;
22
+
23
+ @message_procs.each do |cb| cb.call(packet[:message]); end
24
+ packet[:has_been_handled] = true;
25
+ end
26
+
27
+ if(packet[:callback_query]) then
28
+ return unless packet[:callback_query][:message][:chat][:id] == @userID;
29
+
30
+ @inlinebutton_procs.each do |cb| cb.call(packet[:callback_query]); end
31
+ packet[:has_been_handled] = true;
32
+ end
33
+ end
34
+
35
+ def send_message(text, **args)
36
+ args ||= Hash.new();
37
+ args[:text] = text;
38
+
39
+ args[:chat_id] = @userID;
40
+ args[:parse_mode] ||= "Markdown";
41
+
42
+ sent_message = @httpCore.perform_post("sendMessage", args);
43
+
44
+ return sent_message[:result][:message_id];
45
+ end
46
+
47
+ def edit_message(mID, text=nil, **args)
48
+ args[:chat_id] = @userID;
49
+ args[:message_id] = mID;
50
+
51
+ args[:parse_mode] ||= "Markdown";
52
+
53
+ if(text) then
54
+ args[:text] = text;
55
+ @httpCore.perform_post("editMessageText", args);
56
+ else
57
+ @httpCore.perform_post("editMessageReplyMarkup", args);
58
+ end
59
+ end
60
+
61
+ def delete_message(mID)
62
+ @httpCore.perform_post("deleteMessage", {chat_id: @userID, message_id: mID});
63
+ end
64
+
65
+ def on_message(&block)
66
+ @message_procs << block;
67
+ end
68
+ def on_inlinebutton_press(&block)
69
+ @inlinebutton_procs << block;
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,3 @@
1
+
2
+ require_relative "Telegram/HTTPCore.rb"
3
+ require_relative "Telegram/SingleUser.rb"
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xasin-telegram
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1.dev
5
+ platform: ruby
6
+ authors:
7
+ - Xasin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-06-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mqtt-sub_handler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Multi-Purpose Telegram gem. Mainly for personal use, but also used as
28
+ a Telegram to MQTT Bridge for IoT devices
29
+ email:
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - README.md
35
+ - lib/xasin/telegram.rb
36
+ - lib/xasin/telegram/HTTPCore.rb
37
+ - lib/xasin/telegram/MQTT_Adapter.rb
38
+ - lib/xasin/telegram/SingleUser.rb
39
+ homepage: https://github.com/XasWorks/XasCode/tree/GEM_Telegram/Ruby/Telegram
40
+ licenses:
41
+ - GPL-3.0
42
+ metadata: {}
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">"
55
+ - !ruby/object:Gem::Version
56
+ version: 1.3.1
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 2.6.14.1
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: Xasin's Telegram gem
63
+ test_files: []