collavre_slack 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +80 -0
  3. data/Rakefile +3 -0
  4. data/app/assets/stylesheets/collavre_slack/slack_integration.css +15 -0
  5. data/app/controllers/collavre_slack/application_controller.rb +12 -0
  6. data/app/controllers/collavre_slack/creatives/slack_integrations_controller.rb +101 -0
  7. data/app/controllers/collavre_slack/slack_auth_controller.rb +105 -0
  8. data/app/controllers/collavre_slack/slack_events_controller.rb +63 -0
  9. data/app/controllers/collavre_slack/slack_messages_controller.rb +24 -0
  10. data/app/javascript/collavre_slack.js +509 -0
  11. data/app/jobs/collavre_slack/application_job.rb +4 -0
  12. data/app/jobs/collavre_slack/slack_channel_sync_job.rb +45 -0
  13. data/app/jobs/collavre_slack/slack_inbound_message_delete_job.rb +24 -0
  14. data/app/jobs/collavre_slack/slack_inbound_message_job.rb +129 -0
  15. data/app/jobs/collavre_slack/slack_inbound_message_update_job.rb +22 -0
  16. data/app/jobs/collavre_slack/slack_inbound_reaction_job.rb +47 -0
  17. data/app/jobs/collavre_slack/slack_message_delete_job.rb +29 -0
  18. data/app/jobs/collavre_slack/slack_message_job.rb +45 -0
  19. data/app/jobs/collavre_slack/slack_message_update_job.rb +32 -0
  20. data/app/jobs/collavre_slack/slack_reaction_job.rb +45 -0
  21. data/app/models/collavre_slack/application_record.rb +5 -0
  22. data/app/models/collavre_slack/slack_account.rb +13 -0
  23. data/app/models/collavre_slack/slack_channel_link.rb +16 -0
  24. data/app/models/collavre_slack/slack_comment_link.rb +18 -0
  25. data/app/models/collavre_slack/slack_message_log.rb +11 -0
  26. data/app/models/collavre_slack/slack_user_mapping.rb +10 -0
  27. data/app/models/concerns/collavre_slack/slack_dispatchable.rb +97 -0
  28. data/app/models/concerns/collavre_slack/slack_reaction_dispatchable.rb +55 -0
  29. data/app/services/collavre_slack/emoji_mapping.rb +90 -0
  30. data/app/services/collavre_slack/mention_mapping.rb +45 -0
  31. data/app/services/collavre_slack/slack_client.rb +141 -0
  32. data/app/services/collavre_slack/slack_event_handler.rb +259 -0
  33. data/app/services/collavre_slack/slack_integration_service.rb +26 -0
  34. data/app/services/collavre_slack/slack_message_dispatcher.rb +24 -0
  35. data/app/views/collavre_slack/creatives/slack_integrations/index.html.erb +18 -0
  36. data/app/views/collavre_slack/integrations/_modal.html.erb +66 -0
  37. data/config/initializers/collavre_slack.rb +7 -0
  38. data/config/locales/en.yml +57 -0
  39. data/config/locales/ko.yml +57 -0
  40. data/config/routes.rb +11 -0
  41. data/db/migrate/20250201000001_create_slack_accounts.rb +17 -0
  42. data/db/migrate/20250201000002_create_slack_channel_links.rb +17 -0
  43. data/db/migrate/20250201000003_create_slack_user_mappings.rb +15 -0
  44. data/db/migrate/20250201000004_create_slack_message_logs.rb +14 -0
  45. data/db/migrate/20250201000005_add_last_synced_at_to_slack_channel_links.rb +5 -0
  46. data/db/migrate/20260130010000_create_slack_comment_links.rb +13 -0
  47. data/db/migrate/20260130010001_add_comment_id_to_slack_message_logs.rb +5 -0
  48. data/db/migrate/20260130020000_add_cascade_delete_to_slack_comment_foreign_keys.rb +11 -0
  49. data/db/migrate/20260131000000_remove_is_active_from_slack_channel_links.rb +5 -0
  50. data/lib/collavre_slack/configuration.rb +13 -0
  51. data/lib/collavre_slack/engine.rb +97 -0
  52. data/lib/collavre_slack/version.rb +3 -0
  53. data/lib/collavre_slack.rb +13 -0
  54. metadata +151 -0
