slack-smart-bot 1.6.5 → 1.8.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 +4 -4
- data/README.md +8 -1
- data/lib/slack-smart-bot.rb +3 -8
- data/lib/slack-smart-bot_general_rules.rb +33 -0
- data/lib/slack-smart-bot_rules.rb +80 -84
- data/lib/slack/smart-bot/comm.rb +2 -1
- data/lib/slack/smart-bot/comm/respond.rb +1 -1
- data/lib/slack/smart-bot/comm/send_file.rb +28 -12
- data/lib/slack/smart-bot/comm/unreact.rb +16 -0
- data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +24 -5
- data/lib/slack/smart-bot/commands/on_bot/admin/extend_rules.rb +1 -1
- data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +1 -0
- data/lib/slack/smart-bot/commands/on_bot/admin_master/bot_stats.rb +36 -4
- data/lib/slack/smart-bot/commands/on_bot/repl.rb +19 -32
- data/lib/slack/smart-bot/commands/on_bot/run_repl.rb +12 -3
- data/lib/slack/smart-bot/commands/on_bot/see_repls.rb +1 -1
- data/lib/slack/smart-bot/commands/on_master/create_bot.rb +5 -0
- data/lib/slack/smart-bot/process.rb +10 -6
- data/lib/slack/smart-bot/treat_message.rb +7 -12
- data/lib/slack/smart-bot/utils/create_routine_thread.rb +25 -3
- data/lib/slack/smart-bot/utils/get_help.rb +5 -1
- metadata +18 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b15c46b5b101a0a31487508457982e8f5d6b81ad41f54338407ecdb2aa9974f3
|
4
|
+
data.tar.gz: d32bfceda9068f5f11d1002f255b77a280f3a7b7068f40a632c03b7cb6378127
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61c6e4060d928a1562176a0596ac968c7d007998c268816af489a0d36624a768ba1eadd3b6d27be7d19d37984b335d70215f718189165c1a9ac0a3a18130c5a0
|
7
|
+
data.tar.gz: 48995f9d416dd8906353508ac9bf86219cd92b2ede2f0043c3752dcc4db95564161ad64f41d86fd9f821fa1dc6d9d5bba3ef5519be037214e0003c3423b595c9
|
data/README.md
CHANGED
@@ -124,6 +124,7 @@ def rules(user, command, processed, dest)
|
|
124
124
|
respond "zZzzzzzZZZZZZzzzzzzz!"
|
125
125
|
react :sleeping
|
126
126
|
sleep 10
|
127
|
+
unreact :sleeping
|
127
128
|
react :sunny
|
128
129
|
when /no/i, /nope/i, /cancel/i
|
129
130
|
@questions.delete(from)
|
@@ -152,6 +153,8 @@ def rules(user, command, processed, dest)
|
|
152
153
|
else
|
153
154
|
respond "#{user.name}: #{stdout} #{stderr}"
|
154
155
|
end
|
156
|
+
|
157
|
+
unreact :runner
|
155
158
|
|
156
159
|
else
|
157
160
|
unless processed
|
@@ -159,8 +162,11 @@ def rules(user, command, processed, dest)
|
|
159
162
|
end
|
160
163
|
end
|
161
164
|
end
|
162
|
-
|
163
165
|
```
|
166
|
+
|
167
|
+
Also you can add general rules that will be available on all Smart Bot channels to `./rules/general_rules.rb`
|
168
|
+
|
169
|
+
|
164
170
|
### How to access the Smart Bot
|
165
171
|
You can access the bot directly on the MASTER CHANNEL, on a secondary channel where the bot is running and directly by opening a private chat with the bot, in this case the conversation will be just between you and the bot.
|
166
172
|
|
@@ -388,6 +394,7 @@ Examples:
|
|
388
394
|
>**_`add routine run_tests every 3h !run tests on customers`_**
|
389
395
|
>**_`add routine clean_db at 17:05 !clean customers temp db`_**
|
390
396
|
>**_`add silent routine clean_db at 17:05 !clean customers temp db`_**
|
397
|
+
>**_`add routine clean_custdb on Mondays at 05:00 !clean customers db`_**
|
391
398
|
|
392
399
|
Also instead of adding a Command to be executed, you can attach a file, then the routine will be created and the attached file will be executed on the criteria specified. Only Master Admins are allowed to use it this way.
|
393
400
|
|
data/lib/slack-smart-bot.rb
CHANGED
@@ -36,13 +36,7 @@ class SlackSmartBot
|
|
36
36
|
else
|
37
37
|
config[:path] = '.'
|
38
38
|
end
|
39
|
-
|
40
|
-
config[:silent] = true
|
41
|
-
elsif ENV['BOT_SILENT'].to_s == 'false'
|
42
|
-
config[:silent] = false
|
43
|
-
else
|
44
|
-
config[:silent] = false unless config.key?(:silent)
|
45
|
-
end
|
39
|
+
config[:silent] = false unless config.key?(:silent)
|
46
40
|
config[:testing] = false unless config.key?(:testing)
|
47
41
|
config[:simulate] = false unless config.key?(:simulate)
|
48
42
|
config[:stats] = false unless config.key?(:stats)
|
@@ -210,7 +204,8 @@ class SlackSmartBot
|
|
210
204
|
if version_remote != VERSION
|
211
205
|
version_message = ". There is a new available version: #{version_remote}."
|
212
206
|
end
|
213
|
-
|
207
|
+
if !config[:silent] or ENV['BOT_SILENT'].to_s == 'false'
|
208
|
+
ENV['BOT_SILENT'] = 'true' if config[:silent] == 'true' and ENV['BOT_SILENT'].to_s != 'true'
|
214
209
|
respond "Smart Bot started v#{VERSION}#{version_message}\nIf you want to know what I can do for you: `bot help`.\n`bot rules` if you want to display just the specific rules of this channel.\nYou can talk to me privately if you prefer it."
|
215
210
|
end
|
216
211
|
@routines.each do |ch, rout|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# add here the general rules you will be using in all Smart Bots
|
2
|
+
def general_rules(user, command, processed, dest, files = [], rules_file = "")
|
3
|
+
from = user.name
|
4
|
+
display_name = user.profile.display_name
|
5
|
+
|
6
|
+
begin
|
7
|
+
case command
|
8
|
+
|
9
|
+
# help: ----------------------------------------------
|
10
|
+
# help: `echo SOMETHING`
|
11
|
+
# help: `INTEGER echo SOMETHING`
|
12
|
+
# help: repeats SOMETHING. If INTEGER supplied then that number of times.
|
13
|
+
# help: Examples:
|
14
|
+
# help: _echo I am the Smart Bot_
|
15
|
+
# help: _100 echo :heart:_
|
16
|
+
when /^(\d*)\s*echo\s(.+)/i
|
17
|
+
save_stats :echo
|
18
|
+
$1.to_s == '' ? times = 1 : times = $1.to_i
|
19
|
+
respond ($2*times).to_s
|
20
|
+
|
21
|
+
else
|
22
|
+
return false
|
23
|
+
end
|
24
|
+
return true
|
25
|
+
rescue => exception
|
26
|
+
if defined?(@logger)
|
27
|
+
@logger.fatal exception
|
28
|
+
respond "Unexpected error!! Please contact an admin to solve it: <@#{ADMIN_USERS.join(">, <@")}>"
|
29
|
+
else
|
30
|
+
puts exception
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -38,102 +38,98 @@ def rules(user, command, processed, dest, files = [], rules_file = "")
|
|
38
38
|
from = user.name
|
39
39
|
display_name = user.profile.display_name
|
40
40
|
|
41
|
-
|
42
|
-
|
41
|
+
load "#{config.path}/rules/general_rules.rb"
|
42
|
+
|
43
|
+
unless general_rules(user, command, processed, dest, files, rules_file)
|
44
|
+
begin
|
45
|
+
case command
|
43
46
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
react :monkey_face
|
53
|
-
|
54
|
-
# help: ----------------------------------------------
|
55
|
-
# help: `go to sleep`
|
56
|
-
# help: it will sleep the bot for 5 seconds
|
57
|
-
# help:
|
58
|
-
when /^go\sto\ssleep/i
|
59
|
-
save_stats :to_to_sleep
|
60
|
-
unless @questions.keys.include?(from)
|
61
|
-
ask "do you want me to take a siesta?"
|
62
|
-
else
|
63
|
-
case @questions[from]
|
64
|
-
when /yes/i, /yep/i, /sure/i
|
65
|
-
@questions.delete(from)
|
66
|
-
respond "I'll be sleeping for 5 secs... just for you"
|
67
|
-
respond "zZzzzzzZZZZZZzzzzzzz!"
|
68
|
-
react :sleeping
|
69
|
-
sleep 5
|
70
|
-
react :sunny
|
71
|
-
when /no/i, /nope/i, /cancel/i
|
72
|
-
@questions.delete(from)
|
73
|
-
respond "Thanks, I'm happy to be awake"
|
47
|
+
# help: ----------------------------------------------
|
48
|
+
# help: `go to sleep`
|
49
|
+
# help: it will sleep the bot for 5 seconds
|
50
|
+
# help:
|
51
|
+
when /^go\sto\ssleep/i
|
52
|
+
save_stats :go_to_sleep
|
53
|
+
unless @questions.keys.include?(from)
|
54
|
+
ask "do you want me to take a siesta?"
|
74
55
|
else
|
75
|
-
|
76
|
-
|
56
|
+
case @questions[from]
|
57
|
+
when /yes/i, /yep/i, /sure/i
|
58
|
+
@questions.delete(from)
|
59
|
+
respond "I'll be sleeping for 5 secs... just for you"
|
60
|
+
respond "zZzzzzzZZZZZZzzzzzzz!"
|
61
|
+
react :sleeping
|
62
|
+
sleep 5
|
63
|
+
unreact :sleeping
|
64
|
+
react :sunny
|
65
|
+
when /no/i, /nope/i, /cancel/i
|
66
|
+
@questions.delete(from)
|
67
|
+
respond "Thanks, I'm happy to be awake"
|
68
|
+
else
|
69
|
+
respond "I don't understand"
|
70
|
+
ask "are you sure do you want me to sleep? (yes or no)"
|
71
|
+
end
|
77
72
|
end
|
78
|
-
end
|
79
73
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
74
|
+
# help: ----------------------------------------------
|
75
|
+
# help: `run something`
|
76
|
+
# help: It will run the process and report the results when done
|
77
|
+
# help:
|
78
|
+
when /^run something/i
|
79
|
+
save_stats :run_something
|
80
|
+
react :runner
|
87
81
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
if
|
93
|
-
|
82
|
+
process_to_run = "ruby -v"
|
83
|
+
process_to_run = ("cd #{project_folder} &&" + process_to_run) if defined?(project_folder)
|
84
|
+
stdout, stderr, status = Open3.capture3(process_to_run)
|
85
|
+
unreact :runner
|
86
|
+
if stderr == ""
|
87
|
+
if stdout == ""
|
88
|
+
respond "#{display_name}: Nothing returned."
|
89
|
+
else
|
90
|
+
respond "#{display_name}: #{stdout}"
|
91
|
+
end
|
94
92
|
else
|
95
|
-
respond "#{display_name}: #{stdout}"
|
93
|
+
respond "#{display_name}: #{stdout} #{stderr}"
|
96
94
|
end
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
# respond "the message", '@theuser'
|
114
|
-
# # send 'the message' to a specific user id as direct message
|
115
|
-
# respond "the message", 'US3344D3'
|
95
|
+
|
96
|
+
# Emoticons you can use with `react` command https://www.webfx.com/tools/emoji-cheat-sheet/
|
97
|
+
|
98
|
+
# Examples for respond and respond_direct
|
99
|
+
# # send 'the message' to the channel or direct message where the command was written
|
100
|
+
# respond "the message"
|
101
|
+
# # send 'the message' privately as a direct message to the user that sent the command
|
102
|
+
# respond_direct "the message"
|
103
|
+
# # send 'the message' to a specific channel name
|
104
|
+
# respond "the message", 'my_channel'
|
105
|
+
# # send 'the message' to a specific channel id
|
106
|
+
# respond "the message", 'CSU34D33'
|
107
|
+
# # send 'the message' to a specific user as direct message
|
108
|
+
# respond "the message", '@theuser'
|
109
|
+
# # send 'the message' to a specific user id as direct message
|
110
|
+
# respond "the message", 'US3344D3'
|
116
111
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
112
|
+
# Example downloading a file from slack
|
113
|
+
# if !files.nil? and files.size == 1 and files[0].filetype == 'yaml'
|
114
|
+
# require 'nice_http'
|
115
|
+
# http = NiceHttp.new(host: "https://files.slack.com", headers: { "Authorization" => "Bearer #{config[:token]}" })
|
116
|
+
# http.get(files[0].url_private_download, save_data: './tmp/')
|
117
|
+
# end
|
123
118
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
119
|
+
# Examples sending a file to slack:
|
120
|
+
# send_file(to, msg, filepath, title, format, type = "text")
|
121
|
+
# send_file(dest, 'the message', "#{project_folder}/temp/logs_ptBI.log", 'title', 'text/plain', "text")
|
122
|
+
# send_file(dest, 'the message', "#{project_folder}/temp/example.jpeg", 'title', 'image/jpeg', "jpg")
|
128
123
|
|
129
124
|
|
130
|
-
|
131
|
-
|
132
|
-
|
125
|
+
else
|
126
|
+
unless processed
|
127
|
+
dont_understand()
|
128
|
+
end
|
133
129
|
end
|
130
|
+
rescue => exception
|
131
|
+
@logger.fatal exception
|
132
|
+
respond "Unexpected error!! Please contact an admin to solve it: <@#{config.admins.join(">, <@")}>"
|
134
133
|
end
|
135
|
-
rescue => exception
|
136
|
-
@logger.fatal exception
|
137
|
-
respond "Unexpected error!! Please contact an admin to solve it: <@#{config.admins.join(">, <@")}>"
|
138
134
|
end
|
139
135
|
end
|
data/lib/slack/smart-bot/comm.rb
CHANGED
@@ -38,7 +38,7 @@ class SlackSmartBot
|
|
38
38
|
f.puts "|#{dest}|#{config[:nick_id]}|#{msg}"
|
39
39
|
}
|
40
40
|
end
|
41
|
-
elsif dest[0] == "D" or dest[0] == "U" # Direct message
|
41
|
+
elsif dest[0] == "D" or dest[0] == "U" or dest[0] == "W" # Direct message
|
42
42
|
send_msg_user(dest, msg)
|
43
43
|
elsif dest[0] == "@"
|
44
44
|
begin
|
@@ -3,9 +3,12 @@ class SlackSmartBot
|
|
3
3
|
#to send a file to an user or channel
|
4
4
|
#send_file(dest, 'the message', "#{project_folder}/temp/logs_ptBI.log", 'message to be sent', 'text/plain', "text")
|
5
5
|
#send_file(dest, 'the message', "#{project_folder}/temp/example.jpeg", 'message to be sent', 'image/jpeg', "jpg")
|
6
|
-
|
6
|
+
#send_file(dest, 'the message', "", 'message to be sent', 'text/plain', "ruby", content: "the content to be sent when no file supplied")
|
7
|
+
#send_file(dest, 'the message', "myfile.rb", 'message to be sent', 'text/plain', "ruby", content: "the content to be sent when no file supplied")
|
8
|
+
def send_file(to, msg, file, title, format, type = "text", content: '')
|
7
9
|
unless config[:simulate]
|
8
|
-
if
|
10
|
+
file = 'myfile' if file.to_s == '' and content!=''
|
11
|
+
if to[0] == "U" or to[0] == "W" #user
|
9
12
|
im = client.web_client.im_open(user: to)
|
10
13
|
channel = im["channel"]["id"]
|
11
14
|
else
|
@@ -18,16 +21,29 @@ class SlackSmartBot
|
|
18
21
|
ts = nil
|
19
22
|
end
|
20
23
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
24
|
+
if content.to_s == ''
|
25
|
+
client.web_client.files_upload(
|
26
|
+
channels: channel,
|
27
|
+
as_user: true,
|
28
|
+
file: Faraday::UploadIO.new(file, format),
|
29
|
+
title: title,
|
30
|
+
filename: file,
|
31
|
+
filetype: type,
|
32
|
+
initial_comment: msg,
|
33
|
+
thread_ts: ts
|
34
|
+
)
|
35
|
+
else
|
36
|
+
client.web_client.files_upload(
|
37
|
+
channels: channel,
|
38
|
+
as_user: true,
|
39
|
+
content: content,
|
40
|
+
title: title,
|
41
|
+
filename: file,
|
42
|
+
filetype: type,
|
43
|
+
initial_comment: msg,
|
44
|
+
thread_ts: ts
|
45
|
+
)
|
46
|
+
end
|
31
47
|
end
|
32
48
|
end
|
33
49
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class SlackSmartBot
|
2
|
+
# list of available emojis: https://www.webfx.com/tools/emoji-cheat-sheet/
|
3
|
+
# unreact(:thumbsup)
|
4
|
+
def unreact(emoji, parent=false)
|
5
|
+
if parent
|
6
|
+
ts = Thread.current[:thread_ts]
|
7
|
+
else
|
8
|
+
ts = Thread.current[:ts]
|
9
|
+
end
|
10
|
+
begin
|
11
|
+
client.web_client.reactions_remove(channel: Thread.current[:dest], name: emoji, timestamp: ts)
|
12
|
+
rescue Exception => stack
|
13
|
+
@logger.warn stack
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -5,6 +5,7 @@ class SlackSmartBot
|
|
5
5
|
# helpadmin: `add silent routine NAME every NUMBER PERIOD`
|
6
6
|
# helpadmin: `create routine NAME every NUMBER PERIOD`
|
7
7
|
# helpadmin: `add routine NAME at TIME COMMAND`
|
8
|
+
# helpadmin: `add routine NAME on DAYWEEK at TIME COMMAND`
|
8
9
|
# helpadmin: `add routine NAME at TIME`
|
9
10
|
# helpadmin: `add silent routine NAME at TIME`
|
10
11
|
# helpadmin: `create routine NAME at TIME`
|
@@ -15,12 +16,14 @@ class SlackSmartBot
|
|
15
16
|
# helpadmin: NUMBER: Integer
|
16
17
|
# helpadmin: PERIOD: days, d, hours, h, minutes, mins, min, m, seconds, secs, sec, s
|
17
18
|
# helpadmin: TIME: time at format HH:MM:SS
|
19
|
+
# helpadmin: DAYWEEK: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday. And their plurals.
|
18
20
|
# helpadmin: COMMAND: any valid smart bot command or rule
|
19
21
|
# helpadmin: Examples:
|
20
22
|
# helpadmin: _add routine example every 30s ruby puts 'a'_
|
21
23
|
# helpadmin: _add routine example every 3 days ruby puts 'a'_
|
22
24
|
# helpadmin: _add routine example at 17:05 ruby puts 'a'_
|
23
25
|
# helpadmin: _create silent routine every 12 hours !Run customer tests_
|
26
|
+
# helpadmin: _add routine example on Mondays at 05:00 !run customer tests_
|
24
27
|
# helpadmin:
|
25
28
|
def add_routine(dest, from, user, name, type, number_time, period, command_to_run, files, silent)
|
26
29
|
save_stats(__method__)
|
@@ -30,13 +33,14 @@ class SlackSmartBot
|
|
30
33
|
respond "I'm sorry but there is already a routine with that name.\nCall `see routines` to see added routines", dest
|
31
34
|
else
|
32
35
|
number_time += ":00" if number_time.split(":").size == 2
|
33
|
-
if (type
|
36
|
+
if (type != "every") && !number_time.match?(/^[01][0-9]:[0-5][0-9]:[0-5][0-9]$/) &&
|
34
37
|
!number_time.match?(/^2[0-3]:[0-5][0-9]:[0-5][0-9]$/)
|
35
38
|
respond "Wrong time specified: *#{number_time}*"
|
36
39
|
else
|
37
40
|
file_path = ""
|
38
41
|
every = ""
|
39
42
|
at = ""
|
43
|
+
dayweek = ''
|
40
44
|
next_run = Time.now
|
41
45
|
case period.downcase
|
42
46
|
when "days", "d"
|
@@ -52,16 +56,31 @@ class SlackSmartBot
|
|
52
56
|
every = "#{number_time} seconds"
|
53
57
|
every_in_seconds = number_time.to_i
|
54
58
|
else # time
|
59
|
+
if type != 'at'
|
60
|
+
dayweek = type.downcase
|
61
|
+
days = ['sunday','monday','tuesday','wednesday','thursday','friday','saturday']
|
62
|
+
incr = days.index(dayweek) - Time.now.wday
|
63
|
+
if incr < 0
|
64
|
+
incr = (7+incr)*24*60*60
|
65
|
+
else
|
66
|
+
incr = incr * 24 * 60 * 60
|
67
|
+
end
|
68
|
+
days = incr/(24*60*60)
|
69
|
+
every_in_seconds = 7 * 24 * 60 * 60 # one week
|
70
|
+
else
|
71
|
+
days = 0
|
72
|
+
every_in_seconds = 24 * 60 * 60 # one day
|
73
|
+
end
|
74
|
+
|
55
75
|
at = number_time
|
56
|
-
if next_run.strftime("%H:%M:%S") < number_time
|
76
|
+
if next_run.strftime("%H:%M:%S") < number_time and days == 0
|
57
77
|
nt = number_time.split(":")
|
58
78
|
next_run = Time.new(next_run.year, next_run.month, next_run.day, nt[0], nt[1], nt[2])
|
59
79
|
else
|
60
|
-
next_run += (24 * 60 * 60) # one more
|
80
|
+
next_run += ((24 * 60 * 60) * days) # one or more days
|
61
81
|
nt = number_time.split(":")
|
62
82
|
next_run = Time.new(next_run.year, next_run.month, next_run.day, nt[0], nt[1], nt[2])
|
63
83
|
end
|
64
|
-
every_in_seconds = 24 * 60 * 60
|
65
84
|
end
|
66
85
|
Dir.mkdir("#{config.path}/routines/#{@channel_id}") unless Dir.exist?("#{config.path}/routines/#{@channel_id}")
|
67
86
|
|
@@ -78,7 +97,7 @@ class SlackSmartBot
|
|
78
97
|
|
79
98
|
@routines[@channel_id] = {} unless @routines.key?(@channel_id)
|
80
99
|
@routines[@channel_id][name] = { channel_name: config.channel, creator: from, creator_id: user.id, status: :on,
|
81
|
-
every: every, every_in_seconds: every_in_seconds, at: at, file_path: file_path,
|
100
|
+
every: every, every_in_seconds: every_in_seconds, at: at, dayweek: dayweek, file_path: file_path,
|
82
101
|
command: command_to_run.to_s.strip, silent: silent,
|
83
102
|
next_run: next_run.to_s, dest: dest, last_run: "", last_elapsed: "",
|
84
103
|
running: false }
|
@@ -54,7 +54,7 @@ class SlackSmartBot
|
|
54
54
|
respond "Now the rules from <##{@channel_id}> are available on *<##{@channels_id[channel]}>*", dest
|
55
55
|
end
|
56
56
|
respond "<@#{user.id}> extended the rules from <##{@channel_id}> to this channel so now you can talk to the Smart Bot on demand using those rules.", @channels_id[channel]
|
57
|
-
respond "Use `!` before the command you want to run", @channels_id[channel]
|
57
|
+
respond "Use `!` or `^` or `!!` before the command you want to run", @channels_id[channel]
|
58
58
|
respond "To see the specific rules for this bot on this channel: `!bot rules` or `!bot rules COMMAND`", @channels_id[channel]
|
59
59
|
end
|
60
60
|
end
|
@@ -44,6 +44,7 @@ class SlackSmartBot
|
|
44
44
|
msg << "\tStatus: #{v[:status]}"
|
45
45
|
msg << "\tEvery: #{v[:every]}" unless v[:every] == ""
|
46
46
|
msg << "\tAt: #{v[:at]}" unless v[:at] == ""
|
47
|
+
msg << "\tOn: #{v[:dayweek]}" unless !v.key?(:dayweek) or v[:dayweek].to_s == ""
|
47
48
|
msg << "\tNext Run: #{v[:next_run]}"
|
48
49
|
msg << "\tLast Run: #{v[:last_run]}"
|
49
50
|
msg << "\tTime consumed on last run: #{v[:last_elapsed]}" unless v[:command] !=''
|
@@ -13,6 +13,7 @@ class SlackSmartBot
|
|
13
13
|
# helpadmin: `bot stats CHANNEL exclude masters from YYYY/MM/DD to YYYY/MM/DD`
|
14
14
|
# helpadmin: `bot stats today`
|
15
15
|
# helpadmin: `bot stats exclude COMMAND_ID`
|
16
|
+
# helpadmin: `bot stats monthly`
|
16
17
|
# helpadmin: To see the bot stats
|
17
18
|
# helpadmin: You can use this command only if you are a Master admin user and if you are in a private conversation with the bot
|
18
19
|
# helpadmin: You need to set stats to true to generate the stats when running the bot instance.
|
@@ -21,8 +22,9 @@ class SlackSmartBot
|
|
21
22
|
# helpadmin: _bot stats @peter.wind_
|
22
23
|
# helpadmin: _bot stats #sales from 2019/12/15 to 2019/12/31_
|
23
24
|
# helpadmin: _bot stats #sales today_
|
25
|
+
# helpadmin: _bot stats #sales from 2020-01-01 monthly_
|
24
26
|
# helpadmin:
|
25
|
-
def bot_stats(dest, from_user, typem, channel_id, from, to, user, exclude_masters, exclude_command)
|
27
|
+
def bot_stats(dest, from_user, typem, channel_id, from, to, user, exclude_masters, exclude_command, monthly)
|
26
28
|
require 'csv'
|
27
29
|
if config.stats
|
28
30
|
message = []
|
@@ -34,6 +36,10 @@ class SlackSmartBot
|
|
34
36
|
if !File.exist?("#{config.stats_path}.#{Time.now.strftime("%Y-%m")}.log")
|
35
37
|
message<<'No stats'
|
36
38
|
else
|
39
|
+
if user!=''
|
40
|
+
user_info = client.web_client.users_info(user: user)
|
41
|
+
user_name = user_info.user.name
|
42
|
+
end
|
37
43
|
from = "#{Time.now.strftime("%Y-%m")}-01" if from == ''
|
38
44
|
to = "#{Time.now.strftime("%Y-%m-%d")}" if to == ''
|
39
45
|
from_short = from
|
@@ -43,17 +49,28 @@ class SlackSmartBot
|
|
43
49
|
from+= " 00:00:00 +0000"
|
44
50
|
to+= " 23:59:59 +0000"
|
45
51
|
rows = []
|
52
|
+
rows_month = {}
|
53
|
+
users_month = {}
|
54
|
+
commands_month = {}
|
46
55
|
|
47
56
|
Dir["#{config.stats_path}.*.log"].sort.each do |file|
|
48
57
|
if file >= "#{config.stats_path}.#{from_file}.log" or file <= "#{config.stats_path}.#{to_file}.log"
|
49
58
|
CSV.foreach(file, headers: true, header_converters: :symbol, converters: :numeric) do |row|
|
50
59
|
row[:date] = row[:date].to_s
|
51
60
|
if !exclude_masters or (exclude_masters and !config.masters.include?(row[:user_name]))
|
52
|
-
if user=='' or (user!='' and row[:
|
61
|
+
if user=='' or (user!='' and row[:user_name] == user_name)
|
53
62
|
if exclude_command == '' or (exclude_command!='' and row[:command]!=exclude_command)
|
54
63
|
if row[:bot_channel_id] == channel_id or channel_id == ''
|
55
64
|
if row[:date] >= from and row[:date] <= to
|
56
65
|
rows << row.to_h
|
66
|
+
if monthly
|
67
|
+
rows_month[row[:date][0..6]] = 0 unless rows_month.key?(row[:date][0..6])
|
68
|
+
users_month[row[:date][0..6]] = [] unless users_month.key?(row[:date][0..6])
|
69
|
+
commands_month[row[:date][0..6]] = [] unless commands_month.key?(row[:date][0..6])
|
70
|
+
rows_month[row[:date][0..6]] += 1
|
71
|
+
users_month[row[:date][0..6]] << row[:user_name]
|
72
|
+
commands_month[row[:date][0..6]] << row[:command]
|
73
|
+
end
|
57
74
|
end
|
58
75
|
end
|
59
76
|
end
|
@@ -79,6 +96,21 @@ class SlackSmartBot
|
|
79
96
|
message << "*Total calls <##{channel_id}>*: #{total} from #{from_short} to #{to_short}"
|
80
97
|
end
|
81
98
|
if total > 0
|
99
|
+
if monthly
|
100
|
+
message << '*Totals by month / commands / users (%new)*'
|
101
|
+
all_users = []
|
102
|
+
new_users = []
|
103
|
+
rows_month.each do |k,v|
|
104
|
+
if all_users.empty?
|
105
|
+
message_new_users = ''
|
106
|
+
else
|
107
|
+
new_users = (users_month[k]-all_users).uniq
|
108
|
+
message_new_users = "(#{new_users.size*100/users_month[k].uniq.size}%)"
|
109
|
+
end
|
110
|
+
all_users += users_month[k]
|
111
|
+
message << "\t#{k}: #{v} (#{(v.to_f*100/total).round(2)}%) / #{commands_month[k].uniq.size} / #{users_month[k].uniq.size} #{message_new_users}"
|
112
|
+
end
|
113
|
+
end
|
82
114
|
|
83
115
|
if channel_id == ''
|
84
116
|
message << "*Channels*"
|
@@ -89,16 +121,16 @@ class SlackSmartBot
|
|
89
121
|
end
|
90
122
|
end
|
91
123
|
if user==''
|
92
|
-
message << "*Users*"
|
93
124
|
users = rows.user_name.uniq.sort
|
125
|
+
message << "*Users* - #{users.size}"
|
94
126
|
users.each do |user|
|
95
127
|
count = rows.count {|h| h.user_name==user}
|
96
128
|
message << "\t#{user}: #{count} (#{(count.to_f*100/total).round(2)}%)"
|
97
129
|
end
|
98
130
|
end
|
99
131
|
|
100
|
-
message << "*Commands*"
|
101
132
|
commands = rows.command.uniq.sort
|
133
|
+
message << "*Commands* - #{commands.size}"
|
102
134
|
commands.each do |command|
|
103
135
|
count = rows.count {|h| h.command==command}
|
104
136
|
message << "\t#{command}: #{count} (#{(count.to_f*100/total).round(2)}%)"
|
@@ -82,6 +82,7 @@ class SlackSmartBot
|
|
82
82
|
message = "Session name: *#{session_name}*
|
83
83
|
From now on I will execute all you write as a Ruby command and I will keep the session open until you send `quit` or `bye` or `exit`.
|
84
84
|
I will respond with the result so it is not necessary you send `print`, `puts`, `p` or `pp` unless you want it as the output when calling `run repl`.
|
85
|
+
Use `p` to print a message raw, exacly like it is returned.
|
85
86
|
If you want to avoid a message to be treated by me, start the message with '-'.
|
86
87
|
After 30 minutes of no communication with the Smart Bot the session will be dismissed.
|
87
88
|
If you want to see the methods of a class or module you created use _ls TheModuleOrClass_
|
@@ -100,34 +101,8 @@ class SlackSmartBot
|
|
100
101
|
require \"amazing_print\"
|
101
102
|
bindme' + serialt + ' = binding
|
102
103
|
eval(\"require \'nice_http\'\" , bindme' + serialt + ')
|
103
|
-
def repl_params(met)
|
104
|
-
res = []
|
105
|
-
met.parameters.each do |par|
|
106
|
-
if par[0]==:req
|
107
|
-
res << par[1].to_s
|
108
|
-
elsif par[0]==:keyreq
|
109
|
-
res << par[1].to_s + \":\"
|
110
|
-
elsif par[0]==:key
|
111
|
-
res << \"?\"+par[1].to_s + \":\"
|
112
|
-
elsif par[0]==:opt
|
113
|
-
res << \"?\"+par[1].to_s
|
114
|
-
elsif par[0]==:rest
|
115
|
-
res << \"*\"+par[1].to_s
|
116
|
-
elsif par[0]==:keyrest
|
117
|
-
res << \"**\"+par[1].to_s
|
118
|
-
else
|
119
|
-
res << par[1].to_s
|
120
|
-
end
|
121
|
-
end
|
122
|
-
\"(#{res.join(\", \")})\"
|
123
|
-
end
|
124
104
|
def ls(obj)
|
125
|
-
|
126
|
-
res = []
|
127
|
-
mets.each do |met|
|
128
|
-
res << \"#{met}#{repl_params(obj.method(met))}\"
|
129
|
-
end
|
130
|
-
res
|
105
|
+
(obj.methods - Object.methods)
|
131
106
|
end
|
132
107
|
|
133
108
|
file_input_repl = File.open(\"' + Dir.pwd + '/repl/' + @channel_id + '/' + session_name + '.input\", \"r\")
|
@@ -158,9 +133,15 @@ class SlackSmartBot
|
|
158
133
|
error = true
|
159
134
|
end
|
160
135
|
if resp_repl.to_s != \"\"
|
161
|
-
|
162
|
-
|
163
|
-
|
136
|
+
if code_to_run_repl.match?(/^\s*p\s+/i)
|
137
|
+
open(\"' + Dir.pwd + '/repl/' + @channel_id + '/' + session_name + '.output\", \"a+\") {|f|
|
138
|
+
f.puts \"\`\`\`\n#{resp_repl.inspect}\n\`\`\`\"
|
139
|
+
}
|
140
|
+
else
|
141
|
+
open(\"' + Dir.pwd + '/repl/' + @channel_id + '/' + session_name + '.output\", \"a+\") {|f|
|
142
|
+
f.puts \"\`\`\`\n#{resp_repl.ai}\n\`\`\`\"
|
143
|
+
}
|
144
|
+
end
|
164
145
|
unless error or !add_to_run_repl
|
165
146
|
open(\"' + Dir.pwd + '/repl/' + @channel_id + '/' + session_name + '.run\", \"a+\") {|f|
|
166
147
|
f.puts code_to_run_repl
|
@@ -198,7 +179,13 @@ class SlackSmartBot
|
|
198
179
|
sleep 0.2
|
199
180
|
resp_repl = file_output_repl.read
|
200
181
|
if resp_repl.to_s!=''
|
201
|
-
|
182
|
+
if resp_repl.to_s.lines.count < 60 and resp_repl.to_s.size < 3500
|
183
|
+
respond resp_repl, dest
|
184
|
+
else
|
185
|
+
resp_repl.gsub!(/^\s*```/,'')
|
186
|
+
resp_repl.gsub!(/```\s*$/,'')
|
187
|
+
send_file(dest, "", 'response.rb', "", 'text/plain', "ruby", content: resp_repl)
|
188
|
+
end
|
202
189
|
end
|
203
190
|
rescue Exception => excp
|
204
191
|
@logger.fatal excp
|
@@ -210,7 +197,7 @@ class SlackSmartBot
|
|
210
197
|
@repl_sessions[from][:command] = ''
|
211
198
|
code.gsub!("\\n", "\n")
|
212
199
|
code.gsub!("\\r", "\r")
|
213
|
-
# Disabled for the moment
|
200
|
+
# Disabled for the moment since it is deleting lines with '}'
|
214
201
|
#code.gsub!(/^\W*$/, "") #to remove special chars from slack when copy/pasting.
|
215
202
|
if code.match?(/System/i) or code.match?(/Kernel/i) or code.include?("File") or
|
216
203
|
code.include?("`") or code.include?("exec") or code.include?("spawn") or code.include?("IO.") or
|
@@ -52,7 +52,7 @@ class SlackSmartBot
|
|
52
52
|
Dir.mkdir("#{project_folder}/tmp") unless Dir.exist?("#{project_folder}/tmp")
|
53
53
|
Dir.mkdir("#{project_folder}/tmp/repl") unless Dir.exist?("#{project_folder}/tmp/repl")
|
54
54
|
File.write("#{project_folder}/tmp/repl/#{session_name}.rb", content, mode: "w+")
|
55
|
-
process_to_run = "ruby
|
55
|
+
process_to_run = "ruby ./tmp/repl/#{session_name}.rb"
|
56
56
|
process_to_run = ("cd #{project_folder} && #{process_to_run}") if defined?(project_folder)
|
57
57
|
respond "Running REPL #{session_name}"
|
58
58
|
stdout, stderr, status = Open3.capture3(process_to_run)
|
@@ -60,10 +60,19 @@ class SlackSmartBot
|
|
60
60
|
if stdout == ""
|
61
61
|
respond "*#{session_name}*: Nothing returned."
|
62
62
|
else
|
63
|
-
|
63
|
+
if stdout.to_s.lines.count < 60 and stdout.to_s.size < 3500
|
64
|
+
respond "*#{session_name}*: #{stdout}"
|
65
|
+
else
|
66
|
+
send_file(dest, "", 'response.rb', "", 'text/plain', "ruby", content: stdout)
|
67
|
+
end
|
64
68
|
end
|
65
69
|
else
|
66
|
-
|
70
|
+
if (stdout.to_s+stderr.to_s).lines.count < 60
|
71
|
+
respond "*#{session_name}*: #{stdout} #{stderr}"
|
72
|
+
else
|
73
|
+
send_file(dest, "", 'response.rb', "", 'text/plain', "ruby", content: (stdout.to_s+stderr.to_s))
|
74
|
+
end
|
75
|
+
|
67
76
|
end
|
68
77
|
end
|
69
78
|
else
|
@@ -15,7 +15,7 @@ class SlackSmartBot
|
|
15
15
|
message = ""
|
16
16
|
@repls.sort.to_h.each do |session_name, repl|
|
17
17
|
if (repl.creator_name == user.name or repl.type == :public) or (config.admins.include?(user.name) and typem == :on_dm)
|
18
|
-
message += "(#{repl.type}) *#{session_name}*: #{repl.description} / created: #{repl.created} / accessed: #{repl.accessed} / creator: #{repl.
|
18
|
+
message += "(#{repl.type}) *#{session_name}*: #{repl.description} / created: #{repl.created} / accessed: #{repl.accessed} / creator: #{repl.creator_name} / runs: #{repl.runs_by_creator+repl.runs_by_others} / gets: #{repl.gets} \n"
|
19
19
|
end
|
20
20
|
end
|
21
21
|
message = "No repls created" if message == ''
|
@@ -46,14 +46,19 @@ class SlackSmartBot
|
|
46
46
|
rules_file = "slack-smart-bot_rules_#{channel_id}_#{from.gsub(" ", "_")}.rb"
|
47
47
|
if defined?(RULES_FOLDER)
|
48
48
|
rules_file = RULES_FOLDER + rules_file
|
49
|
+
general_rules_file = RULES_FOLDER + 'general_rules.rb'
|
49
50
|
else
|
50
51
|
Dir.mkdir("#{config.path}/rules") unless Dir.exist?("#{config.path}/rules")
|
51
52
|
Dir.mkdir("#{config.path}/rules/#{channel_id}") unless Dir.exist?("#{config.path}/rules/#{channel_id}")
|
52
53
|
rules_file = "/rules/#{channel_id}/" + rules_file
|
54
|
+
general_rules_file = "/rules/general_rules.rb"
|
53
55
|
end
|
54
56
|
default_rules = (__FILE__).gsub(/slack\/smart-bot\/commands\/on_master\/create_bot\.rb$/, "slack-smart-bot_rules.rb")
|
57
|
+
default_general_rules = (__FILE__).gsub(/slack\/smart-bot\/commands\/on_master\/create_bot\.rb$/, "slack-smart-bot_general_rules.rb")
|
58
|
+
|
55
59
|
File.delete(config.path + rules_file) if File.exist?(config.path + rules_file)
|
56
60
|
FileUtils.copy_file(default_rules, config.path + rules_file) unless File.exist?(config.path + rules_file)
|
61
|
+
FileUtils.copy_file(default_general_rules, config.path + general_rules_file) unless File.exist?(config.path + general_rules_file)
|
57
62
|
admin_users = Array.new()
|
58
63
|
creator_info = client.web_client.users_info(user: channel_found.creator)
|
59
64
|
admin_users = [from, creator_info.user.name] + config.masters
|
@@ -70,7 +70,8 @@ class SlackSmartBot
|
|
70
70
|
channel = $1
|
71
71
|
kill_bot_on_channel(dest, from, channel)
|
72
72
|
when /^\s*(add|create)\s+(silent\s+)?routine\s+(\w+)\s+(every)\s+(\d+)\s*(days|hours|minutes|seconds|mins|min|secs|sec|d|h|m|s)\s*(\s.+)?\s*$/i,
|
73
|
-
|
73
|
+
/^\s*(add|create)\s+(silent\s+)?routine\s+(\w+)\s+on\s+(monday|tuesday|wednesday|thursday|friday|saturday|sunday)s?\s+at\s+(\d+:\d+:?\d+?)\s*()(\s.+)?\s*$/i,
|
74
|
+
/^\s*(add|create)\s+(silent\s+)?routine\s+(\w+)\s+(at)\s+(\d+:\d+:?\d+?)\s*()(\s.+)?\s*$/i
|
74
75
|
silent = $2.to_s!=''
|
75
76
|
name = $3.downcase
|
76
77
|
type = $4
|
@@ -105,12 +106,15 @@ class SlackSmartBot
|
|
105
106
|
st_to = st_to.gsub('.','-').gsub('/','-')
|
106
107
|
st_user = opts.scan(/<@([^>]+)>/).join
|
107
108
|
exclude_masters = opts.match?(/exclude\s+masters?/i)
|
109
|
+
monthly = false
|
108
110
|
if all_opts.include?('today')
|
109
111
|
st_from = st_to = "#{Time.now.strftime("%Y-%m-%d")}"
|
112
|
+
elsif all_opts.include?('monthly')
|
113
|
+
monthly = true
|
110
114
|
end
|
111
115
|
exclude_command = opts.scan(/exclude\s+([^\s]+)/i).join
|
112
116
|
exclude_command = '' if exclude_command == 'masters'
|
113
|
-
bot_stats(dest, from, typem, st_channel, st_from, st_to, st_user, exclude_masters, exclude_command)
|
117
|
+
bot_stats(dest, from, typem, st_channel, st_from, st_to, st_user, exclude_masters, exclude_command, monthly)
|
114
118
|
else
|
115
119
|
processed = false
|
116
120
|
end
|
@@ -166,11 +170,11 @@ class SlackSmartBot
|
|
166
170
|
ruby_code(dest, user, code, rules_file)
|
167
171
|
when /^\s*(private\s+)?(repl|irb|live)\s*()()()$/i,
|
168
172
|
/^\s*(private\s+)?(repl|irb|live)\s+([\w\-]+)()()\s*$/i,
|
169
|
-
/^\s*(private\s+)?(repl|irb|live)\s+([\w\-]+)\s*:\s
|
170
|
-
/^\s*(private\s+)?(repl|irb|live)\s+([\w\-]+)\s*:\s
|
173
|
+
/^\s*(private\s+)?(repl|irb|live)\s+([\w\-]+)\s*:\s+"([^"]+)"()\s*$/i,
|
174
|
+
/^\s*(private\s+)?(repl|irb|live)\s+([\w\-]+)\s*:\s+"([^"]+)"\s+(.+)\s*$/i,
|
171
175
|
/^\s*(private\s+)?(repl|irb|live)\s+([\w\-]+)()\s+(.+)\s*$/i,
|
172
176
|
/^\s*(private\s+)?(repl|irb|live)()\s+()(.+)\s*$/i
|
173
|
-
|
177
|
+
if $1.to_s!=''
|
174
178
|
type = :private
|
175
179
|
else
|
176
180
|
type = :public
|
@@ -206,7 +210,7 @@ class SlackSmartBot
|
|
206
210
|
end
|
207
211
|
run_repl(dest, user, session_name, env_vars.flatten, rules_file)
|
208
212
|
when /^\s*(delete|remove)\s+(repl|irb|live)\s+([\w\-]+)\s*$/i
|
209
|
-
repl_name = $3
|
213
|
+
repl_name = $3
|
210
214
|
delete_repl(dest, user, repl_name)
|
211
215
|
when /^\s*see\s+(repls|repl|irb|irbs)\s*$/i
|
212
216
|
see_repls(dest, user, typem)
|
@@ -32,6 +32,8 @@ class SlackSmartBot
|
|
32
32
|
data.text = CGI.unescapeHTML(data.text)
|
33
33
|
data.text.gsub!("\u00A0", " ") #to change (asc char 160) into blank space
|
34
34
|
end
|
35
|
+
data.text.gsub!('’', "'")
|
36
|
+
data.text.gsub!('“', '"')
|
35
37
|
rescue
|
36
38
|
@logger.warn "Impossible to unescape or clean format for data.text:#{data.text}"
|
37
39
|
end
|
@@ -115,6 +117,7 @@ class SlackSmartBot
|
|
115
117
|
begin
|
116
118
|
#todo: when changed @questions user_id then move user_info inside the ifs to avoid calling it when not necessary
|
117
119
|
user_info = client.web_client.users_info(user: data.user)
|
120
|
+
user_info.user.id = data.user #todo: remove this line when slack issue with Wxxxx Uxxxx fixed
|
118
121
|
if @questions.key?(user_info.user.name)
|
119
122
|
if data.text.match?(/^\s*(Bye|Bæ|Good\sBye|Adiós|Ciao|Bless|Bless\sBless|Adeu)\s(#{@salutations.join("|")})\s*$/i)
|
120
123
|
@questions.delete(user_info.user.name)
|
@@ -127,12 +130,8 @@ class SlackSmartBot
|
|
127
130
|
((@repl_sessions[user_info.user.name][:on_thread] and data.thread_ts == @repl_sessions[user_info.user.name][:thread_ts]) or
|
128
131
|
(!@repl_sessions[user_info.user.name][:on_thread] and data.thread_ts.to_s == '' ))
|
129
132
|
|
130
|
-
if data.text.
|
131
|
-
|
132
|
-
@repl_sessions[user_info.user.name][:command] = ""
|
133
|
-
else
|
134
|
-
@repl_sessions[user_info.user.name][:command] = data.text[3..-4]
|
135
|
-
end
|
133
|
+
if data.text.match(/^\s*```(.*)```\s*$/im)
|
134
|
+
@repl_sessions[user_info.user.name][:command] = $1
|
136
135
|
else
|
137
136
|
@repl_sessions[user_info.user.name][:command] = data.text
|
138
137
|
end
|
@@ -142,12 +141,8 @@ class SlackSmartBot
|
|
142
141
|
end
|
143
142
|
|
144
143
|
#when added special characters on the message
|
145
|
-
if command.
|
146
|
-
|
147
|
-
command = ''
|
148
|
-
else
|
149
|
-
command = command[3..-4]
|
150
|
-
end
|
144
|
+
if command.match(/^\s*```(.*)```\s*$/im)
|
145
|
+
command = $1
|
151
146
|
elsif command.size >= 2 and
|
152
147
|
((command[0] == "`" and command[-1] == "`") or (command[0] == "*" and command[-1] == "*") or (command[0] == "_" and command[-1] == "_"))
|
153
148
|
command = command[1..-2]
|
@@ -13,7 +13,6 @@ class SlackSmartBot
|
|
13
13
|
ruby = ""
|
14
14
|
end
|
15
15
|
@routines[@channel_id][name][:silent] = false if !@routines[@channel_id][name].key?(:silent)
|
16
|
-
|
17
16
|
if @routines[@channel_id][name][:at] == "" or
|
18
17
|
(@routines[@channel_id][name][:at] != "" and @routines[@channel_id][name][:running] and
|
19
18
|
@routines[@channel_id][name][:next_run] != "" and Time.now.to_s >= @routines[@channel_id][name][:next_run])
|
@@ -55,11 +54,34 @@ class SlackSmartBot
|
|
55
54
|
require "time"
|
56
55
|
every_in_seconds = Time.parse(@routines[@channel_id][name][:next_run]) - Time.now
|
57
56
|
elsif @routines[@channel_id][name][:at] != "" #coming from start after pause for 'at'
|
58
|
-
if
|
57
|
+
if @routines[@channel_id][name].key?(:dayweek) and @routines[@channel_id][name][:dayweek].to_s!=''
|
58
|
+
day = @routines[@channel_id][name][:dayweek]
|
59
|
+
days = ['sunday','monday','tuesday','wednesday','thursday','friday','saturday']
|
60
|
+
incr = days.index(day) - Time.now.wday
|
61
|
+
if incr < 0
|
62
|
+
incr = (7+incr)*24*60*60
|
63
|
+
else
|
64
|
+
incr = incr * 24 * 60 * 60
|
65
|
+
end
|
66
|
+
days = incr/(24*60*60)
|
67
|
+
weekly = true
|
68
|
+
else
|
69
|
+
days = 0
|
70
|
+
weekly = false
|
71
|
+
end
|
72
|
+
|
73
|
+
if started.strftime("%H:%M:%S") < @routines[@channel_id][name][:at] and days == 0
|
59
74
|
nt = @routines[@channel_id][name][:at].split(":")
|
60
75
|
next_run = Time.new(started.year, started.month, started.day, nt[0], nt[1], nt[2])
|
61
76
|
else
|
62
|
-
|
77
|
+
if days == 0 and started.strftime("%H:%M:%S") >= @routines[@channel_id][name][:at]
|
78
|
+
if weekly
|
79
|
+
days = 7
|
80
|
+
else
|
81
|
+
days = 1
|
82
|
+
end
|
83
|
+
end
|
84
|
+
next_run = started + (days * 24 * 60 * 60) # one more day/week
|
63
85
|
nt = @routines[@channel_id][name][:at].split(":")
|
64
86
|
next_run = Time.new(next_run.year, next_run.month, next_run.day, nt[0], nt[1], nt[2])
|
65
87
|
end
|
@@ -32,7 +32,11 @@ class SlackSmartBot
|
|
32
32
|
help = @help_messages.deep_copy
|
33
33
|
end
|
34
34
|
if rules_file != ""
|
35
|
-
help[:rules_file] =
|
35
|
+
help[:rules_file] = ''
|
36
|
+
help[:rules_file] += IO.readlines(config.path+rules_file).join.scan(/#\s*help\s*\w*:(.*)/i).join("\n") + "\n"
|
37
|
+
if File.exist?(config.path+'/rules/general_rules.rb')
|
38
|
+
help[:rules_file] += IO.readlines(config.path+'/rules/general_rules.rb').join.scan(/#\s*help\s*\w*:(.*)/i).join("\n")
|
39
|
+
end
|
36
40
|
end
|
37
41
|
help = remove_hash_keys(help, :admin_master) unless user_type == :admin_master
|
38
42
|
help = remove_hash_keys(help, :admin) unless user_type == :admin or user_type == :admin_master
|
metadata
CHANGED
@@ -1,35 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slack-smart-bot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mario Ruiz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-08-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: slack-ruby-client
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0.14'
|
20
17
|
- - ">="
|
21
18
|
- !ruby/object:Gem::Version
|
22
|
-
version: 0.
|
19
|
+
version: 0.15.0
|
20
|
+
- - "~>"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0.15'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
|
-
- - "~>"
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '0.14'
|
30
27
|
- - ">="
|
31
28
|
- !ruby/object:Gem::Version
|
32
|
-
version: 0.
|
29
|
+
version: 0.15.0
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0.15'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: nice_http
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -79,6 +79,9 @@ dependencies:
|
|
79
79
|
- - "~>"
|
80
80
|
- !ruby/object:Gem::Version
|
81
81
|
version: '1'
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 1.2.1
|
82
85
|
type: :runtime
|
83
86
|
prerelease: false
|
84
87
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -86,6 +89,9 @@ dependencies:
|
|
86
89
|
- - "~>"
|
87
90
|
- !ruby/object:Gem::Version
|
88
91
|
version: '1'
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: 1.2.1
|
89
95
|
- !ruby/object:Gem::Dependency
|
90
96
|
name: rspec
|
91
97
|
requirement: !ruby/object:Gem::Requirement
|
@@ -119,6 +125,7 @@ files:
|
|
119
125
|
- LICENSE
|
120
126
|
- README.md
|
121
127
|
- lib/slack-smart-bot.rb
|
128
|
+
- lib/slack-smart-bot_general_rules.rb
|
122
129
|
- lib/slack-smart-bot_rules.rb
|
123
130
|
- lib/slack/smart-bot/comm.rb
|
124
131
|
- lib/slack/smart-bot/comm/ask.rb
|
@@ -129,6 +136,7 @@ files:
|
|
129
136
|
- lib/slack/smart-bot/comm/send_file.rb
|
130
137
|
- lib/slack/smart-bot/comm/send_msg_channel.rb
|
131
138
|
- lib/slack/smart-bot/comm/send_msg_user.rb
|
139
|
+
- lib/slack/smart-bot/comm/unreact.rb
|
132
140
|
- lib/slack/smart-bot/commands.rb
|
133
141
|
- lib/slack/smart-bot/commands/general/bot_help.rb
|
134
142
|
- lib/slack/smart-bot/commands/general/bot_status.rb
|