slack-smart-bot 1.13.2 → 1.14.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +142 -69
  3. data/lib/slack/smart-bot/ai/open_ai/connect.rb +61 -0
  4. data/lib/slack/smart-bot/ai/open_ai/models.rb +21 -0
  5. data/lib/slack/smart-bot/ai/open_ai/send_gpt_chat.rb +24 -0
  6. data/lib/slack/smart-bot/ai/open_ai/send_image_edit.rb +23 -0
  7. data/lib/slack/smart-bot/ai/open_ai/send_image_generation.rb +18 -0
  8. data/lib/slack/smart-bot/ai/open_ai/send_image_variation.rb +22 -0
  9. data/lib/slack/smart-bot/ai/open_ai/whisper_transcribe.rb +21 -0
  10. data/lib/slack/smart-bot/ai.rb +8 -0
  11. data/lib/slack/smart-bot/comm/get_channel_members.rb +15 -13
  12. data/lib/slack/smart-bot/comm/get_channels.rb +31 -29
  13. data/lib/slack/smart-bot/comm/respond_thread.rb +2 -2
  14. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat.rb +40 -0
  15. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_edit_image.rb +66 -0
  16. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_generate_image.rb +65 -0
  17. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_models.rb +37 -0
  18. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_variations_image.rb +84 -0
  19. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_whisper.rb +51 -0
  20. data/lib/slack/smart-bot/commands/general/bot_help.rb +1 -0
  21. data/lib/slack/smart-bot/commands/general/personal_settings.rb +38 -0
  22. data/lib/slack/smart-bot/commands/general/poster.rb +107 -104
  23. data/lib/slack/smart-bot/commands/general/public_holidays.rb +116 -114
  24. data/lib/slack/smart-bot/commands/general/set_public_holidays.rb +6 -2
  25. data/lib/slack/smart-bot/commands/general/teams/add_team.rb +87 -0
  26. data/lib/slack/smart-bot/commands/general/teams/delete_team.rb +69 -0
  27. data/lib/slack/smart-bot/commands/general/teams/memos/add_memo_team.rb +136 -0
  28. data/lib/slack/smart-bot/commands/general/teams/memos/add_memo_team_comment.rb +37 -0
  29. data/lib/slack/smart-bot/commands/general/teams/memos/delete_memo_team.rb +83 -0
  30. data/lib/slack/smart-bot/commands/general/teams/memos/see_memo_team.rb +97 -0
  31. data/lib/slack/smart-bot/commands/general/teams/memos/see_memos_team.rb +304 -0
  32. data/lib/slack/smart-bot/commands/general/teams/memos/set_memo_status.rb +66 -0
  33. data/lib/slack/smart-bot/commands/general/teams/ping_team.rb +104 -0
  34. data/lib/slack/smart-bot/commands/general/teams/see_teams.rb +236 -0
  35. data/lib/slack/smart-bot/commands/general/teams/see_vacations_team.rb +183 -0
  36. data/lib/slack/smart-bot/commands/general/teams/update_team.rb +137 -0
  37. data/lib/slack/smart-bot/commands/general_bot_commands.rb +905 -741
  38. data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +1 -0
  39. data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +2 -2
  40. data/lib/slack/smart-bot/commands/on_bot/general/bot_stats.rb +379 -353
  41. data/lib/slack/smart-bot/commands/on_bot/repl.rb +6 -107
  42. data/lib/slack/smart-bot/commands/on_bot/repl_client.rb +233 -0
  43. data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +17 -4
  44. data/lib/slack/smart-bot/commands.rb +26 -10
  45. data/lib/slack/smart-bot/process.rb +14 -3
  46. data/lib/slack/smart-bot/process_first.rb +36 -2
  47. data/lib/slack/smart-bot/treat_message.rb +28 -0
  48. data/lib/slack/smart-bot/utils/check_vacations.rb +1 -0
  49. data/lib/slack/smart-bot/utils/create_routine_thread.rb +1 -1
  50. data/lib/slack/smart-bot/utils/display_calendar.rb +17 -10
  51. data/lib/slack/smart-bot/utils/encryption/decrypt.rb +23 -0
  52. data/lib/slack/smart-bot/utils/encryption/encrypt.rb +27 -0
  53. data/lib/slack/smart-bot/utils/{encryption_get_key_iv.rb → encryption/encryption_get_key_iv.rb} +12 -8
  54. data/lib/slack/smart-bot/utils/get_help.rb +3 -1
  55. data/lib/slack/smart-bot/utils/get_personal_settings.rb +14 -0
  56. data/lib/slack/smart-bot/utils/get_teams.rb +2 -2
  57. data/lib/slack/smart-bot/utils/get_vacations.rb +2 -2
  58. data/lib/slack/smart-bot/utils/save_stats.rb +3 -1
  59. data/lib/slack/smart-bot/utils/update_personal_settings.rb +18 -0
  60. data/lib/slack/smart-bot/utils/update_teams.rb +1 -1
  61. data/lib/slack/smart-bot/utils/update_vacations.rb +1 -1
  62. data/lib/slack/smart-bot/utils.rb +5 -3
  63. data/lib/slack-smart-bot.rb +12 -0
  64. data/whats_new.txt +13 -14
  65. metadata +63 -15
  66. data/lib/slack/smart-bot/commands/general/add_memo_team.rb +0 -117
  67. data/lib/slack/smart-bot/commands/general/add_team.rb +0 -81
  68. data/lib/slack/smart-bot/commands/general/delete_memo_team.rb +0 -69
  69. data/lib/slack/smart-bot/commands/general/delete_team.rb +0 -55
  70. data/lib/slack/smart-bot/commands/general/ping_team.rb +0 -100
  71. data/lib/slack/smart-bot/commands/general/see_memos_team.rb +0 -202
  72. data/lib/slack/smart-bot/commands/general/see_teams.rb +0 -230
  73. data/lib/slack/smart-bot/commands/general/see_vacations_team.rb +0 -136
  74. data/lib/slack/smart-bot/commands/general/set_memo_status.rb +0 -58
  75. data/lib/slack/smart-bot/commands/general/update_team.rb +0 -131
  76. data/lib/slack/smart-bot/utils/decrypt.rb +0 -15
  77. data/lib/slack/smart-bot/utils/encrypt.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1d49cea86f54f8c7486c39dfbdb0c9e871a5b2d740c06e80242f120e9f3c8b38
