slack-smart-bot 1.14.2 → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (176) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +222 -37
  3. data/img/chat_gpt.png +0 -0
  4. data/img/chat_gpt_session.png +0 -0
  5. data/img/chat_gpt_share.png +0 -0
  6. data/img/command_add_sc.png +0 -0
  7. data/img/command_bot_help_echo.png +0 -0
  8. data/img/command_loop.png +0 -0
  9. data/img/command_my_timeoff.png +0 -0
  10. data/img/command_recap.png +0 -0
  11. data/img/command_repl1.png +0 -0
  12. data/img/command_repl2.png +0 -0
  13. data/img/command_ruby.png +0 -0
  14. data/img/command_run_repl.png +0 -0
  15. data/img/command_see_announcements.png +0 -0
  16. data/img/command_see_statuses.png +0 -0
  17. data/img/command_see_team.png +0 -0
  18. data/img/command_summarize.png +0 -0
  19. data/img/commands_inline.png +0 -0
  20. data/img/commands_on_demand.png +0 -0
  21. data/img/commands_on_external_call.png +0 -0
  22. data/img/image_editing.png +0 -0
  23. data/img/image_generation.png +0 -0
  24. data/img/image_variations.png +0 -0
  25. data/img/openai-300.png +0 -0
  26. data/img/openai.png +0 -0
  27. data/img/slack-300.png +0 -0
  28. data/img/slack.png +0 -0
  29. data/img/smart-bot-150.png +0 -0
  30. data/img/smart-bot-profile-pic-2.png +0 -0
  31. data/img/smart-bot-profile-pic.png +0 -0
  32. data/img/smart-bot.png +0 -0
  33. data/img/whisper.png +0 -0
  34. data/lib/slack/smart-bot/ai/open_ai/connect.rb +165 -43
  35. data/lib/slack/smart-bot/ai/open_ai/models.rb +61 -9
  36. data/lib/slack/smart-bot/ai/open_ai/send_gpt_chat.rb +67 -11
  37. data/lib/slack/smart-bot/ai/open_ai/send_image_edit.rb +4 -3
  38. data/lib/slack/smart-bot/ai/open_ai/send_image_generation.rb +4 -4
  39. data/lib/slack/smart-bot/ai/open_ai/send_image_variation.rb +4 -3
  40. data/lib/slack/smart-bot/ai/open_ai/whisper_transcribe.rb +4 -3
  41. data/lib/slack/smart-bot/comm/ask.rb +20 -8
  42. data/lib/slack/smart-bot/comm/dont_understand.rb +2 -2
  43. data/lib/slack/smart-bot/comm/event_hello.rb +30 -1
  44. data/lib/slack/smart-bot/comm/get_channel_members.rb +2 -1
  45. data/lib/slack/smart-bot/comm/get_presence.rb +1 -0
  46. data/lib/slack/smart-bot/comm/get_smartbot_team_info.rb +10 -0
  47. data/lib/slack/smart-bot/comm/get_user_info.rb +45 -6
  48. data/lib/slack/smart-bot/comm/get_users.rb +8 -1
  49. data/lib/slack/smart-bot/comm/respond.rb +225 -196
  50. data/lib/slack/smart-bot/comm/send_msg_channel.rb +2 -2
  51. data/lib/slack/smart-bot/comm/send_msg_user.rb +10 -9
  52. data/lib/slack/smart-bot/comm/unreact.rb +2 -2
  53. data/lib/slack/smart-bot/comm.rb +1 -0
  54. data/lib/slack/smart-bot/commands/general/add_admin.rb +16 -6
  55. data/lib/slack/smart-bot/commands/general/add_announcement.rb +3 -3
  56. data/lib/slack/smart-bot/commands/general/add_vacation.rb +28 -12
  57. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat.rb +272 -23
  58. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_add_collaborator.rb +42 -0
  59. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_copy_session.rb +89 -0
  60. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_delete_session.rb +45 -0
  61. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_get_prompts.rb +41 -0
  62. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_list_sessions.rb +81 -0
  63. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_share_session.rb +52 -0
  64. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_use_model.rb +52 -0
  65. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_edit_image.rb +14 -11
  66. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_generate_image.rb +15 -11
  67. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_models.rb +29 -17
  68. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_variations_image.rb +16 -13
  69. data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_whisper.rb +13 -7
  70. data/lib/slack/smart-bot/commands/general/allow_access.rb +8 -4
  71. data/lib/slack/smart-bot/commands/general/bot_help.rb +24 -10
  72. data/lib/slack/smart-bot/commands/general/bye_bot.rb +9 -5
  73. data/lib/slack/smart-bot/commands/general/delete_announcement.rb +2 -1
  74. data/lib/slack/smart-bot/commands/general/delete_share.rb +2 -1
  75. data/lib/slack/smart-bot/commands/general/deny_access.rb +1 -1
  76. data/lib/slack/smart-bot/commands/general/get_smartbot_readme.rb +15 -0
  77. data/lib/slack/smart-bot/commands/general/hi_bot.rb +10 -4
  78. data/lib/slack/smart-bot/commands/general/personal_settings.rb +26 -8
  79. data/lib/slack/smart-bot/commands/general/poster.rb +26 -2
  80. data/lib/slack/smart-bot/commands/general/public_holidays.rb +14 -24
  81. data/lib/slack/smart-bot/commands/general/recap.rb +399 -0
  82. data/lib/slack/smart-bot/commands/general/remove_admin.rb +19 -9
  83. data/lib/slack/smart-bot/commands/general/remove_vacation.rb +23 -6
  84. data/lib/slack/smart-bot/commands/general/see_access.rb +2 -1
  85. data/lib/slack/smart-bot/commands/general/see_admins.rb +8 -4
  86. data/lib/slack/smart-bot/commands/general/see_announcements.rb +5 -5
  87. data/lib/slack/smart-bot/commands/general/see_favorite_commands.rb +4 -4
  88. data/lib/slack/smart-bot/commands/general/see_shares.rb +1 -1
  89. data/lib/slack/smart-bot/commands/general/see_vacations.rb +34 -17
  90. data/lib/slack/smart-bot/commands/general/set_public_holidays.rb +4 -2
  91. data/lib/slack/smart-bot/commands/general/share_messages.rb +3 -3
  92. data/lib/slack/smart-bot/commands/general/summarize.rb +191 -0
  93. data/lib/slack/smart-bot/commands/general/teams/add_team.rb +4 -8
  94. data/lib/slack/smart-bot/commands/general/teams/delete_team.rb +3 -3
  95. data/lib/slack/smart-bot/commands/general/teams/memos/add_memo_team.rb +34 -29
  96. data/lib/slack/smart-bot/commands/general/teams/memos/add_memo_team_comment.rb +1 -1
  97. data/lib/slack/smart-bot/commands/general/teams/memos/delete_memo_team.rb +6 -4
  98. data/lib/slack/smart-bot/commands/general/teams/memos/see_memo_team.rb +26 -15
  99. data/lib/slack/smart-bot/commands/general/teams/memos/see_memos_team.rb +33 -24
  100. data/lib/slack/smart-bot/commands/general/teams/memos/set_memo_status.rb +4 -4
  101. data/lib/slack/smart-bot/commands/general/teams/ping_team.rb +10 -8
  102. data/lib/slack/smart-bot/commands/general/teams/see_teams.rb +73 -61
  103. data/lib/slack/smart-bot/commands/general/teams/see_vacations_team.rb +28 -13
  104. data/lib/slack/smart-bot/commands/general/teams/update_team.rb +9 -9
  105. data/lib/slack/smart-bot/commands/general_bot_commands.rb +1152 -839
  106. data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +18 -17
  107. data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +11 -9
  108. data/lib/slack/smart-bot/commands/on_bot/admin/remove_routine.rb +2 -0
  109. data/lib/slack/smart-bot/commands/on_bot/admin/run_routine.rb +1 -0
  110. data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +5 -3
  111. data/lib/slack/smart-bot/commands/on_bot/admin_master/delete_message.rb +2 -3
  112. data/lib/slack/smart-bot/commands/on_bot/admin_master/get_bot_logs.rb +2 -3
  113. data/lib/slack/smart-bot/commands/on_bot/admin_master/react_to.rb +2 -3
  114. data/lib/slack/smart-bot/commands/on_bot/admin_master/send_message.rb +7 -6
  115. data/lib/slack/smart-bot/commands/on_bot/admin_master/update_message.rb +2 -3
  116. data/lib/slack/smart-bot/commands/on_bot/delete_repl.rb +1 -1
  117. data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +21 -20
  118. data/lib/slack/smart-bot/commands/on_bot/general/bot_stats.rb +40 -7
  119. data/lib/slack/smart-bot/commands/on_bot/general/bot_status.rb +6 -2
  120. data/lib/slack/smart-bot/commands/on_bot/general/stop_using_rules.rb +7 -6
  121. data/lib/slack/smart-bot/commands/on_bot/general/suggest_command.rb +5 -4
  122. data/lib/slack/smart-bot/commands/on_bot/general/use_rules.rb +4 -3
  123. data/lib/slack/smart-bot/commands/on_bot/get_repl.rb +4 -4
  124. data/lib/slack/smart-bot/commands/on_bot/kill_repl.rb +1 -1
  125. data/lib/slack/smart-bot/commands/on_bot/repl.rb +109 -53
  126. data/lib/slack/smart-bot/commands/on_bot/repl_client.rb +35 -29
  127. data/lib/slack/smart-bot/commands/on_bot/run_repl.rb +5 -5
  128. data/lib/slack/smart-bot/commands/on_bot/see_repls.rb +1 -2
  129. data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +5 -4
  130. data/lib/slack/smart-bot/commands/on_extended/bot_rules.rb +22 -12
  131. data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +12 -7
  132. data/lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb +2 -2
  133. data/lib/slack/smart-bot/commands/on_master/admin_master/publish_announcements.rb +1 -1
  134. data/lib/slack/smart-bot/commands/on_master/admin_master/set_general_message.rb +5 -5
  135. data/lib/slack/smart-bot/commands/on_master/admin_master/set_maintenance.rb +5 -5
  136. data/lib/slack/smart-bot/commands/on_master/create_bot.rb +3 -3
  137. data/lib/slack/smart-bot/commands.rb +10 -0
  138. data/lib/slack/smart-bot/config.rb +126 -0
  139. data/lib/slack/smart-bot/listen.rb +12 -11
  140. data/lib/slack/smart-bot/process.rb +62 -55
  141. data/lib/slack/smart-bot/process_first.rb +106 -65
  142. data/lib/slack/smart-bot/treat_message.rb +79 -47
  143. data/lib/slack/smart-bot/utils/answer.rb +11 -3
  144. data/lib/slack/smart-bot/utils/answer_delete.rb +11 -3
  145. data/lib/slack/smart-bot/utils/check_vacations.rb +21 -3
  146. data/lib/slack/smart-bot/utils/create_routine_thread.rb +13 -13
  147. data/lib/slack/smart-bot/utils/display_calendar.rb +42 -8
  148. data/lib/slack/smart-bot/utils/encryption/decrypt.rb +16 -9
  149. data/lib/slack/smart-bot/utils/encryption/encrypt.rb +14 -11
  150. data/lib/slack/smart-bot/utils/find_user.rb +71 -0
  151. data/lib/slack/smart-bot/utils/get_access_channels.rb +22 -3
  152. data/lib/slack/smart-bot/utils/get_channels_name_and_id.rb +3 -4
  153. data/lib/slack/smart-bot/utils/get_command_ids.rb +5 -5
  154. data/lib/slack/smart-bot/utils/get_countries_candelarific.rb +18 -0
  155. data/lib/slack/smart-bot/utils/get_help.rb +21 -19
  156. data/lib/slack/smart-bot/utils/get_openai_sessions.rb +47 -0
  157. data/lib/slack/smart-bot/utils/get_personal_settings.rb +29 -3
  158. data/lib/slack/smart-bot/utils/get_rules_imported.rb +27 -6
  159. data/lib/slack/smart-bot/utils/get_shares.rb +1 -1
  160. data/lib/slack/smart-bot/utils/get_team_members.rb +4 -4
  161. data/lib/slack/smart-bot/utils/get_vacations.rb +15 -7
  162. data/lib/slack/smart-bot/utils/has_access.rb +10 -4
  163. data/lib/slack/smart-bot/utils/is_admin.rb +25 -17
  164. data/lib/slack/smart-bot/utils/local_time.rb +29 -0
  165. data/lib/slack/smart-bot/utils/save_stats.rb +5 -3
  166. data/lib/slack/smart-bot/utils/update_access_channels.rb +19 -3
  167. data/lib/slack/smart-bot/utils/update_openai_sessions.rb +42 -0
  168. data/lib/slack/smart-bot/utils/update_personal_settings.rb +11 -3
  169. data/lib/slack/smart-bot/utils/update_rules_imported.rb +18 -3
  170. data/lib/slack/smart-bot/utils/update_vacations.rb +5 -2
  171. data/lib/slack/smart-bot/utils/upgrade_to_use_team_ids.rb +276 -0
  172. data/lib/slack/smart-bot/utils.rb +6 -1
  173. data/lib/slack-smart-bot.rb +182 -76
  174. data/lib/slack-smart-bot_general_commands.rb +10 -9
  175. data/whats_new.txt +30 -13
  176. metadata +148 -20
