slack-smart-bot 1.12.8 → 1.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +85 -12
- data/lib/slack/smart-bot/comm/respond.rb +1 -0
- data/lib/slack/smart-bot/comm/update.rb +13 -0
- data/lib/slack/smart-bot/comm.rb +1 -0
- data/lib/slack/smart-bot/commands/general/add_team.rb +1 -0
- data/lib/slack/smart-bot/commands/general/add_vacation.rb +5 -0
- data/lib/slack/smart-bot/commands/general/allow_access.rb +1 -1
- data/lib/slack/smart-bot/commands/general/delete_team.rb +1 -0
- data/lib/slack/smart-bot/commands/general/deny_access.rb +1 -1
- data/lib/slack/smart-bot/commands/general/public_holidays.rb +144 -0
- data/lib/slack/smart-bot/commands/general/see_announcements.rb +2 -2
- data/lib/slack/smart-bot/commands/general/see_memos_team.rb +202 -0
- data/lib/slack/smart-bot/commands/general/see_teams.rb +3 -175
- data/lib/slack/smart-bot/commands/general/see_vacations.rb +41 -21
- data/lib/slack/smart-bot/commands/general/set_public_holidays.rb +21 -0
- data/lib/slack/smart-bot/commands/general/update_team.rb +1 -0
- data/lib/slack/smart-bot/commands/general_bot_commands.rb +100 -8
- data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +27 -3
- data/lib/slack/smart-bot/commands/on_bot/admin/run_routine.rb +12 -8
- data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +33 -4
- data/lib/slack/smart-bot/commands/on_bot/admin/start_routine.rb +22 -1
- data/lib/slack/smart-bot/commands/on_bot/admin_master/send_message.rb +50 -4
- data/lib/slack/smart-bot/commands/on_bot/admin_master/update_message.rb +25 -0
- data/lib/slack/smart-bot/commands/on_bot/general/bot_stats.rb +8 -6
- data/lib/slack/smart-bot/commands/on_bot/repl.rb +55 -15
- data/lib/slack/smart-bot/commands/on_bot/ruby_code.rb +2 -1
- data/lib/slack/smart-bot/commands.rb +4 -0
- data/lib/slack/smart-bot/listen.rb +1 -1
- data/lib/slack/smart-bot/process.rb +36 -6
- data/lib/slack/smart-bot/process_first.rb +250 -188
- data/lib/slack/smart-bot/treat_message.rb +1 -1
- data/lib/slack/smart-bot/utils/build_help.rb +1 -1
- data/lib/slack/smart-bot/utils/create_routine_thread.rb +40 -4
- data/lib/slack/smart-bot/utils/decrypt.rb +15 -0
- data/lib/slack/smart-bot/utils/display_calendar.rb +86 -0
- data/lib/slack/smart-bot/utils/encrypt.rb +15 -0
- data/lib/slack/smart-bot/utils/encryption_get_key_iv.rb +29 -0
- data/lib/slack/smart-bot/utils/get_help.rb +1 -1
- data/lib/slack/smart-bot/utils/get_team_members.rb +39 -0
- data/lib/slack/smart-bot/utils/get_teams.rb +22 -16
- data/lib/slack/smart-bot/utils/get_vacations.rb +20 -15
- data/lib/slack/smart-bot/utils/save_stats.rb +2 -2
- data/lib/slack/smart-bot/utils/update_teams.rb +15 -9
- data/lib/slack/smart-bot/utils/update_vacations.rb +5 -3
- data/lib/slack/smart-bot/utils.rb +5 -0
- data/lib/slack-smart-bot.rb +9 -0
- data/lib/slack-smart-bot_general_commands.rb +33 -0
- data/lib/slack-smart-bot_general_rules.rb +2 -2
- data/whats_new.txt +15 -17
- metadata +27 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11331340784024ea3f35184a8e580ddbc80d54cf2bb30e5f21e643d0adfe471d
|
4
|
+
data.tar.gz: 39fc7e79977f18893e08215d78eda51af8e21dc25a4d5af3d0a8a33687d021f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d2536ec8de0e528516baed6b50a8ea6ffa9fae939e9c1a31f3d7e430cdcddc579373c8efa6a3a937e88b15d3a688ce9836a3874b3cd2e04c94eca3fc4b2d03a2
|
7
|
+
data.tar.gz: e7e51fa921bdb4e9542319723c82daae8d7d502fcb655b85fdecb17d4f6c3beaa9cbc29c27cb426ed36cbdf1083e960b69813d0dfd9acbf4803272d8fe5e30e8
|
data/README.md
CHANGED
@@ -10,37 +10,40 @@ The main scope of this ruby gem is to be used internally in your company so team
|
|
10
10
|
|
11
11
|
slack-smart-bot can create bots on demand, create shortcuts, run ruby code... just on a chat channel, you can access it just from your mobile phone if you want and run those tests you forgot to run, get the results, restart a server... no limits.
|
12
12
|
|
13
|
-
|
13
|
+
<img src="slack-smart-bot.png" width="150" height="150">![](slack.png)
|
14
14
|
|
15
15
|
# Table of Contents
|
16
16
|
|
17
17
|
- [Installation and configuration](#installation-and-configuration)
|
18
18
|
- [Usage](#usage)
|
19
|
-
* [creating the MASTER BOT](#creating-the-master-bot)
|
19
|
+
* [creating the MASTER BOT](#creating-the-master-bot) (A)
|
20
20
|
* [How to access the Smart Bot](#how-to-access-the-smart-bot)
|
21
21
|
* [Bot Help](#bot-help)
|
22
|
-
* [Bot Management](#bot-management)
|
23
|
-
+ [Cloud Bots](#cloud-bots)
|
24
|
-
* [Extending rules to other channels](#extending-rules-to-other-channels)
|
22
|
+
* [Bot Management](#bot-management) (A)
|
23
|
+
+ [Cloud Bots](#cloud-bots) (A)
|
24
|
+
* [Extending rules to other channels](#extending-rules-to-other-channels) (A)
|
25
25
|
* [Using rules from other channels](#using-rules-from-other-channels)
|
26
26
|
* [Running Ruby code on a conversation](#running-ruby-code-on-a-conversation)
|
27
27
|
+ [REPL](#repl)
|
28
|
-
* [Sending notifications](#sending-notifications)
|
28
|
+
* [Sending notifications](#sending-notifications) (A)
|
29
29
|
* [Shortcuts](#shortcuts)
|
30
30
|
* [Announcements](#announcements)
|
31
31
|
* [Share Messages](#share-messages)
|
32
32
|
* [See Statuses](#see-statuses)
|
33
|
-
* [Routines](#routines)
|
34
|
-
* [
|
33
|
+
* [Routines](#routines) (A)
|
34
|
+
* [Loops](#loops)
|
35
|
+
* [Control who has access to a command](#control-who-has-access-to-a-command) (A)
|
35
36
|
* [See favorite commands](#see-favorite-commands)
|
36
37
|
* [Teams](#teams)
|
37
38
|
* [Time off management](#time-off-management)
|
38
39
|
* [Tips](#tips)
|
39
|
-
+ [Send a file](#send-a-file)
|
40
|
-
+ [Download a file](#download-a-file)
|
40
|
+
+ [Send a file](#send-a-file) (A)
|
41
|
+
+ [Download a file](#download-a-file) (A)
|
41
42
|
- [Contributing](#contributing)
|
42
43
|
- [License](#license)
|
43
44
|
|
45
|
+
(A): Only for Admins
|
46
|
+
|
44
47
|
## Installation and configuration
|
45
48
|
|
46
49
|
$ gem install slack-smart-bot
|
@@ -94,6 +97,8 @@ SmartBot will notify about SmartBot status changes or any SmartBot incident if d
|
|
94
97
|
## Usage
|
95
98
|
|
96
99
|
### creating the MASTER BOT
|
100
|
+
> for admins
|
101
|
+
|
97
102
|
Let's guess the file you created was called my_smart_bot.rb so, just run it:
|
98
103
|
```
|
99
104
|
nohup ruby my_smart_bot.rb&
|
@@ -194,6 +199,8 @@ Also you can add general rules that will be available on all Smart Bot channels
|
|
194
199
|
If you have commands that want to make them available everywhere the Smart Bot is a member then add those commands to `./rules/general_commands.rb`.
|
195
200
|
|
196
201
|
### How to access the Smart Bot
|
202
|
+
> for all users
|
203
|
+
|
197
204
|
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.
|
198
205
|
|
199
206
|
On a Smart Bot channel you will be able to run some of the commands just by writing a command, for example: **_`bot help`_**
|
@@ -258,6 +265,8 @@ Examples:
|
|
258
265
|
>**_Smart-Bot>_** `You're very welcome`
|
259
266
|
|
260
267
|
### Bot Help
|
268
|
+
> for all users
|
269
|
+
|
261
270
|
To get a full list of all commands and rules for a specific Smart Bot: **_`bot help`_**. It will show only the specific available commands for the user requesting. By default it will display only a short version of the bot help, call **_`bot help expanded`_** to get a expanded version of all commands.
|
262
271
|
|
263
272
|
If you want to search just for a specific command: **_`bot help COMMAND`_** It will display expanded explanations for the command.
|
@@ -293,6 +302,8 @@ For the examples use _ and for the rules `. This is a good example of a Help sup
|
|
293
302
|
To see what's new just call `What's new`
|
294
303
|
|
295
304
|
### Bot Management
|
305
|
+
> for admins
|
306
|
+
|
296
307
|
To create a new bot on a channel, run on MASTER CHANNEL: **_`create bot on CHANNEL`_**. The admins of this new bot on that channel will be the MASTER ADMINS, the creator of the bot and the creator of that channel. It will create a new rules file linked to this new bot.
|
297
308
|
|
298
309
|
You can kill any bot running on any channel if you are an admin of that bot: **_`kill bot on CHANNEL`_**
|
@@ -316,11 +327,15 @@ You can add, remove and list admins of any channel by using: `add admin @user`,
|
|
316
327
|
To see the full list of available command ids on any channel call: `see command ids`
|
317
328
|
|
318
329
|
#### Cloud Bots
|
330
|
+
> for admins
|
331
|
+
|
319
332
|
If you want to create a bot that will be running on a different machine: **_`create cloud bot on CHANNEL`_**. Even though the cloud bots are running on different machines, the management can be done through the MASTER CHANNEL. The new cloud bot will be managed by your Master Bot like the others, closing, pausing...
|
320
333
|
|
321
334
|
Cloud Bots are typically used to run commands on specific environments or even different OS or networks.
|
322
335
|
|
323
336
|
### Extending rules to other channels
|
337
|
+
> for admins
|
338
|
+
|
324
339
|
If you want to extend the use of your specific rules on a Bot Channel to a third channel you can use the command: **_`extend rules to CHANNEL`_**
|
325
340
|
|
326
341
|
From that moment everybody part of that channel will be able to run the specific rules from the other channel but just on demand, for example: **_`!run something`_**
|
@@ -328,6 +343,8 @@ From that moment everybody part of that channel will be able to run the specific
|
|
328
343
|
To stop allowing it: **_`stop using rules on CHANNEL`_**
|
329
344
|
|
330
345
|
### Using rules from other channels
|
346
|
+
> for all users
|
347
|
+
|
331
348
|
To be able to access the rules from other channel or from a direct conversation with the bot, first of all you need to be a member of that channel. Then on a direct conversation with the Smart Bot or from another bot channel: **_`use rules from CHANNEL`_**
|
332
349
|
|
333
350
|
When you want to stop using those rules with the bot: **_`stop using rules from CHANNEL`_**
|
@@ -335,6 +352,8 @@ When you want to stop using those rules with the bot: **_`stop using rules from
|
|
335
352
|
Also you can always call the Smart Bot from any channel, even from channels without a running Smart Bot. You can use the External Call on Demand: **_`@NAME_OF_BOT on #CHANNEL_NAME COMMAND`_**. In this case you will call the bot on #CHANNEL_NAME.
|
336
353
|
|
337
354
|
### Running Ruby code on a conversation
|
355
|
+
> for all users
|
356
|
+
|
338
357
|
You can run Ruby code by using the command: **_`ruby THE_CODE`_**.
|
339
358
|
|
340
359
|
Example:
|
@@ -344,6 +363,8 @@ Example:
|
|
344
363
|
Also it is possible to attach a Ruby file and the Smart Bot will run and post the output. You need to select Ruby as file format. Or if you prefer it you can call the `ruby` command and on the same message supply a code block.
|
345
364
|
|
346
365
|
#### REPL
|
366
|
+
> for all users
|
367
|
+
|
347
368
|
Easily starts a REPL session so you will be able to create a script directly from the slack conversation. You will be able to share the REPL so they can run it or see the content.
|
348
369
|
|
349
370
|
It Will run all we write as a ruby command and will keep the session values until we finish the session sending `quit`, `exit` or `bye`
|
@@ -400,9 +421,13 @@ You can run repls and supply parameters to the repl that will be executed on the
|
|
400
421
|
Example:
|
401
422
|
>**_Peter>_** ``run repl Create10RandomUsers `request = {path: '/api-dev/users/'}` ``
|
402
423
|
|
424
|
+
If you want to add a collaborator while you are on a repl call `add collaborator @USER`. From that moment that user will be able to interact with the repl. You can add all the collaborators you want. When any collaborator wants to jump off the repl, that user can use the `quit` command.
|
425
|
+
|
403
426
|
Other REPL commands: `see repls`, `run repl SESSION_NAME ENV_VAR=value`, `get repl SESSION_NAME`, `delete repl SESSION_NAME`, `kill repl RUN_REPL_ID`
|
404
427
|
|
405
428
|
### Sending notifications
|
429
|
+
> for admins
|
430
|
+
|
406
431
|
You can send notifications from MASTER CHANNEL by using **_`notify MESSAGE`_**. All Bot Channels will be notified.
|
407
432
|
|
408
433
|
If you want to send a notification message to all channels the bot joined and direct conversations with the bot: **_`notify all MESSAGE`_**
|
@@ -410,6 +435,8 @@ If you want to send a notification message to all channels the bot joined and di
|
|
410
435
|
And if you want to send a notification message to the specified channel and to its extended channels: **_`notify #CHANNEL MESSAGE`_**
|
411
436
|
|
412
437
|
### Shortcuts
|
438
|
+
> for all users
|
439
|
+
|
413
440
|
Sometimes your commands or rules are too long and you want to add a shortcut to be executed.
|
414
441
|
|
415
442
|
If you have for example a rule like this: **_`run tests on customers android app`_** and you want to add a shortcut: **_`add shortcut run tca: run tests on customers android app`_**
|
@@ -439,6 +466,8 @@ Example:
|
|
439
466
|
To see available shortcuts: **_`see shortcuts`_** and to delete a particular shortcut: **_`delete shortcut NAME`_**
|
440
467
|
|
441
468
|
### Announcements
|
469
|
+
> for all users
|
470
|
+
|
442
471
|
You can add any announcement on any channel where the SmartBot is a member by using **_`add COLOR announcement MESSAGE`_** or **_`add EMOJI announcement MESSAGE`_**.
|
443
472
|
|
444
473
|
It will store the message on the announcement list labeled with the color/emoji specified, white by default. Possible colors white, green, yellow and red. Aliases for announcement: statement, declaration, message.
|
@@ -455,6 +484,8 @@ To see the announcements of the channel: **_`see announcements`_**, **_`see COLO
|
|
455
484
|
If you are a master admin and you are on master channel then you can call **_`publish announcements`_** that will publish the announcements on all channels. The messages stored on a DM won't be published. This is very convenient to be called from a *Routine* for example every weekday at 09:00.
|
456
485
|
|
457
486
|
### Share messages
|
487
|
+
> for all users
|
488
|
+
|
458
489
|
You can automatically share any new message that is posted on the channel and meet the specified criteria by using **_`share messages /REGEXP/ on #CHANNEL`_** or **_`share messages "TEXT" on #CHANNEL`_**.
|
459
490
|
|
460
491
|
This command is only available in public channels. The user adding the Share and the SmartBot need to be a member of both channels.
|
@@ -466,6 +497,8 @@ Examples:
|
|
466
497
|
To see the shares of the channel: **_`see shares`_** and to delete a particular share: **_`delete share ID`_**
|
467
498
|
|
468
499
|
### See statuses
|
500
|
+
> for all users
|
501
|
+
|
469
502
|
To see a list of statuses of the members in the channel you can call `see statuses`, `who is on vacation?`, `who is not on vacation?`, `who is on EMOJI`, `who is on EMOJI #CHANNEL`
|
470
503
|
|
471
504
|
You need to be a member of the channel to be able to get this info.
|
@@ -479,6 +512,8 @@ Examples:
|
|
479
512
|
>**_Peter>_** `who is available?`
|
480
513
|
|
481
514
|
### Routines
|
515
|
+
> for admins
|
516
|
+
|
482
517
|
To add specific commands to be run automatically every certain amount of time or a specific time: **_`add routine NAME every NUMBER PERIOD COMMAND`_** or **_`add routine NAME at TIME COMMAND`_**. Also just before the command you can supply the channel where you want to publish the results, if not channel supplied then it would be the SmartBot Channel or on the DM if the command is run from there. Remember the SmartBot needs to have access to the channel where you want to publish.
|
483
518
|
|
484
519
|
In case you create a *bgroutine* instead of a normal *routine* then the results of the run won't be published.
|
@@ -494,6 +529,7 @@ Examples:
|
|
494
529
|
>**_`add routine clean_custdb on Mondays at 05:00 !clean customers db`_**
|
495
530
|
>**_`add routine clean_custdb on Tuesdays at 09:00 #SREChannel !clean customers db`_**
|
496
531
|
>**_`add silent routine suggestions on weekdays at 09:00 suggest command`_**
|
532
|
+
>**_`add routine example on the 31st at 20:00 ^results sales monthly`_**
|
497
533
|
|
498
534
|
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. Also you can supply a script adding \`\`\`the code\`\`\` and specifying on the routine name the extension that will have. Only Master Admins are allowed to add files or scripts.
|
499
535
|
|
@@ -505,7 +541,24 @@ Other routine commands:
|
|
505
541
|
* **_`see routines`_**
|
506
542
|
* **_`see result routine NAME`_**
|
507
543
|
|
544
|
+
### Loops
|
545
|
+
> for all users
|
546
|
+
|
547
|
+
You can run any command or rule on a loop by using:
|
548
|
+
**_`for NUMBER times every NUMBER minutes COMMAND`_**
|
549
|
+
**_`for NUMBER times every NUMBER seconds COMMAND`_**
|
550
|
+
Maximum number of times to be used: 24. Minimum every 10 seconds. Maximum every 60 minutes.
|
551
|
+
|
552
|
+
To stop the execution of a loop you can use: **_`quit loop LOOP_ID`_**
|
553
|
+
Examples:
|
554
|
+
>**_`for 5 times every 1 minute ^ruby puts Time.now`_**
|
555
|
+
>**_`10 times every 30s !ruby puts Time.now`_**
|
556
|
+
>**_`24 times every 60m !get sales today`_**
|
557
|
+
>**_`quit loop 1`_**
|
558
|
+
>**_`stop iterator 12`_**
|
559
|
+
|
508
560
|
### Control who has access to a command
|
561
|
+
> for admins
|
509
562
|
|
510
563
|
You can add, remove and list admins of any channel by using: `add admin @user`, `remove admin @user` and `see admins`. You need to be the creator of the channel, a Master admin or an admin.
|
511
564
|
|
@@ -568,6 +621,7 @@ it will show the access rights for the specified command
|
|
568
621
|
The authorization is controlled by `save_stats` so it will be check out when calling `save_stats` or by calling `has_access?(:your_command_id)`
|
569
622
|
|
570
623
|
### See favorite commands
|
624
|
+
> for all users
|
571
625
|
|
572
626
|
It will display the favorite commands in that channel.
|
573
627
|
|
@@ -578,6 +632,7 @@ Examples:
|
|
578
632
|
>**_`most used commands`_**
|
579
633
|
|
580
634
|
### Teams
|
635
|
+
> for all users
|
581
636
|
|
582
637
|
You can add, update, see, ping and delete teams. When calling `see TEAM_NAME team` the availability of the members will be displayed.
|
583
638
|
`add team TEAM_NAME PROPERTIES` will add a team with the info supplied. In case it is supplied a channel with type 'members' the members of that channel would be considered members of the team.
|
@@ -629,10 +684,13 @@ Examples:
|
|
629
684
|
>**_`add jira to sales team : labels = SalesT AND status != Done`_**
|
630
685
|
>**_`add github to sales team : https://github.com/PeterBale/SalesBoom/issues?q=is%3Aissue+is%3Aopen+`_**
|
631
686
|
>**_`set :runner: on memo 7 team Sales`_**
|
687
|
+
>**_`see all memos from Sales team`_**
|
688
|
+
>**_`see bugs from Sales team dev`_**
|
632
689
|
|
633
|
-
Other team commands: **_`delete team TEAM_NAME`_**, **_`delete memo ID from team TEAM_NAME`_**, **_`set STATUS on memo ID TEAM_NAME team`_**
|
690
|
+
Other team commands: **_`delete team TEAM_NAME`_**, **_`delete memo ID from team TEAM_NAME`_**, **_`set STATUS on memo ID TEAM_NAME team`_**, **_`see MEMO_TYPE from TEAM_NAME team TOPIC`_**
|
634
691
|
|
635
692
|
### Time off management
|
693
|
+
> for all users
|
636
694
|
|
637
695
|
You will be able to add or remove vacation and sick periods by using `add vacation/sick from YYYY/MM/DD to YYYY/MM/DD`. The SmartBot will automatically set the users status to 🌴 or 🤒 and the expiration date when the user is on vacation or sick. The SmartBot won't be allowed to change the status of workspace admins or owners.
|
638
696
|
|
@@ -649,9 +707,24 @@ settings = {
|
|
649
707
|
}
|
650
708
|
```
|
651
709
|
|
652
|
-
|
710
|
+
If you want to see the public holidays for a specific country or country/region you can use the command `public holidays COUNTRY/REGION`. Examples: `public holidays Iceland`, `public holidays Spain/Madrid`, `public holidays United States/California 2024`, `public holidays Spain/Catalonia 2024/04`.
|
711
|
+
You need to set up an account on https://www.calendarific.com
|
712
|
+
Add to your Smartbot configuration:
|
713
|
+
```ruby
|
714
|
+
settings = {
|
715
|
+
public_holidays: {
|
716
|
+
api_key: API_KEY
|
717
|
+
}
|
718
|
+
}
|
719
|
+
```
|
720
|
+
|
721
|
+
When calling `see my time off` on a DM will display a calendar of the year with the days off, including public holidays
|
722
|
+
<img src="img/my_timeoff.png" width="650">
|
723
|
+
|
724
|
+
Other 'time off' commands: **_`remove time off ID`_**, **_`see my time off`_**, **_`see vacations @USER`_**, **_`time off team NAME`_**, **_`set public holidays to COUNTRY/REGION`_**
|
653
725
|
|
654
726
|
### Tips
|
727
|
+
> for admins
|
655
728
|
|
656
729
|
#### Send a file
|
657
730
|
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class SlackSmartBot
|
2
|
+
def update(channel, ts, text)
|
3
|
+
result = true
|
4
|
+
begin
|
5
|
+
resp = client.web_client.chat_update(channel: channel, as_user: true, ts: ts, text: text)
|
6
|
+
result = resp.ok.to_s == 'true'
|
7
|
+
rescue Exception => exc
|
8
|
+
result = false
|
9
|
+
@logger.fatal exc.inspect
|
10
|
+
end
|
11
|
+
return result
|
12
|
+
end
|
13
|
+
end
|
data/lib/slack/smart-bot/comm.rb
CHANGED
@@ -70,6 +70,7 @@ class SlackSmartBot
|
|
70
70
|
team[:creator] = user.name
|
71
71
|
team[:date] = Time.now.strftime("%Y-%m-%dT%H:%M:%S.000Z")[0..18]
|
72
72
|
new_team = {}
|
73
|
+
team[:name] = name
|
73
74
|
new_team[name.to_sym] = team
|
74
75
|
update_teams(new_team)
|
75
76
|
respond "The *#{name}* team has been added."
|
@@ -36,6 +36,11 @@ class SlackSmartBot
|
|
36
36
|
else
|
37
37
|
vacations = @vacations.deep_copy
|
38
38
|
vacations[user.name] ||= { user_id: user.id, periods: [] }
|
39
|
+
if !vacations[user.name].key?(:periods)
|
40
|
+
vacations[user.name][:user_id] = user.id
|
41
|
+
vacations[user.name][:periods] = []
|
42
|
+
end
|
43
|
+
|
39
44
|
if vacations[user.name].periods.empty?
|
40
45
|
vacation_id = 1
|
41
46
|
else
|
@@ -2,7 +2,7 @@ class SlackSmartBot
|
|
2
2
|
def allow_access(user, command_id, opt)
|
3
3
|
save_stats(__method__)
|
4
4
|
not_allowed = ["hi_bot", "bye_bot", "allow_access", "deny_access", "get_bot_logs", "add_routine", "pause_bot", "pause_routine", "remove_routine", "run_routine", "start_bot",
|
5
|
-
"start_routine", "delete_message", "send_message", "kill_bot_on_channel", "exit_bot", "notify_message", "publish_announcements", "set_general_message",
|
5
|
+
"start_routine", "delete_message", "update_message", "send_message", "kill_bot_on_channel", "exit_bot", "notify_message", "publish_announcements", "set_general_message",
|
6
6
|
"set_maintenance", "bot_help", "bot_rules"]
|
7
7
|
if !is_admin?(user.name)
|
8
8
|
respond "Only admins of this channel can use this command. Take a look who is an admin of this channel by calling `see admins`"
|
@@ -38,6 +38,7 @@ class SlackSmartBot
|
|
38
38
|
when /yes/i, /yep/i, /sure/i
|
39
39
|
answer_delete
|
40
40
|
@teams.delete(team_name.to_sym)
|
41
|
+
File.delete(File.join(config.path, "teams", "t_#{team_name}.yaml"))
|
41
42
|
update_teams()
|
42
43
|
respond "The team #{team_name} has been deleted."
|
43
44
|
when /no/i, /nope/i, /cancel/i
|
@@ -2,7 +2,7 @@ class SlackSmartBot
|
|
2
2
|
def deny_access(user, command_id)
|
3
3
|
save_stats(__method__)
|
4
4
|
not_allowed = ['hi_bot', 'bye_bot', "allow_access", "deny_access", "get_bot_logs", "add_routine", "pause_bot", "pause_routine", "remove_routine", "run_routine", "start_bot",
|
5
|
-
"start_routine", "delete_message", "send_message", "kill_bot_on_channel", "exit_bot", "notify_message", "publish_announcements", "set_general_message",
|
5
|
+
"start_routine", "delete_message", "update_message", "send_message", "kill_bot_on_channel", "exit_bot", "notify_message", "publish_announcements", "set_general_message",
|
6
6
|
"set_maintenance", 'bot_help', 'bot_rules']
|
7
7
|
if !is_admin?(user.name)
|
8
8
|
respond "Only admins of this channel can use this command. Take a look who is an admin of this channel by calling `see admins`"
|
@@ -0,0 +1,144 @@
|
|
1
|
+
def public_holidays(country_name, location, year, month, day, add_stats: true, publish_results: true)
|
2
|
+
save_stats(__method__) if add_stats
|
3
|
+
if config[:public_holidays][:api_key].to_s == ""
|
4
|
+
respond "Sorry, I don't have the API key for the public holidays #{config[:public_holidays][:host]}. Set it up on your SmartBot config file."
|
5
|
+
else
|
6
|
+
begin
|
7
|
+
found_location = true
|
8
|
+
http = NiceHttp.new("#{config[:public_holidays][:host]}/api/v2")
|
9
|
+
if !defined?(@countries_candelarific)
|
10
|
+
if File.exist?("#{config.path}/vacations/countries_candelarific.json")
|
11
|
+
@countries_candelarific = JSON.parse(File.read("#{config.path}/vacations/countries_candelarific.json"))
|
12
|
+
else
|
13
|
+
response = http.get "/countries?api_key=#{config[:public_holidays][:api_key]}"
|
14
|
+
countries_candelarific = response.data.json(:countries)
|
15
|
+
if countries_candelarific.is_a?(Array)
|
16
|
+
File.write("#{config.path}/vacations/countries_candelarific.json", countries_candelarific.to_json)
|
17
|
+
@countries_candelarific = JSON.parse(countries_candelarific.to_json)
|
18
|
+
else
|
19
|
+
@countries_candelarific = []
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
country = @countries_candelarific.find { |c| c.country_name.match?(/^\s*#{country_name}\s*$/i) }
|
24
|
+
if country.nil?
|
25
|
+
respond "Country #{country_name} not found"
|
26
|
+
else
|
27
|
+
country_original_name = country_name.downcase
|
28
|
+
country_region_id = country_name.downcase
|
29
|
+
country_region_id += "/#{location.downcase}" unless location.empty?
|
30
|
+
country_name = country["country_name"]
|
31
|
+
country_iso = country["iso-3166"]
|
32
|
+
states = []
|
33
|
+
if @public_holidays.key?(country_region_id) and @public_holidays[country_region_id].key?(year.to_s)
|
34
|
+
holidays = @public_holidays[country_region_id][year.to_s]
|
35
|
+
elsif File.exist?(File.join(config.path, "vacations", "#{year}_#{country_region_id.gsub("/", "_").gsub(" ", "_")}.json"))
|
36
|
+
holidays = (File.read(File.join(config.path, "vacations", "#{year}_#{country_region_id.gsub("/", "_").gsub(" ", "_")}.json"))).json()
|
37
|
+
elsif !location.empty? and File.exist?(File.join(config.path, "vacations", "#{year}_#{country_original_name.gsub("/", "_").gsub(" ", "_")}.json"))
|
38
|
+
holidays = (File.read(File.join(config.path, "vacations", "#{year}_#{country_original_name.gsub("/", "_").gsub(" ", "_")}.json"))).json()
|
39
|
+
holidays.each do |holiday|
|
40
|
+
if holiday.states.is_a?(Array)
|
41
|
+
states << holiday.states.name
|
42
|
+
else
|
43
|
+
states << holiday.states
|
44
|
+
end
|
45
|
+
end
|
46
|
+
holidays = holidays.select { |h| h.states.is_a?(String) and h.states == "All" or (h.states.is_a?(Array) and h.states.name.grep(/^\s*#{location}\s*$/i).length > 0) }
|
47
|
+
holidays_specific = holidays.select { |h| h.states.is_a?(Array) and h.states.name.grep(/^\s*#{location}\s*$/i).length > 0 }
|
48
|
+
found_location = false if holidays_specific.length == 0
|
49
|
+
else
|
50
|
+
response = http.get "/holidays?country=#{country_iso}&year=#{year}&day=#{day}&month=#{month}&api_key=#{config[:public_holidays][:api_key]}"
|
51
|
+
holidays = response.data.json(:holidays)
|
52
|
+
if location != ""
|
53
|
+
holidays.each do |holiday|
|
54
|
+
if holiday.states.is_a?(Array)
|
55
|
+
states << holiday.states.name
|
56
|
+
else
|
57
|
+
states << holiday.states
|
58
|
+
end
|
59
|
+
end
|
60
|
+
holidays = holidays.select { |h| h.states.is_a?(String) and h.states == "All" or (h.states.is_a?(Array) and h.states.name.grep(/^\s*#{location}\s*$/i).length > 0) }
|
61
|
+
holidays_specific = holidays.select { |h| h.states.is_a?(Array) and h.states.name.grep(/^\s*#{location}\s*$/i).length > 0 }
|
62
|
+
found_location = false if holidays_specific.length == 0
|
63
|
+
end
|
64
|
+
if day == "" and month == "" and holidays.is_a?(Array) and holidays.length > 0 and found_location
|
65
|
+
File.write(File.join(config.path, "vacations", "#{year}_#{country_region_id.gsub("/", "_").gsub(" ", "_")}.json"), holidays.to_json) if holidays.is_a?(Array)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
if day == "" and month == ""
|
69
|
+
date = year
|
70
|
+
elsif day == ""
|
71
|
+
date = "#{year}-#{"%02d" % month}"
|
72
|
+
else
|
73
|
+
date = "#{year}-#{"%02d" % month}-#{"%02d" % day}"
|
74
|
+
end
|
75
|
+
|
76
|
+
if holidays.is_a?(Array) and holidays.length > 0 and found_location
|
77
|
+
date_holiday = ""
|
78
|
+
messages = ["*Holidays in #{country_name}#{" #{location.downcase.capitalize}" unless location.empty?} in #{date}*"]
|
79
|
+
num_holidays_to_show = 0
|
80
|
+
all_holidays = []
|
81
|
+
states = []
|
82
|
+
holidays_to_add = []
|
83
|
+
holidays.each do |holiday|
|
84
|
+
if holiday.type.join.match?(/holiday/i)
|
85
|
+
if location == "" or (location != "" and (holiday.states.is_a?(String) and holiday.states == "All") or (holiday.states.is_a?(Array) and holiday.states.name.grep(/#{location}/i).length > 0))
|
86
|
+
holiday_id = "#{holiday[:date][:datetime][:year]}-#{"%02d" % holiday[:date][:datetime][:month]}-#{"%02d" % holiday[:date][:datetime][:day]} #{holiday[:name]}"
|
87
|
+
unless all_holidays.include?(holiday_id) or
|
88
|
+
(day != "" and holiday[:date][:datetime][:day] != day.to_i) or
|
89
|
+
(month != "" and holiday[:date][:datetime][:month] != month.to_i)
|
90
|
+
all_holidays << holiday_id
|
91
|
+
if day == ""
|
92
|
+
m = holiday[:date][:datetime][:month]
|
93
|
+
d = holiday[:date][:datetime][:day]
|
94
|
+
date_holiday = " #{holiday[:date][:datetime][:year]}-#{"%02d" % m}-#{"%02d" % d} "
|
95
|
+
end
|
96
|
+
num_holidays_to_show += 1
|
97
|
+
break if num_holidays_to_show > 30 and publish_results
|
98
|
+
week_day = Date.new(holiday[:date][:datetime][:year], holiday[:date][:datetime][:month], holiday[:date][:datetime][:day]).strftime("%A")
|
99
|
+
messages << "\t:spiral_calendar_pad:#{date_holiday}*#{holiday[:name]}* _(#{holiday[:type].join(", ")}) (#{week_day})_"
|
100
|
+
messages << "\t#{holiday[:description]}"
|
101
|
+
if location == ""
|
102
|
+
if holiday.states.is_a?(Array)
|
103
|
+
messages << "\tLocations: #{holiday.states.name.sort.join(", ")}"
|
104
|
+
else
|
105
|
+
messages << "\tLocations: #{holiday.states}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
if holiday.states.is_a?(Array)
|
109
|
+
states << holiday.states.name
|
110
|
+
else
|
111
|
+
states << holiday.states
|
112
|
+
end
|
113
|
+
messages << "\n"
|
114
|
+
holidays_to_add << holiday
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
@public_holidays[country_region_id] = {} if !@public_holidays.key?(country_region_id)
|
120
|
+
@public_holidays[country_region_id][year.to_s] = holidays_to_add if !@public_holidays[country_region_id].key?(year.to_s)
|
121
|
+
|
122
|
+
if num_holidays_to_show > 30
|
123
|
+
messages = ["*Holidays in #{country_name}#{" #{location.downcase.capitalize}" unless location.empty?} in #{date}*"]
|
124
|
+
messages << "Too many holidays to show, please refine your search"
|
125
|
+
end
|
126
|
+
else
|
127
|
+
messages = ["*No holidays found in #{country_name}#{" #{location.downcase.capitalize}" unless location.empty?} in #{date}. Be sure the Country and State are written correctly. Try using just the Country, not all countries are supporting States.*"]
|
128
|
+
end
|
129
|
+
states.flatten!
|
130
|
+
states.uniq!
|
131
|
+
states.delete("All")
|
132
|
+
if states.length > 1 and (location == "" or !found_location)
|
133
|
+
messages << "*All States found in #{date} #{country_name}*: #{states.sort.join(", ")}"
|
134
|
+
respond messages[-1] if !publish_results
|
135
|
+
end
|
136
|
+
respond messages.join("\n") unless !publish_results
|
137
|
+
end
|
138
|
+
rescue Exception => stack
|
139
|
+
respond "Sorry, I can't get the public holidays for #{country_name} #{location} in #{date}. Error: #{stack.message}"
|
140
|
+
@logger.fatal stack
|
141
|
+
end
|
142
|
+
return (found_location==true and !country.nil?) if !publish_results
|
143
|
+
end
|
144
|
+
end
|
@@ -74,9 +74,9 @@ class SlackSmartBot
|
|
74
74
|
user_created = user_info.profile.display_name unless user_info.nil?
|
75
75
|
end
|
76
76
|
if type == 'all' and channel_id[0]=='D'
|
77
|
-
message << "\t#{m[:message_id]}
|
77
|
+
message << "\t#{emoji} *private* _(id:#{m[:message_id]} - #{m[:date]} #{m[:time]})_"
|
78
78
|
else
|
79
|
-
message << "\t#{m[:
|
79
|
+
message << "\t#{emoji} #{m[:message]} _(id:#{m[:message_id]} - #{m[:date]} #{m[:time]} #{user_created})_"
|
80
80
|
end
|
81
81
|
end
|
82
82
|
end
|