slack-smart-bot 1.13.2 → 1.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +100 -4
  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/general/bot_stats.rb +379 -353
  39. data/lib/slack/smart-bot/commands/on_bot/repl.rb +6 -107
  40. data/lib/slack/smart-bot/commands/on_bot/repl_client.rb +233 -0
  41. data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +17 -4
  42. data/lib/slack/smart-bot/commands.rb +26 -10
  43. data/lib/slack/smart-bot/process.rb +14 -3
  44. data/lib/slack/smart-bot/process_first.rb +36 -2
  45. data/lib/slack/smart-bot/treat_message.rb +28 -0
  46. data/lib/slack/smart-bot/utils/check_vacations.rb +1 -0
  47. data/lib/slack/smart-bot/utils/create_routine_thread.rb +1 -1
  48. data/lib/slack/smart-bot/utils/display_calendar.rb +17 -10
  49. data/lib/slack/smart-bot/utils/encryption/decrypt.rb +23 -0
  50. data/lib/slack/smart-bot/utils/encryption/encrypt.rb +27 -0
  51. data/lib/slack/smart-bot/utils/{encryption_get_key_iv.rb → encryption/encryption_get_key_iv.rb} +12 -8
  52. data/lib/slack/smart-bot/utils/get_help.rb +3 -1
  53. data/lib/slack/smart-bot/utils/get_personal_settings.rb +14 -0
  54. data/lib/slack/smart-bot/utils/get_teams.rb +2 -2
  55. data/lib/slack/smart-bot/utils/get_vacations.rb +2 -2
  56. data/lib/slack/smart-bot/utils/save_stats.rb +3 -1
  57. data/lib/slack/smart-bot/utils/update_personal_settings.rb +18 -0
  58. data/lib/slack/smart-bot/utils/update_teams.rb +1 -1
  59. data/lib/slack/smart-bot/utils/update_vacations.rb +1 -1
  60. data/lib/slack/smart-bot/utils.rb +5 -3
  61. data/lib/slack-smart-bot.rb +12 -0
  62. data/whats_new.txt +13 -14
  63. metadata +63 -15
  64. data/lib/slack/smart-bot/commands/general/add_memo_team.rb +0 -117
  65. data/lib/slack/smart-bot/commands/general/add_team.rb +0 -81
  66. data/lib/slack/smart-bot/commands/general/delete_memo_team.rb +0 -69
  67. data/lib/slack/smart-bot/commands/general/delete_team.rb +0 -55
  68. data/lib/slack/smart-bot/commands/general/ping_team.rb +0 -100
  69. data/lib/slack/smart-bot/commands/general/see_memos_team.rb +0 -202
  70. data/lib/slack/smart-bot/commands/general/see_teams.rb +0 -230
  71. data/lib/slack/smart-bot/commands/general/see_vacations_team.rb +0 -136
  72. data/lib/slack/smart-bot/commands/general/set_memo_status.rb +0 -58
  73. data/lib/slack/smart-bot/commands/general/update_team.rb +0 -131
  74. data/lib/slack/smart-bot/utils/decrypt.rb +0 -15
  75. 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: fef5b10f464c14059a0c350c44e0bbb86c7c92db0f60a05516982c79e4764159
4
+ data.tar.gz: 5fa566a1f3198e1021a5a1f3ae6759e0814eeafa394e7acad2117bf0661d2cfe
5
5
  SHA512:
6
- metadata.gz: 261ac1f20a7bdec84c5e5b24278584656def3ab09dc0bf2f4fc17080a812952a18474bff74f845fcc83e8783b121e00be555086ea7159bd362b955236c4b1dc6
7
- data.tar.gz: ea5fe6b71b79f696727a1a54585e6a2b450c381fa7daadc6e351e9513e3a0b878c7869683b2df4db35997071af06d17a1d55d03f465421aa701e9bd727adef88
6
+ metadata.gz: 2a73bdd8c22589f205997f00723e15b791805430b4c614f33ea0abe32dee48fc5c6e9f8b7bd0709eb35376e133e40389c12e5efc7e0f5b8f871553cfe9f0b4f3
7
+ data.tar.gz: a98455b32e704fb57a84c6df1df523f0967a8499bf1c61bbda079f951b9f4b854e65f02395f2b85743e93ef05eb9ac505a57f452af9b0399ea362982392ac9ab
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)
@@ -382,9 +394,9 @@ By default it will be automatically loaded the gems: `string_pattern`, `nice_has
382
394
 
383
395
  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
396
 
385
- If you want to see the methods of a class or module you created use `ls TheModuleOrClass`
397
+ 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
398
 
387
- You can supply the Environmental Variables you need for the Session
399
+ You can supply the Environmental Variables you need for the Session
388
400
 
389
401
  Examples:
390
402
  _repl CreateCustomer LOCATION=spain HOST='https://10.30.40.50:8887'_
@@ -674,6 +686,8 @@ In case of 'github' type then you can supply an URL filtering the Github issues
674
686
 
675
687
  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
688
 
689
+ 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.
690
+
677
691
  Examples:
678
692
  >**_`add memo to sales team : Add tests for Michigan feature`_**
679
693
  >**_`add private note to sales team : Bills will need to be deployed before Friday`_**
@@ -686,6 +700,8 @@ Examples:
686
700
  >**_`set :runner: on memo 7 team Sales`_**
687
701
  >**_`see all memos from Sales team`_**
688
702
  >**_`see bugs from Sales team dev`_**
703
+ >**_`sales team memo 4 Put it on hold until tests for Apple feature are finished`_**
704
+ >**_`sales team memo 7`_**
689
705
 
690
706
  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
707
 
@@ -718,11 +734,91 @@ settings = {
718
734
  }
719
735
  ```