@@ -1,11 +1,30 @@
1
1
  class SlackSmartBot
2
2
 
3
3
  def get_access_channels()
4
- if File.exist?("#{config.path}/rules/#{@channel_id}/access_channels.rb")
5
- file_conf = IO.readlines("#{config.path}/rules/#{@channel_id}/access_channels.rb").join
6
- unless file_conf.to_s() == ""
4
+ require 'yaml'
5
+ access_ch_file = "#{config.path}/rules/#{@channel_id}/access_channels"
6
+ if File.exist?("#{access_ch_file}.rb") #backwards compatible
7
+ file_conf = IO.readlines("#{access_ch_file}.rb").join
8
+ if file_conf.to_s() == ""
9
+ @access_channels = {}
10
+ else
7
11
  @access_channels = eval(file_conf)
8
12
  end
13
+ File.open("#{access_ch_file}.yaml", 'w') {|file| file.write(@access_channels.to_yaml) }
14
+ File.delete("#{access_ch_file}.rb")
15
+ end
16
+
17
+ if File.exist?("#{access_ch_file}.yaml")
18
+ access_channels = @access_channels
19
+ 10.times do
20
+ access_channels = YAML.load(File.read("#{access_ch_file}.yaml"))
21
+ if access_channels.is_a?(Hash)
22
+ break
23
+ else
24
+ sleep (0.1*(rand(2)+1))
25
+ end
26
+ end
27
+ @access_channels = access_channels unless access_channels.is_a?(FalseClass)
9
28
  else
