xnm-telegram 0.4.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.
- checksums.yaml +7 -0
- data/README.md +64 -0
- data/lib/xnm/telegram.rb +4 -0
- data/lib/xnm/telegram/Chat.rb +87 -0
- data/lib/xnm/telegram/GroupingAdapter.rb +273 -0
- data/lib/xnm/telegram/HTTPCore.rb +128 -0
- data/lib/xnm/telegram/Handler.rb +302 -0
- data/lib/xnm/telegram/KeyboardLayout.rb +67 -0
- data/lib/xnm/telegram/MQTT_Adapter.rb +73 -0
- data/lib/xnm/telegram/Message.rb +126 -0
- data/lib/xnm/telegram/OnCommand.rb +34 -0
- data/lib/xnm/telegram/OnMessage.rb +29 -0
- data/lib/xnm/telegram/SingleUser.rb +78 -0
- data/lib/xnm/telegram/TestHTTPCore.rb +62 -0
- data/lib/xnm/telegram/User.rb +142 -0
- metadata +72 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module XNM
|
4
|
+
module Telegram
|
5
|
+
class OnCommand < OnTelegramEvent
|
6
|
+
attr_accessor :deny_message
|
7
|
+
attr_accessor :required_perms
|
8
|
+
|
9
|
+
def initialize(options)
|
10
|
+
super()
|
11
|
+
|
12
|
+
@block = options[:block]
|
13
|
+
@command = options[:command]
|
14
|
+
|
15
|
+
@required_perms = [options[:permissions]].flatten.uniq
|
16
|
+
|
17
|
+
@deny_message = options[:deny_msg] || 'You are not authorized, %s.'
|
18
|
+
|
19
|
+
@priority += 5
|
20
|
+
end
|
21
|
+
|
22
|
+
def nomp_message(message)
|
23
|
+
return if message.handled
|
24
|
+
return unless message.command == @command
|
25
|
+
|
26
|
+
if message.user.has_permissions? @required_perms
|
27
|
+
@block.call message
|
28
|
+
else
|
29
|
+
message.reply @deny_message % [message.user.casual_name]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module XNM
|
4
|
+
module Telegram
|
5
|
+
class OnMessage < OnTelegramEvent
|
6
|
+
def initialize(options)
|
7
|
+
super()
|
8
|
+
|
9
|
+
@block = options[:block]
|
10
|
+
@regexp = options[:regexp]
|
11
|
+
|
12
|
+
@priority += 1 if @regexp
|
13
|
+
end
|
14
|
+
|
15
|
+
def nomp_message(message)
|
16
|
+
if @regexp
|
17
|
+
match = @regexp.match message.to_s
|
18
|
+
|
19
|
+
if match
|
20
|
+
@block.call message, match
|
21
|
+
message.handled = true
|
22
|
+
end
|
23
|
+
else
|
24
|
+
@block.call message
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
|
2
|
+
require_relative "HTTPCore.rb"
|
3
|
+
|
4
|
+
module XNM
|
5
|
+
module Telegram
|
6
|
+
class SingleUser
|
7
|
+
attr_reader :httpCore
|
8
|
+
|
9
|
+
def initialize(userChat, httpCore)
|
10
|
+
# Check if we already have a HTTPCore, else create one
|
11
|
+
@httpCore = if(httpCore.is_a? Telegram::HTTPCore)
|
12
|
+
httpCore;
|
13
|
+
else
|
14
|
+
Telegram::HTTPCore.new(httpCore);
|
15
|
+
end
|
16
|
+
@httpCore.attach_receptor(self);
|
17
|
+
@httpCore.attach_receptor(self);
|
18
|
+
|
19
|
+
@userID = userChat;
|
20
|
+
|
21
|
+
@message_procs = Array.new();
|
22
|
+
@inlinebutton_procs = Array.new();
|
23
|
+
end
|
24
|
+
|
25
|
+
def handle_packet(packet)
|
26
|
+
if(packet[:message])
|
27
|
+
return unless packet[:message][:chat][:id] == @userID;
|
28
|
+
|
29
|
+
@message_procs.each do |cb| cb.call(packet[:message]); end
|
30
|
+
packet[:has_been_handled] = true;
|
31
|
+
end
|
32
|
+
|
33
|
+
return unless packet[:callback_query]
|
34
|
+
return unless packet[:callback_query][:message][:chat][:id] == @userID;
|
35
|
+
|
36
|
+
@inlinebutton_procs.each { |cb| cb.call(packet[:callback_query]); }
|
37
|
+
packet[:has_been_handled] = true;
|
38
|
+
end
|
39
|
+
|
40
|
+
def send_message(text, **args)
|
41
|
+
args ||= Hash.new();
|
42
|
+
args[:text] = text;
|
43
|
+
|
44
|
+
args[:chat_id] = @userID;
|
45
|
+
args[:parse_mode] ||= "Markdown";
|
46
|
+
|
47
|
+
sent_message = @httpCore.perform_post("sendMessage", args);
|
48
|
+
|
49
|
+
return sent_message[:result][:message_id];
|
50
|
+
end
|
51
|
+
|
52
|
+
def edit_message(mID, text=nil, **args)
|
53
|
+
args[:chat_id] = @userID;
|
54
|
+
args[:message_id] = mID;
|
55
|
+
|
56
|
+
args[:parse_mode] ||= "Markdown";
|
57
|
+
|
58
|
+
if(text) then
|
59
|
+
args[:text] = text;
|
60
|
+
@httpCore.perform_post("editMessageText", args);
|
61
|
+
else
|
62
|
+
@httpCore.perform_post("editMessageReplyMarkup", args);
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def delete_message(mID)
|
67
|
+
@httpCore.perform_post("deleteMessage", {chat_id: @userID, message_id: mID});
|
68
|
+
end
|
69
|
+
|
70
|
+
def on_message(&block)
|
71
|
+
@message_procs << block;
|
72
|
+
end
|
73
|
+
def on_inlinebutton_press(&block)
|
74
|
+
@inlinebutton_procs << block;
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
|
2
|
+
require_relative 'HTTPCore.rb'
|
3
|
+
|
4
|
+
module XNM
|
5
|
+
module Telegram
|
6
|
+
# This is a purely test-related class. It implements all of HTTPCore's
|
7
|
+
# functionality, but does not connect to the Telegram API. Instead,
|
8
|
+
# it simply saves the last POST request, and simulates received requests,
|
9
|
+
# allowing testing.
|
10
|
+
class TestCore < HTTPCore
|
11
|
+
attr_accessor :lastPostData, :lastPostRequest
|
12
|
+
attr_reader :currentMessageID
|
13
|
+
attr_accessor :toReturn
|
14
|
+
|
15
|
+
def initialize()
|
16
|
+
prepare();
|
17
|
+
|
18
|
+
@receptors = Array.new();
|
19
|
+
end
|
20
|
+
|
21
|
+
def prepare()
|
22
|
+
@lastPostData = Array.new();
|
23
|
+
@lastPostRequest = Array.new();
|
24
|
+
|
25
|
+
@currentMessageID = rand(0..9999);
|
26
|
+
|
27
|
+
@toReturn = {
|
28
|
+
ok: true,
|
29
|
+
result: {
|
30
|
+
message_id: @currentMessageID
|
31
|
+
}
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def perform_post(postRequest, postData)
|
36
|
+
@lastPostRequest << postRequest;
|
37
|
+
@lastPostData << postData;
|
38
|
+
|
39
|
+
return @toReturn;
|
40
|
+
end
|
41
|
+
|
42
|
+
def simulate_send_packet(packet)
|
43
|
+
@receptors.each do |r|
|
44
|
+
r.handle_packet(packet);
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def simulate_sent_message(text, chatID: "test", reply_id: nil )
|
49
|
+
outData = Hash.new();
|
50
|
+
|
51
|
+
outData[:chat] = {id: chatID};
|
52
|
+
outData[:text] = text;
|
53
|
+
|
54
|
+
if(reply_id)
|
55
|
+
outData[:reply_to_message] = reply_id;
|
56
|
+
end
|
57
|
+
|
58
|
+
simulate_send_packet({message: outData});
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
|
2
|
+
require_relative 'Chat.rb'
|
3
|
+
|
4
|
+
module XNM
|
5
|
+
module Telegram
|
6
|
+
# Telegram User class.
|
7
|
+
#
|
8
|
+
# This class is an extension of a Telegram {Chat} object that
|
9
|
+
# represents a DM with a User, and represents the user himself.
|
10
|
+
# This is because Telegram's User ID is equivalent to the
|
11
|
+
# Chat ID of the DM with the User.
|
12
|
+
class User < Chat
|
13
|
+
# Username, without the @
|
14
|
+
attr_reader :username
|
15
|
+
# First name, always guaranteed to be set.
|
16
|
+
attr_reader :first_name
|
17
|
+
# Last name, may not be set.
|
18
|
+
attr_reader :last_name
|
19
|
+
|
20
|
+
# A human readable name.
|
21
|
+
# Overrides {Chat#casual_name}
|
22
|
+
attr_reader :casual_name
|
23
|
+
|
24
|
+
# List of permissions this user has.
|
25
|
+
# This Array of Strings will be used to check against
|
26
|
+
# a executed command, to see if the User has appropriate rights
|
27
|
+
# to run said command.
|
28
|
+
#
|
29
|
+
# Note that the {Handler#permissions_list} will be used to expand
|
30
|
+
# this list, i.e. if the permissions list is:
|
31
|
+
# `{ 'admin' => ['basic_rights'] }`
|
32
|
+
# And the user has the 'admin' permission, he will also have
|
33
|
+
# basic_rights *without them being listed in {#permissions}*
|
34
|
+
#
|
35
|
+
# Use {#has_permissions?} to check if a user has a certain permission.
|
36
|
+
attr_reader :permissions
|
37
|
+
|
38
|
+
# Permanent user state. Will be saved to disk.
|
39
|
+
# @todo Actually save to disk.
|
40
|
+
attr_reader :perm_state
|
41
|
+
|
42
|
+
# Temporary state. Will be lost of restart, should be cleaned
|
43
|
+
# out and only used for intermediary work.
|
44
|
+
attr_accessor :temp_state
|
45
|
+
|
46
|
+
# Initialize a new user object.
|
47
|
+
#
|
48
|
+
# Pass the handler used for this User as well as the
|
49
|
+
# Hash containing Telegram's "User" Object.
|
50
|
+
def initialize(handler, user_info)
|
51
|
+
super(handler, user_info);
|
52
|
+
|
53
|
+
@username = user_info[:username]
|
54
|
+
@first_name = user_info[:first_name]
|
55
|
+
@last_name = user_info[:last_name]
|
56
|
+
|
57
|
+
@casual_name = user_info[:first_name]
|
58
|
+
|
59
|
+
@permissions = user_info[:permissions] || []
|
60
|
+
@perm_state = user_info[:perm_state] || {}
|
61
|
+
end
|
62
|
+
|
63
|
+
def add_permissions(list)
|
64
|
+
list = [list].flatten
|
65
|
+
|
66
|
+
list.each do |perm|
|
67
|
+
next if perm.is_a? Symbol
|
68
|
+
next if perm.is_a? String
|
69
|
+
|
70
|
+
raise ArgumentError, "Permission must be String or Symbol!"
|
71
|
+
end
|
72
|
+
|
73
|
+
@permissions = (@permissions + list).uniq
|
74
|
+
end
|
75
|
+
alias add_permission add_permissions
|
76
|
+
|
77
|
+
def take_permissions(list)
|
78
|
+
list = [list].flatten
|
79
|
+
|
80
|
+
list.each do |perm|
|
81
|
+
next if perm.is_a? Symbol
|
82
|
+
next if perm.is_a? String
|
83
|
+
|
84
|
+
raise ArgumentError, "Permission must be String or Symbol!"
|
85
|
+
end
|
86
|
+
|
87
|
+
@permissions -= list;
|
88
|
+
end
|
89
|
+
alias take_permission take_permissions
|
90
|
+
|
91
|
+
# Check if a user has all given permissions.
|
92
|
+
# Will run {#has_permission} against every permission
|
93
|
+
# in the list, returns false if any one permission is not met.
|
94
|
+
#
|
95
|
+
# An empty list counts as true
|
96
|
+
def has_permissions?(*targets)
|
97
|
+
targets = targets.flatten
|
98
|
+
|
99
|
+
return true if targets.nil?
|
100
|
+
return true if @permissions.include? :sudo
|
101
|
+
|
102
|
+
targets.each do |perm|
|
103
|
+
return false unless has_permission? perm
|
104
|
+
end
|
105
|
+
|
106
|
+
true
|
107
|
+
end
|
108
|
+
|
109
|
+
# Check whether a user has a given permission.
|
110
|
+
#
|
111
|
+
# This function will check if the given permission is in the
|
112
|
+
# User's {#permissions}. It will also use the
|
113
|
+
# {Handler#permissions_list} to expand the user's permissions,
|
114
|
+
# i.e. if the permissions list is:
|
115
|
+
# `{ 'admin' => ['basic_rights'] }`
|
116
|
+
# And the user has the 'admin' permission, he will also have
|
117
|
+
# basic_rights *without them being listed in {#permissions}*
|
118
|
+
#
|
119
|
+
# nil will return true.
|
120
|
+
#
|
121
|
+
# @note This will always return true if the user has the :sudo
|
122
|
+
# permission, use only for full admin access!
|
123
|
+
def has_permission?(target)
|
124
|
+
return true if @permissions.include? :sudo
|
125
|
+
return true if target.nil?
|
126
|
+
|
127
|
+
unchecked = @permissions.dup
|
128
|
+
checked = {}
|
129
|
+
|
130
|
+
while perm = unchecked.pop
|
131
|
+
next if checked[perm]
|
132
|
+
return true if perm == target
|
133
|
+
|
134
|
+
unchecked += @handler.permissions_list[perm] || []
|
135
|
+
checked[perm] = true
|
136
|
+
end
|
137
|
+
|
138
|
+
false
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xnm-telegram
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Xasin
|
8
|
+
- Neira
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2020-04-12 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: mqtt-sub_handler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
description: Multi-Purpose Telegram gem. Mainly for personal use, but also used as
|
29
|
+
a Telegram to MQTT Bridge for IoT devices
|
30
|
+
email:
|
31
|
+
executables: []
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- README.md
|
36
|
+
- lib/xnm/telegram.rb
|
37
|
+
- lib/xnm/telegram/Chat.rb
|
38
|
+
- lib/xnm/telegram/GroupingAdapter.rb
|
39
|
+
- lib/xnm/telegram/HTTPCore.rb
|
40
|
+
- lib/xnm/telegram/Handler.rb
|
41
|
+
- lib/xnm/telegram/KeyboardLayout.rb
|
42
|
+
- lib/xnm/telegram/MQTT_Adapter.rb
|
43
|
+
- lib/xnm/telegram/Message.rb
|
44
|
+
- lib/xnm/telegram/OnCommand.rb
|
45
|
+
- lib/xnm/telegram/OnMessage.rb
|
46
|
+
- lib/xnm/telegram/SingleUser.rb
|
47
|
+
- lib/xnm/telegram/TestHTTPCore.rb
|
48
|
+
- lib/xnm/telegram/User.rb
|
49
|
+
homepage: https://github.com/XasWorks/XasCode/tree/GEM_Telegram/Ruby/Telegram
|
50
|
+
licenses:
|
51
|
+
- GPL-3.0
|
52
|
+
metadata: {}
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options: []
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
requirements: []
|
68
|
+
rubygems_version: 3.0.6
|
69
|
+
signing_key:
|
70
|
+
specification_version: 4
|
71
|
+
summary: XasinTheSystem's Telegram gem
|
72
|
+
test_files: []
|