720
736
 
721
- When calling `see my time off` on a DM will display a calendar of the year with the days off, including public holidays
737
+ When calling `see my time off` on a DM will display a calendar of the year with the days off, including public holidays
738
+
722
739
  <img src="img/my_timeoff.png" width="650">
723
740
 
724
741
  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
742
 
743
+
744
+ ### OpenAI
745
+ > for all users
746
+ #### OpenAI setup
747
+ To be able to use this SmartBot general command you need to ask for an API token: https://platform.openai.com/account/api-keys
748
+
749
+ Then specify in the SmartBot config the keys:
750
+
751
+ ```ruby
752
+ ai: {
753
+ open_ai: {
754
+ access_token: 'OPENAI_ACCESS_TOKEN',
755
+ organization_id: 'OPENAI_ORGANIZATION_ID',
756
+ gpt_model: 'gpt-3.5-turbo',
757
+ whisper_model : 'whisper-1',
758
+ image_size: '256x256'
759
+ }
760
+ }
761
+ ```
762
+
763
+ 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`
764
+ Also you can specify personal settings for `gpt_model`, `whisper_model` or `image_size`, instead of using the default values.
765
+
766
+ #### ChatGPT
767
+
768
+ `??`
769
+ `?? PROMPT`
770
+ `? PROMPT`
771
+ Chat GPT will generate a response based on the PROMPT indicated.
772
+ 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.
773
+ You can share a message and use it as input for the supplied prompt.
774
+
775
+ <img src="img/chat_gpt.png" width="650">
776
+
777
+ <img src="img/chat_gpt_share.png" width="300">
778
+
779
+ #### Image Generation
780
+ `??i PROMPT`
781
+ `?i PROMPT`
782
+ `?ir`
783
+ It will generate an image based on the PROMPT indicated.
784
+ 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.
785
+ if using `?ir` will generate a new image using the session prompts.
786
+
787
+ <img src="img/image_generation.png" width="400">
788
+
789
+ #### Image Variations
790
+
791
+ `?iv`
792
+ `?ivNUMBER`
793
+ It will generate a variation of the last image generated in the session.
794
+ In the case of NUMBER, it will generate NUMBER of variations of the last image generated. NUMBER needs to be between 1 and 9.
795
+ If an image is attached then it will generate temporary variations of the attached image.
796
+
797
+ <img src="img/image_variations.png" width="400">
798
+
799
+ #### Image Editing
800
+
801
+ `?ie PROMPT`
802
+ It will edit the attached image with the supplied PROMPT. The supplied image needs to be an image with a transparent area.
803
+ The PROMPT need to explain the final result of the image.
804
+
805
+ <img src="img/image_editing.png" width="400">
806
+
807
+ #### Whisper
808
+
809
+ `?w PROMPT`
810
+ `?w`
811
+ It will transcribe the audio file attached and perform the PROMPT indicated if supplied.
812
+
813
+ <img src="img/whisper.png" width="650">
814
+
815
+ #### Models
816
+
817
+ `?m`
818
+ `?m MODEL`
819
+ It will return the list of models available or the details of the model indicated.
820
+
821
+
726
822
  ### Tips
727
823
  > for admins
728
824
 
@@ -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
@@ -1,5 +1,5 @@
1
1
  class SlackSmartBot
2
- def respond_thread(msg, unfurl_links: true, unfurl_media: true)
3
- respond(msg, :on_thread, unfurl_links: unfurl_links, unfurl_media: unfurl_media)
2
+ def respond_thread(msg='', unfurl_links: true, unfurl_media: true, blocks: [])
3
+ respond(msg, :on_thread, unfurl_links: unfurl_links, unfurl_media: unfurl_media, blocks: blocks)
4
4
  end
5
5
  end
@@ -0,0 +1,40 @@
1
+ class SlackSmartBot
2
+ module Commands
3
+ module General
4
+ module AI
5
+ module OpenAI
6
+ def open_ai_chat(message, delete_history)
7
+ save_stats(__method__)
8
+ get_personal_settings()
9
+ @ai_open_ai, message_connect = SlackSmartBot::AI::OpenAI.connect(@ai_open_ai, config, @personal_settings, reconnect: delete_history)
10
+ respond message_connect if message_connect
11
+ user = Thread.current[:user]
12
+ if !@ai_open_ai[user.name].nil? and !@ai_open_ai[user.name][:client].nil?
13
+ @ai_gpt ||= {}
14
+ @ai_gpt[user.name] ||= []
15
+
16
+ if message == "" # ?? is called
17
+ @ai_gpt[user.name] = []
18
+ respond "*GPT*: Let's start a new conversation. Ask me anything."
19
+ else
20
+ react :speech_balloon
21
+ begin
22
+ @ai_gpt[user.name] = [] if delete_history
23
+ @ai_gpt[user.name] << message
24
+ success, res = SlackSmartBot::AI::OpenAI.send_gpt_chat(@ai_open_ai[user.name][:client], @ai_open_ai[user.name].gpt_model, @ai_gpt[user.name].join("\n"))
25
+ if success
26
+ @ai_gpt[user.name] << res
27
+ end
28
+ respond "*GPT* Session: _<#{@ai_gpt[user.name].first[0..29]}...>_ (id:#{@ai_gpt[user.name].object_id}) \n#{res.strip}"
29
+ rescue => exception
30
+ respond "*GPT*: Sorry, I'm having some problems. OpenAI probably is not available. Please try again later."
31
+ end
32
+ unreact :speech_balloon
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,66 @@
1
+ class SlackSmartBot
2
+ module Commands
3
+ module General
4
+ module AI
5
+ module OpenAI
6
+ def open_ai_edit_image(message, files)
7
+ save_stats(__method__)
8
+ get_personal_settings()
9
+ @ai_open_ai, message_connect = SlackSmartBot::AI::OpenAI.connect(@ai_open_ai, config, @personal_settings)
10
+ respond message_connect if message_connect
11
+ user = Thread.current[:user]
12
+ if !@ai_open_ai[user.name].nil? and !@ai_open_ai[user.name][:client].nil?
13
+ @ai_open_ai_image ||= {}
14
+ @ai_open_ai_image[user.name] ||= []
15
+ react :art
16
+ begin
17
+ @ai_open_ai_image[user.name] = [] if !files.nil? and files.size == 1
18
+ if files.nil? or files.size != 1
19
+ respond "*OpenAI*: Sorry, I need an image to edit. Please upload an image and try again."
20
+ else
21
+ require "nice_http"
22
+ image = "#{config.path}/tmp/#{user.name}_#{@ai_open_ai_image[user.name].object_id}.png"
23
+ http = NiceHttp.new(host: "https://files.slack.com", headers: { "Authorization" => "Bearer #{config.token}" })
24
+ res = http.get(files[0].url_private_download, save_data: image)
25
+ success, res = SlackSmartBot::AI::OpenAI.send_image_edit(@ai_open_ai[user.name].client, image, message, size: @ai_open_ai[user.name][:image_size])
26
+
27
+ if success
28
+ urls = res
29
+ urls = [urls] if urls.is_a?(String)
30
+ if urls.nil? or urls.empty?
31
+ respond "*OpenAI*: Sorry, I'm having some problems. OpenAI was not able to generate an image."
32
+ else
33
+ if @ai_open_ai_image[user.name].empty?
34
+ session_name = "Edit"
35
+ else
36
+ session_name = @ai_open_ai_image[user.name].first[0..29]
37
+ end
38
+ messagersp = "OpenAI Session: _<#{session_name}...>_ (id:#{@ai_open_ai_image[user.name].object_id})"
39
+ message = "Edit"
40
+ require "uri"
41
+ urls.each do |url|
42
+ uri = URI.parse(url)
43
+ require "nice_http"
44
+ http = NiceHttp.new(host: "https://#{uri.host}")
45
+ file_path_name = "#{config.path}/tmp/#{user.name}_#{@ai_open_ai_image[user.name].object_id}.png"
46
+ res = http.get(uri.path + "?#{uri.query}", save_data: file_path_name)
47
+ send_file(Thread.current[:dest], messagersp, file_path_name, message, "image/png", "png")
48
+ http.close unless http.nil?
49
+ end
50
+ end
51
+ else
52
+ respond res
53
+ end
54
+ end
55
+ rescue => exception
56
+ respond "*OpenAI*: Sorry, I'm having some problems. OpenAI probably is not available. Please try again later."
57
+ @logger.warn exception
58
+ end
59
+ unreact :art
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end