diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 5ce7063..70934e9 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -78,7 +78,7 @@ en: errors: action_prohibited: "The bot does not have permission to post to that channel" channel_not_found: "The specified channel does not exist on slack" - + ####################################### ########## TELEGRAM STRINGS ########### ####################################### @@ -178,3 +178,16 @@ en: help: "e.g. #channel, @username." errors: invalid_channel: "That channel does not exist on Rocket Chat" + + ####################################### + ############ GITTER STRINGS ########### + ####################################### + gitter: + title: "Gitter" + param: + name: + title: "Name" + help: "A Gitter room's name e.g. gitterHQ/services." + webhook_url: + title: "Webhook URL" + help: "The URL provided when you create a new integration in a Gitter room." diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 3ec459c..0b05905 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -72,8 +72,13 @@ en: chat_integration_rocketchat_webhook_url: "The URL for the Rocket Chat integration webhook" chat_integration_rocketchat_excerpt_length: "Rocket Chat post excerpt length" + ####################################### + ############ GITTER SETTINGS ########## + ####################################### + chat_integration_gitter_enabled: "Enable the Gitter chat integration provider" + chat_integration: - + all_categories: "(all categories)" deleted_category: "(deleted category)" deleted_group: "(deleted group)" @@ -116,7 +121,7 @@ en: (`[rule number]` can be found by running `/discourse status`) *List rules:* `/discourse status` - + *Post transcript:* `/discourse post [n]` Create a draft topic on discourse containing the last `n` posts in this channel @@ -172,7 +177,7 @@ en: ([rule number] can be found by running /status) List rules: /status - + Help: /help ####################################### @@ -214,7 +219,7 @@ en: (`[rule number]` can be found by running `/discourse status`) *List rules:* `/discourse status` - + *Help:* `/discourse help` ####################################### diff --git a/config/settings.yml b/config/settings.yml index fa5b04a..fabc62d 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -108,3 +108,9 @@ plugins: default: '' chat_integration_rocketchat_excerpt_length: default: 400 + +####################################### +########## GITTER SETTINGS ############ +####################################### + chat_integration_gitter_enabled: + default: false diff --git a/lib/discourse_chat/provider.rb b/lib/discourse_chat/provider.rb index 981acd3..6bbf5c2 100644 --- a/lib/discourse_chat/provider.rb +++ b/lib/discourse_chat/provider.rb @@ -97,3 +97,4 @@ require_relative "provider/mattermost/mattermost_provider.rb" require_relative "provider/matrix/matrix_provider.rb" require_relative "provider/zulip/zulip_provider.rb" require_relative "provider/rocketchat/rocketchat_provider.rb" +require_relative "provider/gitter/gitter_provider.rb" diff --git a/lib/discourse_chat/provider/gitter/gitter_provider.rb b/lib/discourse_chat/provider/gitter/gitter_provider.rb new file mode 100644 index 0000000..a4308c5 --- /dev/null +++ b/lib/discourse_chat/provider/gitter/gitter_provider.rb @@ -0,0 +1,30 @@ +module DiscourseChat + module Provider + module GitterProvider + PROVIDER_NAME = 'gitter'.freeze + PROVIDER_ENABLED_SETTING = :chat_integration_gitter_enabled + CHANNEL_PARAMETERS = [ + { key: "name", regex: '^\S+$', unique: true }, + { key: "webhook_url", regex: '^https://webhooks.gitter.im/e/\S+$', unique: true, hidden: true } + ] + + def self.trigger_notification(post, channel) + message = gitter_message(post) + response = Net::HTTP.post_form(URI(channel.data['webhook_url']), message: message) + unless response.kind_of? Net::HTTPSuccess + error_key = nil + raise ::DiscourseChat::ProviderError.new info: { error_key: error_key, message: message, response_body: response.body } + end + end + + def self.gitter_message(post) + display_name = post.user.username + topic = post.topic + parent_category = topic.category.try :parent_category + category_name = parent_category ? "[#{parent_category.name}/#{topic.category.name}]" : "[#{topic.category.name}]" + + "[__#{display_name}__ - #{topic.title} - #{category_name}](#{post.full_url})" + end + end + end +end diff --git a/spec/lib/discourse_chat/provider/gitter/gitter_provider_spec.rb b/spec/lib/discourse_chat/provider/gitter/gitter_provider_spec.rb new file mode 100644 index 0000000..665b4cf --- /dev/null +++ b/spec/lib/discourse_chat/provider/gitter/gitter_provider_spec.rb @@ -0,0 +1,26 @@ +require 'rails_helper' + +RSpec.describe DiscourseChat::Provider::GitterProvider do + let(:post) { Fabricate(:post) } + + describe '.trigger_notifications' do + before do + SiteSetting.chat_integration_gitter_enabled = true + end + + let(:chan1) { DiscourseChat::Channel.create!(provider: 'gitter', data: { name: 'gitterHQ/services', webhook_url: 'https://webhooks.gitter.im/e/a1e2i3o4u5' }) } + + it 'sends a webhook request' do + stub1 = stub_request(:post, chan1.data['webhook_url']).to_return(body: "OK") + described_class.trigger_notification(post, chan1) + expect(stub1).to have_been_requested.once + end + + it 'handles errors correctly' do + stub1 = stub_request(:post, chan1.data['webhook_url']).to_return(status: 404, body: "{ \"error\": \"Not Found\"}") + expect(stub1).to have_been_requested.times(0) + expect { described_class.trigger_notification(post, chan1) }.to raise_exception(::DiscourseChat::ProviderError) + expect(stub1).to have_been_requested.once + end + end +end