diff --git a/lib/discourse_chat/provider/slack/slack_command_controller.rb b/lib/discourse_chat/provider/slack/slack_command_controller.rb index 5975092..7eb8ca3 100644 --- a/lib/discourse_chat/provider/slack/slack_command_controller.rb +++ b/lib/discourse_chat/provider/slack/slack_command_controller.rb @@ -22,7 +22,7 @@ module DiscourseChat::Provider::SlackProvider tokens = params[:text].split(" ") # channel name fix - channel = + channel_id = case params[:channel_name] when 'directmessage' "@#{params[:user_name]}" @@ -34,6 +34,11 @@ module DiscourseChat::Provider::SlackProvider provider = DiscourseChat::Provider::SlackProvider::PROVIDER_NAME + channel = DiscourseChat::Channel.with_provider(provider).with_data_value('identifier',channel_id).first + + # Create channel if doesn't exist + channel ||= DiscourseChat::Channel.create!(provider:provider, data:{identifier: channel_id}) + cmd = tokens.shift if tokens.size >= 1 error_text = I18n.t("chat_integration.provider.slack.parse_error") @@ -72,7 +77,7 @@ module DiscourseChat::Provider::SlackProvider end category_id = category.nil? ? nil : category.id - case DiscourseChat::Helper.smart_create_rule(provider: provider, channel:channel, filter:cmd, category_id: category_id, tags:tags) + case DiscourseChat::Helper.smart_create_rule(channel:channel, filter:cmd, category_id: category_id, tags:tags) when :created return I18n.t("chat_integration.provider.slack.create.created") when :updated @@ -86,13 +91,13 @@ module DiscourseChat::Provider::SlackProvider rule_number = tokens[0].to_i return error_text unless rule_number.to_s == tokens[0] # Check we were given a number - if DiscourseChat::Helper.delete_by_index(provider, channel, rule_number) + if DiscourseChat::Helper.delete_by_index(channel, rule_number) return I18n.t("chat_integration.provider.slack.delete.success") else return I18n.t("chat_integration.provider.slack.delete.error") end when "status" - return DiscourseChat::Helper.status_for_channel(provider, channel) + return DiscourseChat::Helper.status_for_channel(channel) when "help" return I18n.t("chat_integration.provider.slack.help") else diff --git a/lib/discourse_chat/provider/slack/slack_provider.rb b/lib/discourse_chat/provider/slack/slack_provider.rb index dbd3afe..b212739 100644 --- a/lib/discourse_chat/provider/slack/slack_provider.rb +++ b/lib/discourse_chat/provider/slack/slack_provider.rb @@ -3,7 +3,7 @@ module DiscourseChat::Provider::SlackProvider PROVIDER_ENABLED_SETTING = :chat_integration_slack_enabled - CHANNEL_PARAMETERS = {"channel" => '^[@#]\S*$'} + CHANNEL_PARAMETERS = {"identifier" => '^[@#]\S*$'} def self.excerpt(post, max_length = SiteSetting.chat_integration_slack_excerpt_length) doc = Nokogiri::HTML.fragment(post.excerpt(max_length, @@ -137,12 +137,13 @@ module DiscourseChat::Provider::SlackProvider end def self.trigger_notification(post, channel) - message = slack_message(post, channel) + channel_id = channel.data['identifier'] + message = slack_message(post, channel_id) if SiteSetting.chat_integration_slack_access_token.empty? self.send_via_webhook(message) else - self.send_via_api(post, channel, message) + self.send_via_api(post, channel_id, message) end end diff --git a/spec/lib/discourse_chat/provider/slack/slack_command_controller_spec.rb b/spec/lib/discourse_chat/provider/slack/slack_command_controller_spec.rb index 11d00a0..bc4e9f7 100644 --- a/spec/lib/discourse_chat/provider/slack/slack_command_controller_spec.rb +++ b/spec/lib/discourse_chat/provider/slack/slack_command_controller_spec.rb @@ -4,6 +4,7 @@ describe 'Slack Command Controller', type: :request do let(:category) { Fabricate(:category) } let(:tag) { Fabricate(:tag) } let(:tag2) { Fabricate(:tag) } + let!(:chan1){DiscourseChat::Channel.create!(provider:'slack', data:{identifier: '#welcome'})} describe 'with plugin disabled' do it 'should return a 404' do @@ -24,8 +25,6 @@ describe 'Slack Command Controller', type: :request do end end - - describe 'slash commands endpoint' do before do SiteSetting.chat_integration_enabled = true @@ -82,8 +81,7 @@ describe 'Slack Command Controller', type: :request do expect(json["text"]).to eq(I18n.t("chat_integration.provider.slack.create.created")) rule = DiscourseChat::Rule.all.first - expect(rule.provider).to eq('slack') - expect(rule.channel).to eq('#welcome') + expect(rule.channel).to eq(chan1) expect(rule.filter).to eq('watch') expect(rule.category_id).to eq(category.id) expect(rule.tags).to eq(nil) @@ -144,8 +142,7 @@ describe 'Slack Command Controller', type: :request do expect(json["text"]).to eq(I18n.t("chat_integration.provider.slack.create.created")) rule = DiscourseChat::Rule.all.first - expect(rule.provider).to eq('slack') - expect(rule.channel).to eq('#welcome') + expect(rule.channel).to eq(chan1) expect(rule.filter).to eq('watch') expect(rule.category_id).to eq(nil) expect(rule.tags).to eq([tag.name]) @@ -164,8 +161,7 @@ describe 'Slack Command Controller', type: :request do expect(json["text"]).to eq(I18n.t("chat_integration.provider.slack.create.created")) rule = DiscourseChat::Rule.all.first - expect(rule.provider).to eq('slack') - expect(rule.channel).to eq('#welcome') + expect(rule.channel).to eq(chan1) expect(rule.filter).to eq('watch') expect(rule.category_id).to eq(category.id) expect(rule.tags).to contain_exactly(tag.name, tag2.name) @@ -184,16 +180,36 @@ describe 'Slack Command Controller', type: :request do expect(json["text"]).to eq(I18n.t("chat_integration.provider.slack.not_found.tag", name:"blah")) end end + + context 'from an unknown channel' do + it 'creates the channel' do + post "/chat-integration/slack/command.json", + text: "watch #{category.slug}", + channel_name: 'general', + token: token + + json = JSON.parse(response.body) + + expect(json["text"]).to eq(I18n.t("chat_integration.provider.slack.create.created")) + + chan = DiscourseChat::Channel.with_provider('slack').with_data_value('identifier','#general').first + expect(chan.provider).to eq('slack') + + rule = chan.rules.first + expect(rule.filter).to eq('watch') + expect(rule.category_id).to eq(category.id) + expect(rule.tags).to eq(nil) + end + end end describe 'remove rule' do it 'removes the rule' do - rule1 = DiscourseChat::Rule.new({provider: 'slack', - channel: '#welcome', - filter: 'watch', - category_id: category.id, - tags: [tag.name, tag2.name] - }).save! + rule1 = DiscourseChat::Rule.create(channel: chan1, + filter: 'watch', + category_id: category.id, + tags: [tag.name, tag2.name] + ) expect(DiscourseChat::Rule.all.size).to eq(1) post "/chat-integration/slack/command.json", @@ -250,7 +266,7 @@ describe 'Slack Command Controller', type: :request do json = JSON.parse(response.body) - expect(json["text"]).to eq(DiscourseChat::Helper.status_for_channel('slack','#welcome')) + expect(json["text"]).to eq(DiscourseChat::Helper.status_for_channel(chan1)) end end diff --git a/spec/lib/discourse_chat/provider/slack/slack_provider_spec.rb b/spec/lib/discourse_chat/provider/slack/slack_provider_spec.rb index 7a93862..6295d50 100644 --- a/spec/lib/discourse_chat/provider/slack/slack_provider_spec.rb +++ b/spec/lib/discourse_chat/provider/slack/slack_provider_spec.rb @@ -57,16 +57,18 @@ RSpec.describe DiscourseChat::Provider::SlackProvider do SiteSetting.chat_integration_slack_enabled = true end + let(:chan1){DiscourseChat::Channel.create!(provider:'slack', data:{identifier: '#general'})} + it 'sends a webhook request' do stub1 = stub_request(:post, SiteSetting.chat_integration_slack_outbound_webhook_url).to_return(body: "success") - described_class.trigger_notification(post, '#general') + described_class.trigger_notification(post, chan1) expect(stub1).to have_been_requested.once end it 'handles errors correctly' do stub1 = stub_request(:post, SiteSetting.chat_integration_slack_outbound_webhook_url).to_return(status: 400, body: "error") expect(stub1).to have_been_requested.times(0) - expect{described_class.trigger_notification(post, '#general')}.to raise_exception(::DiscourseChat::ProviderError) + expect{described_class.trigger_notification(post, chan1)}.to raise_exception(::DiscourseChat::ProviderError) expect(stub1).to have_been_requested.once end @@ -81,14 +83,14 @@ RSpec.describe DiscourseChat::Provider::SlackProvider do it 'sends an api request' do expect(@stub2).to have_been_requested.times(0) - described_class.trigger_notification(post, '#general') + described_class.trigger_notification(post, chan1) expect(@stub1).to have_been_requested.times(0) expect(@stub2).to have_been_requested.once end it 'handles errors correctly' do @stub2 = stub_request(:post, %r{https://slack.com/api/chat.postMessage}).to_return(body: "{\"ok\":false }", headers: {'Content-Type' => 'application/json'}) - expect{described_class.trigger_notification(post, '#general')}.to raise_exception(::DiscourseChat::ProviderError) + expect{described_class.trigger_notification(post, chan1)}.to raise_exception(::DiscourseChat::ProviderError) expect(@stub2).to have_been_requested.once end @@ -97,8 +99,8 @@ RSpec.describe DiscourseChat::Provider::SlackProvider do expect(@stub2).to have_been_requested.times(0) expect(@stub3).to have_been_requested.times(0) - described_class.trigger_notification(post, '#general') - described_class.trigger_notification(second_post, '#general') + described_class.trigger_notification(post, chan1) + described_class.trigger_notification(second_post, chan1) expect(@stub1).to have_been_requested.times(0) expect(@stub2).to have_been_requested.once # Initial creation of message expect(@stub3).to have_been_requested.once # Requests to update the existing message