10
29
  @access_channels = {}
11
30
  end
@@ -5,14 +5,13 @@ class SlackSmartBot
5
5
  @channels_id = Hash.new()
6
6
  @channels_name = Hash.new()
7
7
  @channels_creator = Hash.new()
8
- @users = get_users() if @users.empty?
9
8
  @channels_list.each do |ch|
10
9
  unless ch.is_archived
11
10
  @channels_id[ch.name] = ch.id
12
11
  @channels_name[ch.id] = ch.name
13
- user_info = @users.select{|u| u.id == ch.creator or (u.key?(:enterprise_user) and u.enterprise_user.id == ch.creator)}[-1]
14
- @channels_creator[ch.id] = user_info.name unless user_info.nil?
15
- @channels_creator[ch.name] = user_info.name unless user_info.nil?
12
+ user_info = find_user(ch.creator)
13
+ @channels_creator[ch.id] = "#{user_info.team_id}_#{user_info.name}" unless user_info.nil?
14
+ @channels_creator[ch.name] = "#{user_info.team_id}_#{user_info.name}" unless user_info.nil?
16
15
  end
17
16
  end
18
17
  end
@@ -17,13 +17,13 @@ class SlackSmartBot
17
17
  typem = Thread.current[:typem]
18
18
  user = Thread.current[:user]
19
19
  # :on_call, :on_bot, :on_extended, :on_dm, :on_master, :on_pg, :on_pub
20
- admin = is_admin?(user.name)
20
+ admin = is_admin?(user)
21
21
 
22
22
  commands[:general] = (Dir.entries("#{__dir__}/../commands/general/").select { |e| e.match?(/\.rb/) }).sort.join('|').gsub('.rb','').split('|')
23
23
  general = File.read("#{__dir__}/../commands/general_bot_commands.rb")