4
- data.tar.gz: fb3d52d42693d1dba820685d7ef0bada290298de9db2cd00212e1196c2baaae8
3
+ metadata.gz: 37c704bfddd83d7a7d34f9b15cea3cf8d1f01dde28c11c9e9bea01fb6ac9db19
4
+ data.tar.gz: 9785ce98b6695b77aaf89a0e239142e2443a4d812c2dcb1fe3119953f516d023
5
5
  SHA512:
6
- metadata.gz: 261ac1f20a7bdec84c5e5b24278584656def3ab09dc0bf2f4fc17080a812952a18474bff74f845fcc83e8783b121e00be555086ea7159bd362b955236c4b1dc6
7
- data.tar.gz: ea5fe6b71b79f696727a1a54585e6a2b450c381fa7daadc6e351e9513e3a0b878c7869683b2df4db35997071af06d17a1d55d03f465421aa701e9bd727adef88
6
+ metadata.gz: 8e287b2173246c2adc1805738c87a6428ef43776213294558e1e900b29a03094df9b16d44b3a754d7b52d6a774a1a44da946cb553c4a5c9e83ca76b651239a1a
7
+ data.tar.gz: 9100ceee4ac4efd07a9ae4fae9d9014d00417626b0650bcd9bfa3824ff4070812cd9dfc79bbf26d68b088a43600ad22a469a40c137f4d9634066e9c2d133a596
data/README.md CHANGED
@@ -3,6 +3,10 @@
3
3
  [![Gem Version](https://badge.fury.io/rb/slack-smart-bot.svg)](https://rubygems.org/gems/slack-smart-bot)
4
4
  [![Build Status](https://travis-ci.com/MarioRuiz/slack-smart-bot.svg?branch=master)](https://github.com/MarioRuiz/slack-smart-bot)
5
5
  [![Coverage Status](https://coveralls.io/repos/github/MarioRuiz/slack-smart-bot/badge.svg?branch=master)](https://coveralls.io/github/MarioRuiz/slack-smart-bot?branch=master)
6
+ ![Gem](https://img.shields.io/gem/dt/slack-smart-bot)
7
+ ![GitHub commit activity](https://img.shields.io/github/commit-activity/y/MarioRuiz/slack-smart-bot)
8
+ ![GitHub last commit](https://img.shields.io/github/last-commit/MarioRuiz/slack-smart-bot)
9
+ ![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/MarioRuiz/slack-smart-bot)
6
10
 
7
11
  Create a Slack bot that is really smart and so easy to expand.
8
12
 
@@ -10,7 +14,7 @@ The main scope of this ruby gem is to be used internally in your company so team
10
14
 
11
15
  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
16
 
13
- <img src="slack-smart-bot.png" width="150" height="150">![](slack.png)
17
+ <img src="./img/smart-bot.png" width="150" height="150">![](./img/slack.png)
14
18
 
15
19
  # Table of Contents
16
20
 
@@ -36,6 +40,14 @@ slack-smart-bot can create bots on demand, create shortcuts, run ruby code... ju
36
40
  * [See favorite commands](#see-favorite-commands)
37
41
  * [Teams](#teams)
38
42
  * [Time off management](#time-off-management)
43
+ * [OpenAI](#openai)
44
+ + [OpenAI Set up](#openai-setup)
45
+ + [Chat GPT](#chatgpt)
46
+ + [Image Generation](#image-generation)
47
+ + [Image Variations](#image-variations)
48
+ + [Image Editing](#image-editing)
49
+ + [Whisper](#whisper)
50
+ + [Models](#models)
39
51
  * [Tips](#tips)
40
52
  + [Send a file](#send-a-file) (A)
41
53
  + [Download a file](#download-a-file) (A)
@@ -219,28 +231,16 @@ To run a command on demand and add the response on a thread:
219
231
  **_`^THE_COMMAND`_**
220
232
  **_`!!THE_COMMAND`_**
221
233
 
222
- Examples run a command on demand:
223
- >**_Peter>_** `!ruby puts Time.now`
224
- >**_Smart-Bot>_** `2019-10-23 12:43:42 +0000`
234
+ Examples run a command on demand:
225
235
 
226
- >**_Peter>_** `@smart-bot echo Example`
227
- >**_Smart-Bot>_** `Example`
236
+ <img src="img/commands_on_demand.png" width="400">
228
237
 
229
- >**_Peter>_** `smart-bot see shortcuts`
230
- >**_Smart-Bot>_** `Available shortcuts for Peter:`
231
- >`Spanish account: ruby require 'iso/iban'; 10.times {puts ISO::IBAN.random('ES')}`
232
- >**_Peter>_** `!!echo Example`
233
- >. . . . . . . . .**_Smart-Bot>_** `Example`
234
- >**_Peter>_** `^echo Example`
235
- >. . . . . . . . .**_Smart-Bot>_** `Example`
236
238
 
237
239
  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. You can supply more than one channel then all the bots will respond. In case you are in a private conversation with the Smart Bot (DM) then you can use directly: **_`#CHANNEL_NAME COMMAND`_** or **_`on #CHANNEL_NAME COMMAND`_**
238
240
 
239
- Examples:
240
- >**_Peter>_** `@smart-bot on #the_channel ruby puts Time.now`
241
- >**_Smart-Bot>_** `2019-10-23 12:43:42 +0000`
242
- >**_Peter>_** `@smart-bot on #the_channel ^ruby puts Time.now`
243
- >. . . . . . . . .**_Smart-Bot>_** `2019-10-23 12:43:42 +0000`
241
+ Examples:
242
+
243
+ <img src="img/commands_on_external_call.png" width="400">
244
244
 
245
245
  Examples on DM:
246
246
  >**_Peter>_** `#sales show report from India`
@@ -248,14 +248,8 @@ Examples on DM:
248
248
 
249
249
  If you want the Smart Bot just listen to part of the message you send, add the commands you want using '`' and start the line with '-!', '-!!' or '-^'
250
250
 
251
- Examples:
252
- >**_Peter>_** ``-!This text won't be treated but this one yes `ruby puts 'a'` and also this one `ruby puts 'b'` ``
253
- >**_Smart-Bot>_** `a`
254
- >**_Smart-Bot>_** `b`
255
-
256
- >**_Peter>_** ``-^This text won't be treated but this one yes `ruby puts 'a'` and also this one `ruby puts 'b'` ``
257
- >. . . . . . . . .**_Smart-Bot>_** `a`
258
- >. . . . . . . . .**_Smart-Bot>_** `b`
251
+ Examples:
252
+ <img src="img/commands_inline.png" width="400">
259
253
 
260
254
 
261
255
  All the commands specified on `./rules/general_commands.rb` will be accessible from any channel where the Smart Bot is present, without the necessity to call it with !, !!, ^ or on demand.
@@ -275,10 +269,9 @@ To show only the specific rules of the Smart Bot defined on the rules file: **_`
275
269
 
276
270
  Also you can call `suggest command` or `random command` and SmartBot will return the help content for a random command.
277
271
 
278
- Example:
279
- >**_Peter>_** `bot help echo`
280
- >**_Smart-Bot>_** `echo SOMETHING`
281
- `repeats SOMETHING`
272
+ Example:
273
+ <img src="img/command_bot_help_echo.png" width="300">
274
+
282
275
 
283
276
  When you call a command that is not recognized, you will get suggestions from the Smart Bot.
284
277
 
@@ -356,9 +349,9 @@ Also you can always call the Smart Bot from any channel, even from channels with
356
349
 
357
350
  You can run Ruby code by using the command: **_`ruby THE_CODE`_**.
358
351
 
359
- Example:
360
- >**_Peter>_** `!ruby require 'json'; res=[]; 20.times {res.push rand(100)}; my_json={result: res}; puts my_json.to_json`
361
- >**_Smart-Bot>_** `{"result":[63,66,35,83,44,40,72,25,59,73,75,54,56,91,19,6,68,1,25,3]}`
352
+ Example:
353
+ <img src="img/command_ruby.png" width="500">
354
+
362
355
 
363
356
  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.
364
357
 
@@ -382,9 +375,9 @@ By default it will be automatically loaded the gems: `string_pattern`, `nice_has
382
375
 
383
376
  To pre-execute some ruby when starting the session add the code to `.smart-bot-repl` file on the project root folder defined on `project_folder`. Then that file will be always executed before the REPL started or created. In that case if we want to avoid to run that file before the REPL we can do it adding the word 'clean' before the command `clean repl`.
384
377
 
385
- If you want to see the methods of a class or module you created use `ls TheModuleOrClass`
378
+ If you want to see the methods of a class or module you created use `ls TheModuleOrClass`. To see all documentation of a method: `doc TheModuleOrClass.method_name`. And to see the source code of a method: `code TheModuleOrClass.method_name`. Examples: `ls Sales`, `doc Sales.list`, `code Sales.list`
386
379
 
387
- You can supply the Environmental Variables you need for the Session
380
+ You can supply the Environmental Variables you need for the Session
388
381
 
389
382
  Examples:
390
383
  _repl CreateCustomer LOCATION=spain HOST='https://10.30.40.50:8887'_
@@ -394,28 +387,16 @@ Examples:
394
387
  _repl_
395
388
 
396
389
 
397
- Running Example:
398
- >**_Peter>_** `!repl Create10RandomUsers: "This is just an example"`
399
- >**_Smart-Bot>_** `Session name: *Create10RandomUsers*`
400
- >**_Peter>_** `http = NiceHttp.new("https://reqres.in/")`
401
- >**_Smart-Bot>_** `#<NiceHttp:0x00007fc6e216e328 @host="reqres.in", @port=443...>`
402
- >**_Peter>_** `request ||= { path: '/api/users' }`
403
- >**_Smart-Bot>_** `{ :path => "/api/users" }`
404
- >**_Peter>_** `request.data = { name: '1-10:L', job: 'leader|worker' }`
405
- >**_Smart-Bot>_** `{ :name => "1-10:L", :job => "leader|worker" }`
406
- >**_Peter>_** `request.data.generate`
407
- >**_Smart-Bot>_** `{ :name => "kLam", :job => "leader" }`
408
- >**_Peter>_** `10.times { http.post(request.generate) } `
409
- >**_Smart-Bot>_** `10`
410
- >**_Peter>_** `puts "10 Random Users Created"`
411
- >**_Smart-Bot>_** `10 Random Users Created`
412
- >**_Peter>_** `quit`
413
- >**_Smart-Bot>_** `REPL session finished: Create10RandomUsers`
414
-
415
-
416
- >**_Peter>_** `run repl Create10RandomUsers`
417
- >**_Smart-Bot>_** `Running REPL Create10RandomUsers`
418
- >**_Smart-Bot>_** `Create10RandomUsers: 10 Random Users Created`
390
+ Running Example:
391
+ <img src="img/command_repl1.png" width="600">
392
+
393
+ <img src="img/command_repl2.png" width="600">
394
+
395
+
396
+ Runnning on demand the repl we created:
397
+
398
+ <img src="img/command_run_repl.png" width="400">
399
+
419
400
 
420
401
  You can run repls and supply parameters to the repl that will be executed on the same session just before the repl. [More info](https://github.com/MarioRuiz/slack-smart-bot/issues/60)
421
402
  Example:
@@ -444,13 +425,11 @@ If you have for example a rule like this: **_`run tests on customers android app
444
425
  From that moment you will be able to run the command: **_`run tca`_**
445
426
 
446
427
  That shortcut will be available for you, in case you want to make it available for everybody on the channel:
447
- Example:
448
- >**_Peter>_** `!add shortcut for all spanish bank account: ruby require 'iso/iban'; 3.times {puts ISO::IBAN.random('ES')}`
449
- >**_Smart-Bot>_** `shortcut added`
450
- >**_John>_** `!spanish bank account`
451
- >**_Smart-Bot>_** `ES4664553191352006861448`
452
- `ES4799209592433480943244`
453
- `ES8888795057132445752702`
428
+
429
+ Example:
430
+
431
+ <img src="img/command_add_sc.png" width="500">
432
+
454
433
 
455
434
  In case you want to use a shortcut as a inline shortcut inside a command you can do it by adding a $:
456
435
  Example:
@@ -479,7 +458,9 @@ Examples:
479
458
  >**_Peter>_** `add announcement Party will start at 20:00 :tada:`
480
459
  >**_Peter>_** `add :heavy_exclamation_mark: message Pay attention all DB are on maintenance until 20:00 GMT`
481
460
 
482
- To see the announcements of the channel: **_`see announcements`_**, **_`see COLOR announcements`_**, **_`see EMOJI announcements`_** and to delete a particular announcement: **_`delete announcement ID`_**
461
+ To see the announcements of the channel: **_`see announcements`_**, **_`see COLOR announcements`_**, **_`see EMOJI announcements`_** and to delete a particular announcement: **_`delete announcement ID`_**
462
+
463
+ <img src="img/command_see_announcements.png" width="500">
483
464
 
484
465
  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.
485
466
 
@@ -509,7 +490,9 @@ Examples:
509
490
  >**_Peter>_** `who is not on vacation?`
510
491
  >**_Peter>_** `who is on vacation? #SalesChannel`
511
492
  >**_Peter>_** `who is on :working-from-home:`
512
- >**_Peter>_** `who is available?`
493
+ >**_Peter>_** `who is available?`
494
+
495
+ <img src="img/command_see_statuses.png" width="400">
513
496
 
514
497
  ### Routines
515
498
  > for admins
@@ -544,7 +527,7 @@ Other routine commands:
544
527
  ### Loops
545
528
  > for all users
546
529
 
547
- You can run any command or rule on a loop by using:
530
+ You can run *any command* or rule on a loop by using:
548
531
  **_`for NUMBER times every NUMBER minutes COMMAND`_**
549
532
  **_`for NUMBER times every NUMBER seconds COMMAND`_**
550
533
  Maximum number of times to be used: 24. Minimum every 10 seconds. Maximum every 60 minutes.
@@ -557,6 +540,8 @@ Examples:
557
540
  >**_`quit loop 1`_**
558
541
  >**_`stop iterator 12`_**
559
542
 
543
+ <img src="img/command_loop.png" width="400">
544
+
560
545
  ### Control who has access to a command
561
546
  > for admins
562
547
 
@@ -674,6 +659,8 @@ In case of 'github' type then you can supply an URL filtering the Github issues
674
659
 
675
660
  If you want to change the memo status use the command `set STATUS on memo ID TEAM_NAME team`. For example: `set :runner: on memo 7 Sales team`
676
661
 
662
+ You can add also comments to any memo by calling: `team TEAM_NAME memo ID MESSAGE`. To see a specific memo and all the comments: `team TEAM_NAME memo ID`. In case of a Jira or GitHub memo then it will show also the comments in there.
663
+
677
664
  Examples:
678
665
  >**_`add memo to sales team : Add tests for Michigan feature`_**
679
666
  >**_`add private note to sales team : Bills will need to be deployed before Friday`_**
@@ -686,9 +673,15 @@ Examples:
686
673
  >**_`set :runner: on memo 7 team Sales`_**
687
674
  >**_`see all memos from Sales team`_**
688
675
  >**_`see bugs from Sales team dev`_**
676
+ >**_`sales team memo 4 Put it on hold until tests for Apple feature are finished`_**
677
+ >**_`sales team memo 7`_**
678
+
679
+ <img src="img/command_see_team.png" width="600">
680
+
689
681
 
690
682
  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`_**
691
683
 
684
+
692
685
  ### Time off management
693
686
  > for all users
694
687
 
@@ -718,11 +711,91 @@ settings = {
718
711
  }
719
712
  ```
720
713
 
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">
714
+ When calling `see my time off` on a DM will display a calendar of the year with the days off, including public holidays
715
+
716
+ <img src="img/command_my_timeoff.png" width="650">
723
717
 
724
718
  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`_**
725
719
 
720
+
721
+ ### OpenAI
722
+ > for all users
723
+ #### OpenAI setup
724
+ To be able to use this SmartBot general command you need to ask for an API token: https://platform.openai.com/account/api-keys
725
+
726
+ Then specify in the SmartBot config the keys:
727
+
728
+ ```ruby
729
+ ai: {
730
+ open_ai: {
731
+ access_token: 'OPENAI_ACCESS_TOKEN',
732
+ organization_id: 'OPENAI_ORGANIZATION_ID',
733
+ gpt_model: 'gpt-3.5-turbo',
734
+ whisper_model : 'whisper-1',
735
+ image_size: '256x256'
736
+ }
737
+ }
738
+ ```
739
+
740
+ Or if you want you can set your personal access token just to be used by you by calling on a DM with the SmartBot the command: `set personal settings ai.open_ai.access_token ACCESS_TOKEN`
741
+ Also you can specify personal settings for `gpt_model`, `whisper_model` or `image_size`, instead of using the default values.
742
+
743
+ #### ChatGPT
744
+
745
+ `??`
746
+ `?? PROMPT`
747
+ `? PROMPT`
748
+ Chat GPT will generate a response based on the PROMPT indicated.
749
+ If ?? is used, it will start from zero the session. If not all the previous prompts from the session will be used to generate the response.
750
+ You can share a message and use it as input for the supplied prompt.
751
+
752
+ <img src="img/chat_gpt.png" width="650">
753
+
754
+ <img src="img/chat_gpt_share.png" width="300">
755
+
756
+ #### Image Generation
757
+ `??i PROMPT`
758
+ `?i PROMPT`
759
+ `?ir`
760
+ It will generate an image based on the PROMPT indicated.
761
+ If `??i` is used, it will start from zero the session. If not all the previous prompts from the session will be used to generate the image.
762
+ if using `?ir` will generate a new image using the session prompts.
763
+
764
+ <img src="img/image_generation.png" width="400">
765
+
766
+ #### Image Variations
767
+
768
+ `?iv`
769
+ `?ivNUMBER`
770
+ It will generate a variation of the last image generated in the session.
771
+ In the case of NUMBER, it will generate NUMBER of variations of the last image generated. NUMBER needs to be between 1 and 9.
772
+ If an image is attached then it will generate temporary variations of the attached image.
773
+
774
+ <img src="img/image_variations.png" width="400">
775
+
776
+ #### Image Editing
777
+
778
+ `?ie PROMPT`
779
+ It will edit the attached image with the supplied PROMPT. The supplied image needs to be an image with a transparent area.
780
+ The PROMPT need to explain the final result of the image.
781
+
782
+ <img src="img/image_editing.png" width="400">
783
+
784
+ #### Whisper
785
+
786
+ `?w PROMPT`
787
+ `?w`
788
+ It will transcribe the audio file attached and perform the PROMPT indicated if supplied.
789
+
790
+ <img src="img/whisper.png" width="650">
791
+
792
+ #### Models
793
+
794
+ `?m`
795
+ `?m MODEL`
796
+ It will return the list of models available or the details of the model indicated.
797
+
798
+
726
799
  ### Tips
727
800
  > for admins
728
801
 
@@ -0,0 +1,61 @@
1
+ class SlackSmartBot
2
+ module AI
3
+ module OpenAI
4
+ def self.connect(ai_open_ai, general_config, personal_settings, reconnect: false)
5
+ require "openai"
6
+ user = Thread.current[:user]
7
+ ai_open_ai = {} if ai_open_ai.nil?
8
+
9
+ # ._ai to avoid to call .ai method from amazing_print
10
+ ai_open_ai[user.name] ||= { client: nil, gpt_model: general_config._ai.open_ai.gpt_model, whisper_model: general_config._ai.open_ai.whisper_model, image_size: general_config._ai.open_ai.image_size }
11
+ if personal_settings.key?(user.name) and personal_settings[user.name].key?("ai.open_ai.gpt_model") and
12
+ personal_settings[user.name]["ai.open_ai.gpt_model"] != ""
13
+ ai_open_ai[user.name][:gpt_model] = personal_settings[user.name]["ai.open_ai.gpt_model"]
14
+ elsif general_config.key?(:ai) and general_config[:ai].key?(:open_ai) and general_config[:ai][:open_ai].key?(:gpt_model) and
15
+ general_config[:ai][:open_ai][:gpt_model] != ""
16
+ ai_open_ai[user.name][:gpt_model] = general_config[:ai][:open_ai][:gpt_model]
17
+ end
18
+ if personal_settings.key?(user.name) and personal_settings[user.name].key?("ai.open_ai.whisper_model") and
19
+ personal_settings[user.name]["ai.open_ai.whisper_model"] != ""
20
+ ai_open_ai[user.name][:whisper_model] = personal_settings[user.name]["ai.open_ai.whisper_model"]
21
+ elsif general_config.key?(:ai) and general_config[:ai].key?(:open_ai) and general_config[:ai][:open_ai].key?(:whisper_model) and
22
+ general_config[:ai][:open_ai][:whisper_model] != ""
23
+ ai_open_ai[user.name][:whisper_model] = general_config[:ai][:open_ai][:whisper_model]
24
+ end
25
+ if personal_settings.key?(user.name) and personal_settings[user.name].key?("ai.open_ai.image_size") and
26
+ personal_settings[user.name]["ai.open_ai.image_size"] != ""
27
+ ai_open_ai[user.name][:image_size] = personal_settings[user.name]["ai.open_ai.image_size"]
28
+ elsif general_config.key?(:ai) and general_config[:ai].key?(:open_ai) and general_config[:ai][:open_ai].key?(:image_size) and
29
+ general_config[:ai][:open_ai][:image_size] != ""
30
+ ai_open_ai[user.name][:image_size] = general_config[:ai][:open_ai][:image_size]
31
+ end
32
+ if ai_open_ai.key?(user.name) and ai_open_ai[user.name] != nil and ai_open_ai[user.name].key?(:client) and
33
+ ai_open_ai[user.name][:client] != nil and !reconnect
34
+ # do nothing
35
+ elsif personal_settings.key?(user.name) and personal_settings[user.name].key?("ai.open_ai.access_token") and
36
+ personal_settings[user.name]["ai.open_ai.access_token"].to_s != ""
37
+ ai_open_ai[user.name].client = ::OpenAI::Client.new(access_token: personal_settings[user.name]["ai.open_ai.access_token"].to_s)
38
+ elsif general_config.key?(:ai) and general_config[:ai].key?(:open_ai) and general_config[:ai][:open_ai].key?(:access_token) and
39
+ general_config[:ai][:open_ai][:access_token] != ""
40
+ ai_open_ai[user.name].client = ::OpenAI::Client.new(access_token: general_config[:ai][:open_ai][:access_token])
41
+ else
42
+ ai_open_ai[user.name] = nil
43
+ message = ["You need to set the OpenAI access token in the config file or in the personal settings."]
44
+ message << "You can get it from https://platform.openai.com/account/api-keys"
45
+ message << "Then in case you are a master admin, you can set it in the SmartBot config file:"
46
+ message << " `ai: { open_ai: { access_token: 'ACCESS_TOKEN'} }`"
47
+ message << "If you want to use your personal access token, you can set it on a DM with SmartBot in the personal settings:"
48
+ message << " `set personal settings ai.open_ai.access_token ACCESS_TOKEN`"
49
+ message << "By default we will be using the gpt_model #{general_config._ai.open_ai.gpt_model}. You can change it in the config file or in personal settings:"
50
+ message << " `set personal settings ai.open_ai.gpt_model gpt-4`"
51
+ message << "By default we will be using the whisper_model #{general_config._ai.open_ai.whisper_model}. You can change it in the config file or in personal settings:"
52
+ message << " `set personal settings ai.open_ai.whisper_model whisper-1`"
53
+ message << "You can also change the image size in the config file or in personal settings:"
54
+ message << " `set personal settings ai.open_ai.image_size 512x512`"
55
+ return ai_open_ai, message.join("\n")
56
+ end
57
+ return ai_open_ai, ''
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,21 @@
1
+ class SlackSmartBot
2
+ module AI
3
+ module OpenAI
4
+ def self.models(open_ai_client, model='')
5
+ require "openai"
6
+ user = Thread.current[:user]
7
+ if model.empty?
8
+ response = open_ai_client.models.list
9
+ result = response.body.json().data.id.sort.join("\n")
10
+ else
11
+ response = open_ai_client.models.retrieve(id: model)
12
+ result = response.body
13
+ end
14
+ if !response.body.json(:message).empty? and response.body.json(:content).empty?
15
+ result = response.body.json(:message)
16
+ end
17
+ return result
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ class SlackSmartBot
2
+ module AI
3
+ module OpenAI
4
+ def self.send_gpt_chat(open_ai_client, model, message)
5
+ require "openai"
6
+ user = Thread.current[:user]
7
+ response = open_ai_client.chat(
8
+ parameters: {
9
+ model: model, # Required.
10
+ messages: [{ role: "user", content: message }], # Required.
11
+ temperature: 0.7,
12
+ },
13
+ )
14
+ if !response.body.json(:message).empty? and response.body.json(:content).empty?
15
+ result = response.body.json(:message)
16
+ return false, result
17
+ else
18
+ result = response.body.json(:content)
19
+ return true, result
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ class SlackSmartBot
2
+ module AI
3
+ module OpenAI
4
+ def self.send_image_edit(open_api_client, image, message, size: "")
5
+ #todo: add size personal settings
6
+ require "openai"
7
+ user = Thread.current[:user]
8
+
9
+ if size == ""
10
+ response = open_ai_client.images.edit(parameters: { image: image, prompt: message })
11
+ else
12
+ response = open_api_client.images.edit(parameters: { image: image, prompt: message, size: size })
13
+ end
14
+ if !response.body.json(:message).empty?
15
+ return false, "*OpenAI*: #{response.body.json(:message)}"
16
+ else
17
+ urls = [response.body.json(:url)].flatten
18
+ return true, urls
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ class SlackSmartBot
2
+ module AI
3
+ module OpenAI
4
+ def self.send_image_generation(open_ai_client, message, image_size)
5
+ require "openai"
6
+ user = Thread.current[:user]
7
+ #todo: personal settings size #Jal
8
+ response = open_ai_client.images.generate(parameters: { prompt: message, size: image_size })
9
+ if !response.body.json(:message).empty?
10
+ return false, "*OpenAI*: #{response.body.json(:message)}"
11
+ else
12
+ urls = [response.body.json(:url)].flatten
13
+ return true, urls
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ class SlackSmartBot
2
+ module AI
3
+ module OpenAI
4
+ def self.send_image_variation(open_ai_client, image, variations, size: "")
5
+ #todo: add size personal settings
6
+ require "openai"
7
+ user = Thread.current[:user]
8
+ if size == ""
9
+ response = open_ai_client.images.variations(parameters: { image: image, n: variations })
10
+ else
11
+ response = open_ai_client.images.variations(parameters: { image: image, n: variations, size: size })
12
+ end
13
+ if !response.body.json(:message).empty?
14
+ return false, "*OpenAI*: #{response.body.json(:message)}"
15
+ else
16
+ urls = [response.body.json(:url)].flatten
17
+ return true, urls
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ class SlackSmartBot
2
+ module AI
3
+ module OpenAI
4
+ def self.whisper_transcribe(open_ai_client, model, file)
5
+ require "openai"
6
+ user = Thread.current[:user]
7
+ response = open_ai_client.transcribe(
8
+ parameters: {
9
+ model: model, # Required.
10
+ file: File.open(file, "rb"),
11
+ },
12
+ )
13
+ if !response.body.json(:message).empty?
14
+ return false, response.body.json(:message)
15
+ else
16
+ return true, response.body.json(:text)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,8 @@
1
+ require_relative 'ai/open_ai/connect'
2
+ require_relative 'ai/open_ai/send_gpt_chat'
3
+ require_relative 'ai/open_ai/send_image_edit'
4
+ require_relative 'ai/open_ai/send_image_variation'
5
+ require_relative 'ai/open_ai/send_image_generation'
6
+ require_relative 'ai/open_ai/models'
7
+ require_relative 'ai/open_ai/whisper_transcribe'
8
+
@@ -1,17 +1,19 @@
1
- #todo: add pagination for case more than 1000 members in the channel
2
- def get_channel_members(channel_id)
3
- begin
4
- if channel_id.nil?
5
- return nil
6
- else
7
- if config.simulate and config.key?(:client)
8
- client.web_client.conversations_members[channel_id.to_sym].members
1
+ class SlackSmartBot
2
+ #todo: add pagination for case more than 1000 members in the channel
3
+ def get_channel_members(channel_id)
4
+ begin
5
+ if channel_id.nil?
6
+ return nil
9
7
  else
10
- client.web_client.conversations_members(channel: channel_id, limit: 1000).members
8
+ if config.simulate and config.key?(:client)
9
+ client.web_client.conversations_members[channel_id.to_sym].members
10
+ else
11
+ client.web_client.conversations_members(channel: channel_id, limit: 1000).members
12
+ end
11
13
  end
14
+ rescue Exception => stack
15
+ @logger.warn stack
12
16
  end
13
- rescue Exception => stack
14
- @logger.warn stack
15
- end
16
17
 
17
- end
18
+ end
19
+ end
@@ -1,35 +1,37 @@
1
- def get_channels(bot_is_in: false, types: 'private_channel,public_channel')
2
- begin
3
- if config.simulate and config.key?(:client)
4
- if bot_is_in
5
- client.web_client.conversations_members.reject { |r, v| !v.members.include?(config.nick_id) }.values
6
- else
7
- client.web_client.conversations_members.values
8
- end
9
- else
10
- if bot_is_in
11
- client.web_client.users_conversations(exclude_archived: true, limit: 1000, types: "im, public_channel,private_channel").channels
1
+ class SlackSmartBot
2
+ def get_channels(bot_is_in: false, types: 'private_channel,public_channel')
3
+ begin
4
+ if config.simulate and config.key?(:client)
5
+ if bot_is_in
6
+ client.web_client.conversations_members.reject { |r, v| !v.members.include?(config.nick_id) }.values
7
+ else
8
+ client.web_client.conversations_members.values
9
+ end
12
10
  else
13
- resp = client.web_client.conversations_list(types: types, limit: "600", exclude_archived: "true")
14
- channels = resp.channels
15
- begin
16
- while resp.response_metadata.next_cursor.to_s != ""
17
- resp = client.web_client.conversations_list(
18
- cursor: resp.response_metadata.next_cursor.to_s,
19
- types: types,
20
- limit: "600",
21
- exclude_archived: "true",
22
- )
23
- channels += resp.channels
11
+ if bot_is_in
12
+ client.web_client.users_conversations(exclude_archived: true, limit: 1000, types: "im, public_channel,private_channel").channels
13
+ else
14
+ resp = client.web_client.conversations_list(types: types, limit: "600", exclude_archived: "true")
15
+ channels = resp.channels
16
+ begin
17
+ while resp.response_metadata.next_cursor.to_s != ""
18
+ resp = client.web_client.conversations_list(
19
+ cursor: resp.response_metadata.next_cursor.to_s,
20
+ types: types,
21
+ limit: "600",
22
+ exclude_archived: "true",
23
+ )
24
+ channels += resp.channels
25
+ end
26
+ rescue Exception => stack
27
+ @logger.warn stack
24
28
  end
25
- rescue Exception => stack
26
- @logger.warn stack
29
+ return channels
27
30
  end
28
- return channels
29
31
  end
32
+ rescue Exception => stack
33
+ @logger.warn stack
34
+ return []
30
35
  end
31
- rescue Exception => stack
32
- @logger.warn stack
33
- return []
34
36
  end
35
- end
37
+ end