diff --git a/config/settings.yml b/config/settings.yml index 2709ce3..5801b22 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -4,4 +4,22 @@ plugins: chat_discourse_username: default: system chat_delay_seconds: - default: 20 \ No newline at end of file + default: 20 + +####################################### +########## SLACK SETTINGS ############# +####################################### + chat_slack_enabled: + default: false + chat_slack_outbound_webhook_url: + default: '' + chat_slack_discourse_excerpt_length: + default: 400 + chat_slack_icon_url: + default: '' + +####################################### +######### TELEGRAM SETTINGS ########### +####################################### + chat_telegram_enabled: + default: false diff --git a/lib/discourse_chat/provider/slack/slack_message_formatter.rb b/lib/discourse_chat/provider/slack/slack_message_formatter.rb new file mode 100644 index 0000000..e1bcbae --- /dev/null +++ b/lib/discourse_chat/provider/slack/slack_message_formatter.rb @@ -0,0 +1,49 @@ +module DiscourseChat::Provider::SlackProvider + class SlackMessageFormatter < Nokogiri::XML::SAX::Document + attr_reader :excerpt + + def initialize + @excerpt = "" + end + + def self.format(html = '') + me = self.new + parser = Nokogiri::HTML::SAX::Parser.new(me) + parser.parse(html) + me.excerpt + end + + def start_element(name, attributes = []) + case name + when "a" + attributes = Hash[*attributes.flatten] + @in_a = true + @excerpt << "<#{absolute_url(attributes['href'])}|" + end + end + + def end_element(name) + case name + when "a" + @excerpt << ">" + @in_a = false + end + end + + def characters(string) + string.strip! if @in_a + @excerpt << string + end + + private + + def absolute_url(url) + uri = URI(url) rescue nil + + return Discourse.current_hostname unless uri + uri.host = Discourse.current_hostname if !uri.host + uri.scheme = (SiteSetting.force_https ? 'https' : 'http') if !uri.scheme + uri.to_s + end + end +end diff --git a/lib/discourse_chat/provider/slack/slack_provider.rb b/lib/discourse_chat/provider/slack/slack_provider.rb index ebc16e4..19e5676 100644 --- a/lib/discourse_chat/provider/slack/slack_provider.rb +++ b/lib/discourse_chat/provider/slack/slack_provider.rb @@ -1,7 +1,71 @@ -module DiscourseChat - module Provider - module SlackProvider - PROVIDER_NAME = "slack".freeze +module DiscourseChat::Provider::SlackProvider + PROVIDER_NAME = "slack".freeze + + def self.excerpt(post, max_length = SiteSetting.chat_slack_discourse_excerpt_length) + doc = Nokogiri::HTML.fragment(post.excerpt(max_length, + remap_emoji: true, + keep_onebox_source: true + )) + + SlackMessageFormatter.format(doc.to_html) + end + + def self.slack_message(post, channel) + display_name = "@#{post.user.username}" + full_name = post.user.name || "" + + if !(full_name.strip.empty?) && (full_name.strip.gsub(' ', '_').casecmp(post.user.username) != 0) && (full_name.strip.gsub(' ', '').casecmp(post.user.username) != 0) + display_name = "#{full_name} @#{post.user.username}" end + + topic = post.topic + + category = (topic.category.parent_category) ? "[#{topic.category.parent_category.name}/#{topic.category.name}]": "[#{topic.category.name}]" + + icon_url = + if !SiteSetting.chat_slack_icon_url.blank? + "#{Discourse.base_url}#{SiteSetting.chat_slack_icon_url}" + elsif !SiteSetting.logo_small_url.blank? + "#{Discourse.base_url}#{SiteSetting.logo_small_url}" + end + + message = { + channel: channel, + username: SiteSetting.title, + icon_url: icon_url, + attachments: [] + } + + summary = { + fallback: "#{topic.title} - #{display_name}", + author_name: display_name, + author_icon: post.user.small_avatar_url, + color: "##{topic.category.color}", + text: ::DiscourseSlack::Slack.excerpt(post), + mrkdwn_in: ["text"] + } + + record = ::PluginStore.get(DiscourseSlack::PLUGIN_NAME, "topic_#{post.topic.id}_#{channel}") + + if (SiteSetting.slack_access_token.empty? || post.is_first_post? || record.blank? || (record.present? && ((Time.now.to_i - record[:ts].split('.')[0].to_i)/ 60) >= 5 )) + summary[:title] = "#{topic.title} #{(category == '[uncategorized]')? '' : category} #{topic.tags.present? ? topic.tags.map(&:name).join(', ') : ''}" + summary[:title_link] = post.full_url + summary[:thumb_url] = post.full_url + end + + message[:attachments].push(summary) + message + end + + def self.trigger_notification(post, channel) + message = slack_message(post, channel) + + http = Net::HTTP.new("hooks.slack.com", 443) + http.use_ssl = true + + req = Net::HTTP::Post.new(URI(SiteSetting.slack_outbound_webhook_url), 'Content-Type' =>'application/json') + req.body = message.to_json + response = http.request(req) + end end \ No newline at end of file