24
24
  commands[:general] += general.scan(/^\s*#\s*help\w*:\s+command_id:\s+:(\w+)\s*$/i).flatten
25
25
  commands[:general].uniq!
26
-
26
+
27
27
  if typem == :on_bot or typem == :on_master
28
28
  commands[:on_bot_general] = (Dir.entries("#{__dir__}/../commands/on_bot/general/").select { |e| e.match?(/\.rb/) }).sort.join('|').gsub('.rb','').split('|')
29
29
  end
@@ -36,7 +36,7 @@ class SlackSmartBot
36
36
  commands[:on_bot_admin] = (Dir.entries("#{__dir__}/../commands/on_bot/admin/").select { |e| e.match?(/\.rb/) }).sort.join('|').gsub('.rb','').split('|')
37
37
  end
38
38
 
39
- if (typem == :on_bot or typem == :on_master) and config.masters.include?(user.name)
39
+ if (typem == :on_bot or typem == :on_master) and config.team_id_masters.include?("#{user.team_id}_#{user.name}")
40
40
  commands[:on_bot_master_admin] = (Dir.entries("#{__dir__}/../commands/on_bot/admin_master/").select { |e| e.match?(/\.rb/) }).sort.join('|').gsub('.rb','').split('|')
41
41
  end
42
42
 
@@ -53,7 +53,7 @@ class SlackSmartBot
53
53
  commands[:on_master_admin] = (Dir.entries("#{__dir__}/../commands/on_master/admin/").select { |e| e.match?(/\.rb/) }).sort.join('|').gsub('.rb','').split('|')
54
54
  end
55
55
 
56
- if typem == :on_master and config.masters.include?(user.name)
56
+ if typem == :on_master and config.team_id_masters.include?("#{user.team_id}_#{user.name}")
57
57
  commands[:on_master_master_admin] = (Dir.entries("#{__dir__}/../commands/on_master/admin_master/").select { |e| e.match?(/\.rb/) }).sort.join('|').gsub('.rb','').split('|')
58
58
  end
59
59
 
@@ -75,7 +75,7 @@ class SlackSmartBot
75
75
  general_rules = File.read("#{config.path}/rules/general_rules.rb")
76
76
  commands[:general_rules] = general_rules.scan(/^\s*#\s*help\w*:\s+command_id:\s+:(\w+)\s*$/i).flatten
77
77
  commands[:general_rules]+= general_rules.scan(/^\s*save_stats\(?\s*:(\w+)\s*,?/i).flatten
78
- commands[:general_rules].uniq!
78
+ commands[:general_rules].uniq!
79
79
  end
80
80
  end
81
81
  end
@@ -0,0 +1,18 @@
1
+ class SlackSmartBot
2
+ def get_countries_candelarific()
3
+ http = NiceHttp.new("#{config[:public_holidays][:host]}/api/v2")
4
+ if File.exist?("#{config.path}/vacations/countries_candelarific.json")
5
+ @countries_candelarific = JSON.parse(File.read("#{config.path}/vacations/countries_candelarific.json"))
6
+ else
7
+ response = http.get "/countries?api_key=#{config[:public_holidays][:api_key]}"
8
+ countries_candelarific = response.data.json(:countries)
9
+ if countries_candelarific.is_a?(Array)
10
+ File.write("#{config.path}/vacations/countries_candelarific.json", countries_candelarific.to_json)
11
+ @countries_candelarific = JSON.parse(countries_candelarific.to_json)
12
+ else
13
+ @countries_candelarific = []
14
+ end
15
+ end
16
+ http.close
17
+ end
18
+ end
@@ -1,25 +1,27 @@
1
1
  class SlackSmartBot
2
- def get_help(rules_file, dest, from, only_rules, expanded, descriptions: true, only_normal_user: false)
2
+ def get_help(rules_file, dest, user, only_rules, expanded, descriptions: true, only_normal_user: false)
3
3
  order = {
4
- general: [:bot_help, :hi_bot, :bye_bot, :add_admin, :remove_admin, :see_admins, :poster, :add_announcement, :delete_announcement,
5
- :see_announcements, :see_command_ids, :share_messages, :see_shares, :delete_share, :see_favorite_commands, :see_statuses,
4
+ general: [:bot_help, :hi_bot, :bye_bot, :add_admin, :remove_admin, :see_admins, :add_announcement, :delete_announcement,
5
+ :see_announcements, :see_command_ids, :share_messages, :see_shares, :delete_share, :see_favorite_commands, :see_statuses,
6
6
  :allow_access, :see_access, :deny_access, :add_team, :add_memo_team, :delete_memo_team, :set_memo_status, :see_teams, :update_team, :ping_team, :delete_team,
7
- :see_memos_team, :add_vacation, :remove_vacation, :see_vacations, :see_vacations_team, :public_holidays, :set_public_holidays, :create_loop, :quit_loop,
8
- :get_personal_settings, :delete_personal_settings, :set_personal_settings,
9
- :open_ai_chat, :open_ai_generate_image, :open_ai_edit_image, :open_ai_variations_image, :open_ai_whisper, :open_ai_models ],
7
+ :see_memos_team, :add_vacation, :remove_vacation, :see_vacations, :see_vacations_team, :public_holidays, :set_public_holidays, :create_loop, :quit_loop,
8
+ :get_personal_settings, :delete_personal_settings, :set_personal_settings,
9
+ :open_ai_chat, :open_ai_chat_get_prompts, :open_ai_chat_delete_session, :open_ai_chat_share_session, :open_ai_chat_list_sessions,
10
+ :open_ai_chat_list_sessions, :open_ai_chat_copy_session,
11
+ :open_ai_generate_image, :open_ai_edit_image, :open_ai_variations_image, :open_ai_whisper, :open_ai_models, :recap, :summarize, :get_smartbot_readme, :poster ],
10
12
  on_bot_general: [:whats_new, :suggest_command, :bot_status, :use_rules, :stop_using_rules, :bot_stats, :leaderboard],
11
13
  on_bot: [:ruby_code, :repl, :get_repl, :run_repl, :delete_repl, :see_repls, :kill_repl, :add_shortcut, :delete_shortcut, :see_shortcuts],
12
14
  on_bot_admin: [:extend_rules, :stop_using_rules_on, :start_bot, :pause_bot, :add_routine,
13
15
  :see_routines, :start_routine, :pause_routine, :remove_routine, :see_result_routine, :run_routine]
14
16
  }
15
- if config.masters.include?(from)
17
+ if config.team_id_masters.include?("#{user.team_id}_#{user.name}")
16
18
  user_type = :master # master admin
17
- elsif is_admin?(from)
19
+ elsif is_admin?(user)
18
20
  user_type = :admin
19
21
  else
20
22
  user_type = :normal #normal user
21
23
  end
22
-
24
+
23
25
  # channel_type: :bot, :master_bot, :direct, :extended, :external
24
26
  if dest[0] == "D"
25
27
  channel_type = :direct
@@ -36,7 +38,7 @@ class SlackSmartBot
36
38
  end
37
39
 
38
40
  if only_normal_user
39
- user_type = :normal
41
+ user_type = :normal
40
42
  channel_type = :bot
41
43
  end
42
44
 
@@ -51,7 +53,7 @@ class SlackSmartBot
51
53
  end
52
54
  if rules_file != ""
53
55
  help[:rules_file] = build_help(config.path+rules_file, expanded)[user_type].values.join("\n") + "\n"
54
-
56
+
55
57
  # to get all the help from other rules files added to the main rules file by using require or load. For example general_rules.rb
56
58
  res = IO.readlines(config.path+rules_file).join.scan(/$\s*(load|require)\s("|')(.+)("|')/)
57
59
  rules_help = []
@@ -79,7 +81,7 @@ class SlackSmartBot
79
81
  commands_on_extended_from_on_bot = [:repl, :see_repls, :get_repl, :run_repl, :delete_repl, :kill_repl, :ruby_code]
80
82
  commands_on_extended_from_on_bot.each do |cm|
81
83
  help[:on_extended][cm] = help[:on_bot][cm] if help[:on_bot].key?(cm)
82
- end
84
+ end
83
85
  end
84
86
  help = remove_hash_keys(help, :admin_master) unless user_type == :master
85
87
  help = remove_hash_keys(help, :admin) unless user_type == :admin or user_type == :master
@@ -92,12 +94,12 @@ class SlackSmartBot
92
94
  txt += "===================================
93
95
  For the Smart Bot start listening to you say *hi bot*
94
96
  To run a command on demand even when the Smart Bot is not listening to you:
95
- *!THE_COMMAND*
96
- *@NAME_OF_BOT THE_COMMAND*
97
- *NAME_OF_BOT THE_COMMAND*
97
+ `!THE_COMMAND`
98
+ `@NAME_OF_BOT THE_COMMAND`
99
+ `NAME_OF_BOT THE_COMMAND`
98
100
  To run a command on demand and add the respond on a thread:
99
- *^THE_COMMAND*
100
- *!!THE_COMMAND*\n"
101
+ `^THE_COMMAND`
102
+ `!!THE_COMMAND`\n"
101
103
  end
102
104
  if channel_type == :direct and expanded and descriptions
103
105
  txt += "===================================
@@ -125,7 +127,7 @@ class SlackSmartBot
125
127
  if descriptions
126
128
  if channel_type == :direct
127
129
  txt += "===================================
128
- *General commands:*\n"
130
+ *General commands on Bot channel:*\n"
129
131
  else
130
132
  txt += "===================================
131
133
  *General commands on Bot channel even when the Smart Bot is not listening to you:*\n"
@@ -204,7 +206,7 @@ class SlackSmartBot
204
206
  txt += "===================================
205
207
  *Specific commands on this Channel, call them !THE_COMMAND or !!THE_COMMAND:*\n" if descriptions
206
208
  end
207
-
209
+
208
210
  txt += help.rules_file
209
211
  end
210
212
  return txt
@@ -0,0 +1,47 @@
1
+ class SlackSmartBot
2
+ def get_openai_sessions(session_name='', team_id: '', user_name: '')
3
+ require 'yaml'
4
+ unless Thread.current[:user].nil?
5
+ user_name = Thread.current[:user].name if user_name == ''
6
+ team_id = Thread.current[:user].team_id if team_id == ''
7
+ team_id_user = team_id + "_" + user_name
8
+ end
9
+
10
+ # get folders on openai folder
11
+ folders = Dir.glob(File.join(config.path, "openai", "*")).select {|f| File.directory? f}
12
+ # get files on every team folder
13
+ files = []
14
+ folders.each do |folder|
15
+ files += Dir.glob(File.join(folder, "o_*.yaml"))
16
+ end
17
+ @datetime_open_ai_file ||= {}
18
+
19
+ files.each do |file|
20
+ if !defined?(@datetime_open_ai_file) or !@datetime_open_ai_file.key?(file) or @datetime_open_ai_file[file] != File.mtime(file)
21
+ opean_ai_user = YAML.load(Utils::Encryption.decrypt(File.read(file), config))
22
+ #user_file will be the team_id _ + the user name
23
+ user_team_id = File.basename(File.dirname(file))
24
+ user_file = user_team_id + "_" + File.basename(file).gsub("o_","").gsub(".yaml","")
25
+
26
+ if @open_ai.key?(user_file) and @open_ai[user_file].key?(:chat_gpt) and @open_ai[user_file][:chat_gpt].key?(:sessions) and
27
+ @open_ai[user_file][:chat_gpt][:sessions].key?("")
28
+ temp_session = @open_ai[user_file][:chat_gpt][:sessions][""].deep_copy
29
+ else
30
+ temp_session = nil
31
+ end
32
+ @open_ai[user_file] = opean_ai_user
33
+ @open_ai[user_file][:chat_gpt][:sessions][""] = temp_session unless temp_session.nil?
34
+ @datetime_open_ai_file[file] = File.mtime(file)
35
+ end
36
+ end
37
+ if session_name != ''
38
+ file_name = File.join(config.path, "openai", "#{team_id}/#{user_name}/session_#{session_name}.txt")
39
+ if File.exist?(file_name)
40
+ @ai_gpt ||= {}
41
+ @ai_gpt[team_id_user] ||= {}
42
+ content = File.read(file_name)
43
+ @ai_gpt[team_id_user][session_name] = Utils::Encryption.decrypt(content, config).force_encoding("UTF-8").split("\n")
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,13 +1,39 @@
1
1
  class SlackSmartBot
2
- def get_personal_settings
2
+ def get_personal_settings()
3
3
  @personal_settings ||= {}
4
4
  @datetime_personal_settings_file ||= {}
5
- files = Dir.glob(File.join(config.path, "personal_settings", "ps_*.yaml"))
5
+ @personal_settings_hash ||= {}
6
+
7
+ folders = Dir.glob(File.join(config.path, "personal_settings", "*")).select {|f| File.directory? f}
8
+ files = []
9
+ folders.each do |folder|
10
+ files += Dir.glob(File.join(folder, "ps_*.yaml"))
11
+ end
12
+
6
13
  files.each do |file|
7
14
  if !defined?(@datetime_personal_settings_file) or !@datetime_personal_settings_file.key?(file) or @datetime_personal_settings_file[file] != File.mtime(file)
8
15
  user_personal_settings = YAML.load(Utils::Encryption.decrypt(File.read(file),config))
9
- @personal_settings[File.basename(file).gsub("ps_","").gsub(".yaml","")] = user_personal_settings
16
+
17
+ user_team_id = File.basename(File.dirname(file))
18
+ user_file = user_team_id + "_" + File.basename(file).gsub("ps_","").gsub(".yaml","")
19
+
20
+ @personal_settings[user_file] = user_personal_settings
10
21
  @datetime_personal_settings_file[file] = File.mtime(file)
22
+
23
+ @personal_settings.each do |user, ps|
24
+ @personal_settings_hash[user] = {}
25
+ ps.each do |key, value|
26
+ t = @personal_settings_hash[user]
27
+ key.split('.').each_with_index do |k, i|
28
+ if i == key.split('.').size - 1 #last element
29
+ t[k.to_s.to_sym] = value
30
+ else
31
+ t[k.to_s.to_sym] ||= {}
32
+ t = t[k.to_s.to_sym]
33
+ end
34
+ end
35
+ end
36
+ end
11
37
  end
12
38
  end
13
39
  end
@@ -1,14 +1,35 @@
1
1
  class SlackSmartBot
2
2
 
3
3
  def get_rules_imported
4
- if File.exist?("#{config.path}/rules/rules_imported.rb")
5
- if !defined?(@datetime_rules_imported) or @datetime_rules_imported != File.mtime("#{config.path}/rules/rules_imported.rb")
6
- @datetime_rules_imported = File.mtime("#{config.path}/rules/rules_imported.rb")
7
- file_conf = IO.readlines("#{config.path}/rules/rules_imported.rb").join
8
- unless file_conf.to_s() == ""
9
- @rules_imported = eval(file_conf)
4
+ require 'yaml'
5
+ file_path = "#{config.path}/rules/rules_imported"
6
+ if File.exist?("#{file_path}.rb") #backwards compatible
7
+ file_conf = IO.readlines("#{file_path}.rb").join
8
+ if file_conf.to_s() == ""
9
+ @rules_imported = {}
10
+ else
11
+ @rules_imported = eval(file_conf)
12
+ end
13
+ File.open("#{file_path}.yaml", 'w') {|file| file.write(@rules_imported.to_yaml) }
14
+ File.delete("#{file_path}.rb")
15
+ end
16
+
17
+ if File.exist?("#{file_path}.yaml")
18
+ if !defined?(@datetime_rules_imported) or @datetime_rules_imported != File.mtime("#{file_path}.yaml")
19
+ @datetime_rules_imported = File.mtime("#{file_path}.yaml")
20
+ rules_imported = @rules_imported
21
+ 10.times do
22
+ rules_imported = YAML.load(File.read("#{file_path}.yaml"))
23
+ if rules_imported.is_a?(Hash)
24
+ break
25
+ else
26
+ sleep (0.1*(rand(2)+1))
27
+ end
10
28
  end
29
+ @rules_imported = rules_imported unless rules_imported.is_a?(FalseClass)
11
30
  end
31
+ else
32
+ @rules_imported = {}
12
33
  end
13
34
  end
14
35
 
@@ -4,7 +4,7 @@ class SlackSmartBot
4
4
  channel = @channels_name[@channel_id]
5
5
  if File.exist?("#{config.path}/shares/#{channel}.csv")
6
6
  "#{config.path}/shares/#{channel}.csv"
7
- t = CSV.table("#{config.path}/shares/#{channel}.csv", headers: ['share_id', 'user_deleted', 'user_created', 'date', 'time', 'type', 'to_channel', 'condition'])
7
+ t = CSV.table("#{config.path}/shares/#{channel}.csv", headers: ['share_id', 'user_team_id_deleted', 'user_deleted', 'user_team_id_created', 'user_created', 'date', 'time', 'type', 'to_channel', 'condition'])
8
8
  t.delete_if {|row| row[:user_deleted] != ''}
9
9
  @shares[channel] = t
10
10
  end
@@ -3,7 +3,7 @@ class SlackSmartBot
3
3
  assigned_members = team.members.values.flatten
4
4
  assigned_members.uniq!
5
5
  assigned_members.dup.each do |m|
6
- user_info = @users.select { |u| u.id == m or (u.key?(:enterprise_user) and u.enterprise_user.id == m) or u.name == m or (u.key?(:enterprise_user) and u.enterprise_user.name == m) }[-1]
6
+ user_info = find_user(m)
7
7
  assigned_members.delete(m) if user_info.nil? or user_info.deleted
8
8
  end
9
9
  channels_members = []
@@ -18,15 +18,15 @@ class SlackSmartBot
18
18
  else
19
19
  channels_members << @channels_id[ch]
20
20
  tm.each do |m|
21
- user_info = @users.select { |u| u.id == m or (u.key?(:enterprise_user) and u.enterprise_user.id == m) }[-1]
22
- team_members << user_info.name unless user_info.is_app_user or user_info.is_bot
21
+ user_info = find_user(m)
22
+ team_members << "#{user_info.team_id}_#{user_info.name}" unless user_info.nil? or user_info.is_app_user or user_info.is_bot
23
23
  end
24
24
  end
25
25
  end
26
26
  team_members.flatten!
27
27
  team_members.uniq!
28
28
  unassigned_members = team_members - assigned_members
29
- unassigned_members.delete(config.nick)
29
+ unassigned_members.delete("#{config.team_id}_#{config.nick}")
30
30
  not_on_team_channel = assigned_members - team_members
31
31
  all_team_members += team_members
32
32
  else
@@ -14,13 +14,21 @@ class SlackSmartBot
14
14
  @logger.info "Deleting old_vacations_file: #{old_vacations_file}"
15
15
  File.delete(old_vacations_file)
16
16
  end
17
- files = Dir.glob(File.join(config.path, "vacations", "v_*.yaml"))
18
- @datetime_vacations_file ||= {}
19
- files.each do |file|
20
- if !defined?(@datetime_vacations_file) or !@datetime_vacations_file.key?(file) or @datetime_vacations_file[file] != File.mtime(file)
21
- vacations_user = YAML.load(Utils::Encryption.decrypt(File.read(file), config))
22
- @vacations[File.basename(file).gsub("v_","").gsub(".yaml","")] = vacations_user
23
- @datetime_vacations_file[file] = File.mtime(file)
17
+ # get the yaml files. They will be on /vacations then in there a folder for each team and inside the yaml files for each user
18
+ folders = Dir.glob(File.join(config.path, "vacations", "*"))
19
+ folders.each do |folder|
20
+ if File.directory?(folder)
21
+ files = Dir.glob(File.join(folder, "*.yaml"))
22
+ @datetime_vacations_file ||= {}
23
+ files.each do |file|
24
+ if !defined?(@datetime_vacations_file) or !@datetime_vacations_file.key?(file) or @datetime_vacations_file[file] != File.mtime(file)
25
+ vacations_user = YAML.load(Utils::Encryption.decrypt(File.read(file), config))
26
+ #the key of @vacations will be the team_id_user_name
27
+ team_id = File.basename(folder)
28
+ @vacations["#{team_id}_#{File.basename(file).gsub("v_","").gsub(".yaml","")}"] = vacations_user
29
+ @datetime_vacations_file[file] = File.mtime(file)
30
+ end
31
+ end
24
32
  end
25
33
  end
26
34
  end
@@ -1,8 +1,11 @@
1
1
  class SlackSmartBot
2
2
  def has_access?(method, user = nil)
3
3
  user = Thread.current[:user] if user.nil?
4
+ team_id_user = "#{user.team_id}_#{user.name}"
4
5
  if config[:allow_access].key?(method) and !config[:allow_access][method].include?(user.name) and !config[:allow_access][method].include?(user.id) and
5
- (!user.key?(:enterprise_user) or (user.key?(:enterprise_user) and !config[:allow_access][method].include?(user[:enterprise_user].id)))
6
+ !config[:allow_access][method].include?(team_id_user) and
7
+ (!user.key?(:enterprise_user) or (user.key?(:enterprise_user) and !config[:allow_access][method].include?(user[:enterprise_user].id) and
8
+ !config[:allow_access][method].include?("#{user[:enterprise_user].enterprise_id}_#{user[:enterprise_user].name}")))
6
9
  respond "You don't have access to use this command, please contact an Admin to be able to use it: <@#{config.admins.join(">, <@")}>"
7
10
  return false
8
11
  else
@@ -13,14 +16,17 @@ class SlackSmartBot
13
16
  else
14
17
  channel = Thread.current[:using_channel]
15
18
  end
16
- if !@access_channels.key?(channel) or !@access_channels[channel].key?(method.to_s) or @access_channels[channel][method.to_s].include?(user.name)
19
+ if !@access_channels.key?(channel) or !@access_channels[channel].key?(method.to_s) or
20
+ @access_channels[channel][method.to_s].include?(user.name) or
21
+ @access_channels[channel][method.to_s].include?(team_id_user)
17
22
  return true
18
23
  else
19
24
  if @admins_channels.key?(channel) and !@admins_channels[channel].empty?
20
- respond "You don't have access to use this command, please contact an Admin to be able to use it: <@#{@admins_channels[channel].join(">, <@")}>"
25
+ admins = @admins_channels[channel].map { |a| a.split('_')[1..-1].join('_') }
26
+ respond "You don't have access to use this command, please contact an Admin to be able to use it: <@#{admins.join(">, <@")}>"
21
27
  else
22
28
  respond "You don't have access to use this command, please contact an Admin to be able to use it."
23
- end
29
+ end
24
30
  return false
25
31
  end
26
32
  end
@@ -1,27 +1,35 @@
1
1
  class SlackSmartBot
2
- def is_admin?(from=nil)
3
- if from.nil?
2
+ def is_admin?(user=nil)
3
+ if user.nil?
4
4
  user = Thread.current[:user]
5
- from = user.name
5
+ team_id_user_name = "#{user.team_id}_#{user.name}"
6
+ elsif user.is_a?(String) and user.match?(/^[A-Z0-9]{7,11}_/)
7
+ team_id = user.split('_')[0]
8
+ user_name = user.split('_')[1..-1].join('_')
9
+ team_id_user_name = "#{team_id}_#{user_name}"
10
+ elsif user.is_a?(String)
11
+ team_id_user_name = "#{config.team_id}_#{user}"
12
+ else
13
+ team_id_user_name = "#{user.team_id}_#{user.name}"
6
14
  end
7
-
8
- if (Thread.current[:dchannel].to_s!='' and !@channels_creator.key?(Thread.current[:dchannel])) or
9
- (Thread.current[:dest].to_s!='' and Thread.current[:dest][0]!='D' and !@channels_creator.key?(Thread.current[:dest])) or
10
- (Thread.current[:using_channel].to_s!='' and !@channels_creator.key?(:using_channel))
11
- get_channels_name_and_id()
15
+
16
+ if (Thread.current[:dchannel].to_s!='' and Thread.current[:dchannel][0]!='D' and !@channels_creator.key?(Thread.current[:dchannel])) or
17
+ (Thread.current[:dest].to_s!='' and Thread.current[:dest][0]!='D' and !@channels_creator.key?(Thread.current[:dest])) or
18
+ (Thread.current[:using_channel].to_s!='' and !@channels_creator.key?(Thread.current[:using_channel]))
19
+ get_channels_name_and_id()
12
20
  end
13
21
 
14
- if config.masters.include?(from) or
15
- config.admins.include?(from) or
16
- (Thread.current[:typem] == :on_call and @admins_channels.key?(Thread.current[:dchannel]) and @admins_channels[Thread.current[:dchannel]].include?(from)) or
17
- (Thread.current[:using_channel].to_s == '' and @admins_channels.key?(Thread.current[:dest]) and @admins_channels[Thread.current[:dest]].include?(from)) or
18
- (@admins_channels.key?(Thread.current[:using_channel]) and @admins_channels[Thread.current[:using_channel]].include?(from)) or
19
- (Thread.current[:using_channel].to_s=='' and @channels_creator.key?(Thread.current[:dest]) and from == @channels_creator[Thread.current[:dest]]) or
20
- (Thread.current[:typem] == :on_call and @channels_creator.key?(Thread.current[:dchannel]) and from == @channels_creator[Thread.current[:dchannel]]) or
21
- (@channels_creator.key?(Thread.current[:using_channel]) and from == @channels_creator[Thread.current[:using_channel]])
22
+ if config.team_id_masters.include?(team_id_user_name) or
23
+ config.team_id_admins.include?(team_id_user_name) or
24
+ (Thread.current[:typem] == :on_call and @admins_channels.key?(Thread.current[:dchannel]) and @admins_channels[Thread.current[:dchannel]].include?(team_id_user_name)) or
25
+ (Thread.current[:using_channel].to_s == '' and @admins_channels.key?(Thread.current[:dest]) and @admins_channels[Thread.current[:dest]].include?(team_id_user_name)) or
26
+ (@admins_channels.key?(Thread.current[:using_channel]) and @admins_channels[Thread.current[:using_channel]].include?(team_id_user_name)) or
27
+ (Thread.current[:using_channel].to_s=='' and @channels_creator.key?(Thread.current[:dest]) and team_id_user_name == @channels_creator[Thread.current[:dest]]) or
28
+ (Thread.current[:typem] == :on_call and @channels_creator.key?(Thread.current[:dchannel]) and team_id_user_name == @channels_creator[Thread.current[:dchannel]]) or
29
+ (@channels_creator.key?(Thread.current[:using_channel]) and team_id_user_name == @channels_creator[Thread.current[:using_channel]])
22
30
  return true
23
31
  else
24
32
  return false
25
33
  end
26
34
  end
27
- end
35
+ end
@@ -0,0 +1,29 @@
1
+ class SlackSmartBot
2
+ def local_time(country_region, return_default_if_not_found = true)
3
+ require "tzinfo"
4
+ @time_zone_identifiers ||= TZInfo::Timezone.all_identifiers
5
+ country, region = country_region.to_s.split("/")
6
+ identifier = nil
7
+ if region.nil?
8
+ get_countries_candelarific() if !defined?(@countries_candelarific)
9
+ found_country = @countries_candelarific.find { |c| c.country_name.match?(/^\s*#{country}\s*$/i) }
10
+ unless found_country.nil?
11
+ country_iso = found_country["iso-3166"]
12
+ found_country = TZInfo::Country.get(country_iso).zone_identifiers
13
+ region = found_country.first.split("/").last unless found_country.empty?
14
+ end
15
+ end
16
+ identifier = @time_zone_identifiers.find { |id| id.downcase.include?(region.to_s.gsub(" ", "_").downcase) } unless region.nil?
17
+ identifier = @time_zone_identifiers.find { |id| id.downcase.include?(country.to_s.gsub(" ", "_").downcase) } if identifier.nil?
18
+ if identifier.nil?
19
+ if return_default_if_not_found
20
+ return local_time(config.public_holidays.default_calendar, false)
21
+ else
22
+ return nil
23
+ end
24
+ else
25
+ tz = TZInfo::Timezone.get(identifier)
26
+ return tz.now
27
+ end
28
+ end
29
+ end
@@ -8,7 +8,7 @@ class SlackSmartBot
8
8
  require "csv"
9
9
  if !File.exist?("#{config.stats_path}.#{Time.now.strftime("%Y-%m")}.log")
10
10
  CSV.open("#{config.stats_path}.#{Time.now.strftime("%Y-%m")}.log", "wb") do |csv|
11
- csv << ["date", "bot_channel", "bot_channel_id", "dest_channel", "dest_channel_id", "type_message", "user_name", "user_id", "text", "command", "files", "time_zone", "job_title"]
11
+ csv << ["date", "bot_channel", "bot_channel_id", "dest_channel", "dest_channel_id", "type_message", "user_name", "user_id", "text", "command", "files", "time_zone", "job_title", "team_id"]
12
12
  end
13
13
  end
14
14
  if data.empty?
@@ -36,17 +36,19 @@ class SlackSmartBot
36
36
  user_name = data.user.name
37
37
  user_id = data.user.id
38
38
  end
39
- user_info = @users.select { |u| u.id == user_id or (u.key?(:enterprise_user) and u.enterprise_user.id == user_id) }[-1]
39
+ user_info = find_user(data.user.id)
40
40
  if user_info.nil? or user_info.is_app_user or user_info.is_bot
41
41
  time_zone = ''
42
42
  job_title = ''
43
+ team_id = ''
43
44
  else
44
45
  time_zone = user_info.tz_label
45
46
  job_title = user_info.profile.title
47
+ team_id = user_info.team_id
46
48
  end
47
49
  command_txt = "#{method} encrypted" if command_ids_not_to_log.include?(method.to_s)
48
50
  CSV.open("#{config.stats_path}.#{Time.now.strftime("%Y-%m")}.log", "a+") do |csv|
49
- csv << [Time.now, config.channel, @channel_id, @channels_name[data.dest], data.dest, data.typem, user_name, user_id, command_txt, method, data.files, time_zone, job_title]
51
+ csv << [Time.now, config.channel, @channel_id, @channels_name[data.dest], data.dest, data.typem, user_name, user_id, command_txt, method, data.files, time_zone, job_title, team_id]
50
52
  end
51
53
  rescue Exception => exception
52
54
  @logger.fatal "There was a problem on the stats"
@@ -1,8 +1,24 @@
1
1
  class SlackSmartBot
2
2
 
3
3
  def update_access_channels()
4
- file = File.open("#{config.path}/rules/#{@channel_id}/access_channels.rb", "w")
5
- file.write (@access_channels.inspect)
6
- file.close
4
+ require 'yaml'
5
+ access_ch_file = "#{config.path}/rules/#{@channel_id}/access_channels"
6
+
7
+ if File.exist?("#{access_ch_file}.rb") #backwards compatible
8
+ file_conf = IO.readlines("#{access_ch_file}.rb").join
9
+ if file_conf.to_s() == ""
10
+ @access_channels = {}
11
+ else
12
+ @access_channels = eval(file_conf)
13
+ end
14
+ File.open("#{access_ch_file}.yaml", 'w') {|file| file.write(@access_channels.to_yaml) }
15
+ File.delete("#{access_ch_file}.rb")
16
+ end
17
+
18
+ File.open("#{access_ch_file}.yaml", 'w') {|file|
19
+ file.flock(File::LOCK_EX)
20
+ file.write(@access_channels.to_yaml)
21
+ file.flock(File::LOCK_UN)
22
+ }
7
23
  end
8
24
  end
@@ -0,0 +1,42 @@
1
+ class SlackSmartBot
2
+ def update_openai_sessions(session_name='', team_id: '', user_name: '')
3
+ require 'yaml'
4
+ user_name = Thread.current[:user].name if user_name == ''
5
+ team_id = Thread.current[:user].team_id if team_id == ''
6
+ team_id_user = team_id + "_" + user_name
7
+
8
+ unless Dir.exist?("#{config.path}/openai/#{team_id}")
9
+ Dir.mkdir("#{config.path}/openai/#{team_id}")
10
+ end
11
+
12
+ unless Dir.exist?("#{config.path}/openai/#{team_id}/#{user_name}")
13
+ Dir.mkdir("#{config.path}/openai/#{team_id}/#{user_name}")
14
+ end
15
+ file_name = File.join(config.path, "openai/#{team_id}", "o_#{user_name}.yaml")
16
+ data = @open_ai[team_id_user].deep_copy
17
+ if data.key?(:chat_gpt) and data[:chat_gpt].key?(:sessions)
18
+ data[:chat_gpt][:sessions].delete('') #temporary session
19
+ end
20
+ File.open(file_name, 'w') {|file|
21
+ file.flock(File::LOCK_EX)
22
+ file.write(Utils::Encryption.encrypt(data.to_yaml, config))
23
+ file.flock(File::LOCK_UN)
24
+ }
25
+ @datetime_open_ai_file[file_name] = File.mtime(file_name)
26
+ if session_name != ''
27
+ if !@open_ai[team_id_user][:chat_gpt][:sessions].key?(session_name) #delete file if session is not longer available
28
+ if File.exist?(File.join(config.path, "openai/#{team_id}", "#{user_name}/session_#{session_name}.txt"))
29
+ File.delete(File.join(config.path, "openai/#{team_id}", "#{user_name}/session_#{session_name}.txt"))
30
+ end
31
+ else
32
+ file_name = File.join(config.path, "openai/#{team_id}", "#{user_name}/session_#{session_name}.txt")
33
+ content = @ai_gpt[team_id_user][session_name].join("\n").force_encoding("UTF-8")
34
+ File.open(file_name, 'w') {|file|
35
+ file.flock(File::LOCK_EX)
36
+ file.write(Utils::Encryption.encrypt(content, config))
37
+ file.flock(File::LOCK_UN)
38
+ }
39
+ end
40
+ end
41
+ end
42
+ end