@@ -0,0 +1,57 @@
1
+ ko:
2
+ collavre_slack:
3
+ integration:
4
+ label: "Slack"
5
+ description: "Slack 채널과 채팅 메시지 동기화"
6
+ errors:
7
+ forbidden: "접근 권한이 없습니다"
8
+ not_found: "찾을 수 없습니다"
9
+ creative_already_linked: "이미 Slack 채널에 연결되어 있습니다"
10
+ no_slack_account: "연결된 Slack 계정이 없습니다"
11
+ authentication_required: "인증이 필요합니다"
12
+ missing_oauth_code: "OAuth 코드가 없습니다"
13
+ missing_oauth_state: "OAuth 상태가 없습니다"
14
+ invalid_oauth_state: "잘못된 OAuth 상태입니다"
15
+ user_not_found: "사용자를 찾을 수 없습니다"
16
+ oauth_failed: "Slack OAuth 인증에 실패했습니다"
17
+ save_failed: "저장 실패: %{errors}"
18
+ invalid_signature: "잘못된 서명입니다"
19
+ messages:
20
+ anonymous: "익명"
21
+ thread_reply: "[스레드 답글]"
22
+ slack_user_prefix: "[Slack: @%{name}]"
23
+ attachments: "첨부파일:"
24
+ views:
25
+ slack_integrations:
26
+ title: "Slack 연동"
27
+ connect_slack: "Slack 연결"
28
+ no_channels_linked: "연결된 Slack 채널이 없습니다."
29
+ auth:
30
+ success_title: "Slack 연결됨"
31
+ success_message: "Slack 워크스페이스가 성공적으로 연결되었습니다! 이 창을 닫아도 됩니다."
32
+ modal:
33
+ title: "Slack 연동 설정"
34
+ success_message: "Slack 연동이 성공적으로 저장되었습니다."
35
+ login_required: "연동을 시작하려면 Slack 워크스페이스에 로그인하세요."
36
+ missing_creative: "연동할 Creative가 선택되지 않았습니다."
37
+ existing_message: "이미 아래 Slack 채널에 연결되어 있습니다."
38
+ delete_confirm: "이 Slack 채널 연결을 삭제하시겠습니까?"
39
+ delete_success: "Slack 채널 연결이 성공적으로 삭제되었습니다."
40
+ delete_error: "Slack 채널 연결 삭제에 실패했습니다."
41
+ delete_button: "삭제"
42
+ add_first_channel: "Slack 채널 연결하기"
43
+ connect_message: "이 Creative와 메시지를 동기화하려면 Slack 워크스페이스를 연결하세요."
44
+ login_button: "Slack 워크스페이스 연결"
45
+ connected_status: "Slack 연결됨"
46
+ existing_intro: "연결된 Slack 채널:"
47
+ add_channel: "다른 채널 추가"
48
+ choose_channel: "이 Creative와 연결할 Slack 채널을 선택하세요."
49
+ summary_intro: "Slack 채널을 연결할 준비가 되었습니다:"
50
+ channel_label: "채널:"
51
+ sync_note: "이 Slack 채널에 게시된 메시지가 이 Creative에 나타나고, 그 반대도 마찬가지입니다."
52
+ loading: "로딩 중..."
53
+ linking: "연결 중..."
54
+ link_channel: "채널 연결"
55
+ refresh: "새로고침"
56
+ refresh_error: "채널 목록을 새로고침하는데 실패했습니다"
57
+ linked_label: "(연결됨)"
data/config/routes.rb ADDED
@@ -0,0 +1,11 @@
1
+ CollavreSlack::Engine.routes.draw do
2
+ get "/auth/slack", to: "slack_auth#start"
3
+ get "/auth/slack/callback", to: "slack_auth#callback"
4
+
5
+ resources :creatives, only: [] do
6
+ resources :slack_integrations, module: :creatives, only: [ :index, :create, :destroy ]
7
+ resources :slack_messages, only: [ :create ]
8
+ end
9
+
10
+ post "/slack/events", to: "slack_events#create"
11
+ end
@@ -0,0 +1,17 @@
1
+ class CreateSlackAccounts < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :slack_accounts do |t|
4
+ t.references :user, null: false, foreign_key: { to_table: :users }
5
+ t.string :team_id, null: false
6
+ t.string :team_name, null: false
7
+ t.string :access_token, null: false
8
+ t.string :authed_user_id
9
+ t.string :scopes
10
+ t.datetime :token_expires_at
11
+
12
+ t.timestamps
13
+ end
14
+
15
+ add_index :slack_accounts, :team_id, unique: true
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ class CreateSlackChannelLinks < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :slack_channel_links do |t|
4
+ t.references :creative, null: false, foreign_key: { to_table: :creatives }
5
+ t.references :slack_account, null: false, foreign_key: { to_table: :slack_accounts }
6
+ t.string :channel_id, null: false
7
+ t.string :channel_name, null: false
8
+ t.references :created_by, null: false, foreign_key: { to_table: :users }
9
+ t.boolean :is_active, null: false, default: true
10
+
11
+ t.timestamps
12
+ end
13
+
14
+ add_index :slack_channel_links, [ :creative_id, :channel_id ], unique: true
15
+ add_index :slack_channel_links, :channel_id
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ class CreateSlackUserMappings < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :slack_user_mappings do |t|
4
+ t.references :slack_account, null: false, foreign_key: { to_table: :slack_accounts }
5
+ t.references :collavre_user, null: false, foreign_key: { to_table: :users }
6
+ t.string :slack_user_id, null: false
7
+ t.string :display_name
8
+ t.string :email
9
+
10
+ t.timestamps
11
+ end
12
+
13
+ add_index :slack_user_mappings, [ :slack_account_id, :slack_user_id ], unique: true
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ class CreateSlackMessageLogs < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :slack_message_logs do |t|
4
+ t.references :slack_channel_link, null: false, foreign_key: { to_table: :slack_channel_links }
5
+ t.references :sender, null: true, foreign_key: { to_table: :users }
6
+ t.text :message, null: false
7
+ t.string :message_ts
8
+ t.string :status, null: false, default: "queued"
9
+ t.text :error_message
10
+
11
+ t.timestamps
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ class AddLastSyncedAtToSlackChannelLinks < ActiveRecord::Migration[8.0]
2
+ def change
3
+ add_column :slack_channel_links, :last_synced_at, :datetime
4
+ end
5
+ end
@@ -0,0 +1,13 @@
1
+ class CreateSlackCommentLinks < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :slack_comment_links do |t|
4
+ t.references :comment, null: false, foreign_key: { to_table: :comments }
5
+ t.references :slack_channel_link, null: false, foreign_key: true
6
+ t.string :message_ts, null: false
7
+
8
+ t.timestamps
9
+ end
10
+
11
+ add_index :slack_comment_links, [ :slack_channel_link_id, :message_ts ], unique: true, name: "idx_slack_comment_links_on_channel_and_ts"
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ class AddCommentIdToSlackMessageLogs < ActiveRecord::Migration[8.0]
2
+ def change
3
+ add_reference :slack_message_logs, :comment, foreign_key: { to_table: :comments }
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ class AddCascadeDeleteToSlackCommentForeignKeys < ActiveRecord::Migration[8.0]
2
+ def change
3
+ # Remove existing foreign keys
4
+ remove_foreign_key :slack_comment_links, :comments
5
+ remove_foreign_key :slack_message_logs, :comments
6
+
7
+ # Re-add with ON DELETE CASCADE
8
+ add_foreign_key :slack_comment_links, :comments, on_delete: :cascade
9
+ add_foreign_key :slack_message_logs, :comments, on_delete: :cascade
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ class RemoveIsActiveFromSlackChannelLinks < ActiveRecord::Migration[8.0]
2
+ def change
3
+ remove_column :slack_channel_links, :is_active, :boolean, default: true, null: false
4
+ end
5
+ end
@@ -0,0 +1,13 @@
1
+ module CollavreSlack
2
+ class Configuration
3
+ attr_accessor :client_id, :client_secret, :signing_secret, :redirect_uri, :scopes
4
+
5
+ def initialize
6
+ @client_id = ENV.fetch("SLACK_CLIENT_ID", "")
7
+ @client_secret = ENV.fetch("SLACK_CLIENT_SECRET", "")
8
+ @signing_secret = ENV.fetch("SLACK_SIGNING_SECRET", "")
9
+ @redirect_uri = ENV.fetch("SLACK_REDIRECT_URI", "")
10
+ @scopes = ENV.fetch("SLACK_SCOPES", "chat:write,channels:read,channels:history,groups:read,im:read,mpim:read,users:read,users:read.email,reactions:read,reactions:write")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,97 @@
1
+ module CollavreSlack
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace CollavreSlack
4
+
5
+ config.generators do |g|
6
+ g.test_framework :minitest
7
+ end
8
+
9
+ # Path to engine's JavaScript sources for jsbundling-rails integration
10
+ def self.javascript_path
11
+ root.join("app/javascript")
12
+ end
13
+
14
+ # Path to engine's stylesheet sources
15
+ def self.stylesheet_path
16
+ root.join("app/assets/stylesheets")
17
+ end
18
+
19
+ # Load locale files
20
+ config.i18n.load_path += Dir[root.join("config", "locales", "*.yml")]
21
+
22
+ # Auto-mount engine routes
23
+ initializer "collavre_slack.routes", before: :add_routing_paths do |app|
24
+ app.routes.append do
25
+ mount CollavreSlack::Engine => "/slack", as: :slack_engine
26
+ end
27
+ end
28
+
29
+ # Add engine stylesheets to asset paths for Propshaft
30
+ initializer "collavre_slack.assets" do |app|
31
+ if app.config.respond_to?(:assets) && app.config.assets.respond_to?(:paths)
32
+ app.config.assets.paths << root.join("app/assets/stylesheets")
33
+ end
34
+ end
35
+
36
+ initializer "collavre_slack.migrations" do |app|
37
+ unless app.root.to_s.match?(root.to_s)
38
+ config.paths["db/migrate"].expanded.each do |expanded_path|
39
+ app.config.paths["db/migrate"] << expanded_path
40
+ end
41
+ end
42
+ end
43
+
44
+ # Register as Collavre integration
45
+ initializer "collavre_slack.register_integration", after: :load_config_initializers do
46
+ Rails.application.config.to_prepare do
47
+ if defined?(Collavre::IntegrationRegistry)
48
+ Collavre::IntegrationRegistry.register(:slack, {
49
+ label: I18n.t("collavre_slack.integration.label", default: "Slack"),
50
+ icon: "slack",
51
+ description: I18n.t("collavre_slack.integration.description", default: "Sync chat messages with Slack channels"),
52
+ routes: CollavreSlack::Engine.routes.url_helpers,
53
+ creative_menu_partial: "collavre_slack/integrations/modal"
54
+ })
55
+ end
56
+ end
57
+ end
58
+
59
+ # Hook into Comment and CommentReaction to dispatch to Slack
60
+ initializer "collavre_slack.comment_hooks", after: :load_config_initializers do
61
+ Rails.application.config.to_prepare do
62
+ if defined?(Collavre::Comment) && !Collavre::Comment.included_modules.include?(CollavreSlack::SlackDispatchable)
63
+ Collavre::Comment.include(CollavreSlack::SlackDispatchable)
64
+ Rails.logger.info("[CollavreSlack] SlackDispatchable included in Collavre::Comment")
65
+ end
66
+
67
+ if defined?(Collavre::CommentReaction) && !Collavre::CommentReaction.included_modules.include?(CollavreSlack::SlackReactionDispatchable)
68
+ Collavre::CommentReaction.include(CollavreSlack::SlackReactionDispatchable)
69
+ Rails.logger.info("[CollavreSlack] SlackReactionDispatchable included in Collavre::CommentReaction")
70
+ end
71
+ end
72
+ end
73
+
74
+ # Extend User model with Slack associations for proper cleanup on user deletion
75
+ initializer "collavre_slack.user_associations", after: :load_config_initializers do
76
+ Rails.application.config.to_prepare do
77
+ user_class = Collavre.user_class rescue nil
78
+ next unless user_class
79
+
80
+ unless user_class.reflect_on_association(:slack_accounts)
81
+ user_class.has_many :slack_accounts,
82
+ class_name: "CollavreSlack::SlackAccount",
83
+ dependent: :destroy
84
+ Rails.logger.info("[CollavreSlack] Added slack_accounts association to #{user_class.name}")
85
+ end
86
+
87
+ unless user_class.reflect_on_association(:slack_user_mappings)
88
+ user_class.has_many :slack_user_mappings,
89
+ class_name: "CollavreSlack::SlackUserMapping",
90
+ foreign_key: :collavre_user_id,
91
+ dependent: :destroy
92
+ Rails.logger.info("[CollavreSlack] Added slack_user_mappings association to #{user_class.name}")
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,3 @@
1
+ module CollavreSlack
2
+ VERSION = "0.2.0"
3
+ end
@@ -0,0 +1,13 @@
1
+ require "collavre_slack/version"
2
+ require "collavre_slack/configuration"
3
+ require "collavre_slack/engine"
4
+
5
+ module CollavreSlack
6
+ def self.config
7
+ @config ||= Configuration.new
8
+ end
9
+
10
+ def self.configure
11
+ yield(config)
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,151 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: collavre_slack
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Collavre
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: rails
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '8.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '8.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: collavre
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: faraday
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: faraday-retry
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ description: Plugin engine to connect Collavre creatives with Slack channels and sync
69
+ chat messages.
70
+ email:
71
+ - support@collavre.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - README.md
77
+ - Rakefile
78
+ - app/assets/stylesheets/collavre_slack/slack_integration.css
79
+ - app/controllers/collavre_slack/application_controller.rb
80
+ - app/controllers/collavre_slack/creatives/slack_integrations_controller.rb
81
+ - app/controllers/collavre_slack/slack_auth_controller.rb
82
+ - app/controllers/collavre_slack/slack_events_controller.rb
83
+ - app/controllers/collavre_slack/slack_messages_controller.rb
84
+ - app/javascript/collavre_slack.js
85
+ - app/jobs/collavre_slack/application_job.rb
86
+ - app/jobs/collavre_slack/slack_channel_sync_job.rb
87
+ - app/jobs/collavre_slack/slack_inbound_message_delete_job.rb
88
+ - app/jobs/collavre_slack/slack_inbound_message_job.rb
89
+ - app/jobs/collavre_slack/slack_inbound_message_update_job.rb
90
+ - app/jobs/collavre_slack/slack_inbound_reaction_job.rb
91
+ - app/jobs/collavre_slack/slack_message_delete_job.rb
92
+ - app/jobs/collavre_slack/slack_message_job.rb
93
+ - app/jobs/collavre_slack/slack_message_update_job.rb
94
+ - app/jobs/collavre_slack/slack_reaction_job.rb
95
+ - app/models/collavre_slack/application_record.rb
96
+ - app/models/collavre_slack/slack_account.rb
97
+ - app/models/collavre_slack/slack_channel_link.rb
98
+ - app/models/collavre_slack/slack_comment_link.rb
99
+ - app/models/collavre_slack/slack_message_log.rb
100
+ - app/models/collavre_slack/slack_user_mapping.rb
101
+ - app/models/concerns/collavre_slack/slack_dispatchable.rb
102
+ - app/models/concerns/collavre_slack/slack_reaction_dispatchable.rb
103
+ - app/services/collavre_slack/emoji_mapping.rb
104
+ - app/services/collavre_slack/mention_mapping.rb
105
+ - app/services/collavre_slack/slack_client.rb
106
+ - app/services/collavre_slack/slack_event_handler.rb
107
+ - app/services/collavre_slack/slack_integration_service.rb
108
+ - app/services/collavre_slack/slack_message_dispatcher.rb
109
+ - app/views/collavre_slack/creatives/slack_integrations/index.html.erb
110
+ - app/views/collavre_slack/integrations/_modal.html.erb
111
+ - config/initializers/collavre_slack.rb
112
+ - config/locales/en.yml
113
+ - config/locales/ko.yml
114
+ - config/routes.rb
115
+ - db/migrate/20250201000001_create_slack_accounts.rb
116
+ - db/migrate/20250201000002_create_slack_channel_links.rb
117
+ - db/migrate/20250201000003_create_slack_user_mappings.rb
118
+ - db/migrate/20250201000004_create_slack_message_logs.rb
119
+ - db/migrate/20250201000005_add_last_synced_at_to_slack_channel_links.rb
120
+ - db/migrate/20260130010000_create_slack_comment_links.rb
121
+ - db/migrate/20260130010001_add_comment_id_to_slack_message_logs.rb
122
+ - db/migrate/20260130020000_add_cascade_delete_to_slack_comment_foreign_keys.rb
123
+ - db/migrate/20260131000000_remove_is_active_from_slack_channel_links.rb
124
+ - lib/collavre_slack.rb
125
+ - lib/collavre_slack/configuration.rb
126
+ - lib/collavre_slack/engine.rb
127
+ - lib/collavre_slack/version.rb
128
+ homepage: https://collavre.com
129
+ licenses:
130
+ - AGPL
131
+ metadata:
132
+ homepage_uri: https://collavre.com
133
+ source_code_uri: https://github.com/sh1nj1/plan42
134
+ rdoc_options: []
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ requirements: []
148
+ rubygems_version: 3.6.7
149
+ specification_version: 4
150
+ summary: Slack integration for Collavre
151
+ test_files: []