slack-notifier 1.5.1 → 2.0.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.
- checksums.yaml +4 -4
 - data/lib/slack-notifier.rb +35 -60
 - data/lib/slack-notifier/config.rb +37 -0
 - data/lib/slack-notifier/payload_middleware.rb +21 -0
 - data/lib/slack-notifier/payload_middleware/base.rb +35 -0
 - data/lib/slack-notifier/payload_middleware/format_attachments.rb +37 -0
 - data/lib/slack-notifier/payload_middleware/format_message.rb +19 -0
 - data/lib/slack-notifier/payload_middleware/stack.rb +35 -0
 - data/lib/slack-notifier/util/escape.rb +15 -0
 - data/lib/slack-notifier/util/http_client.rb +53 -0
 - data/lib/slack-notifier/util/link_formatter.rb +63 -0
 - data/lib/slack-notifier/version.rb +2 -1
 - data/spec/end_to_end_spec.rb +84 -0
 - data/spec/integration/ping_integration_test.rb +12 -5
 - data/spec/lib/slack-notifier/config_spec.rb +71 -0
 - data/spec/lib/slack-notifier/payload_middleware/base_spec.rb +75 -0
 - data/spec/lib/slack-notifier/payload_middleware/format_attachments_spec.rb +35 -0
 - data/spec/lib/slack-notifier/payload_middleware/format_message_spec.rb +26 -0
 - data/spec/lib/slack-notifier/payload_middleware/stack_spec.rb +93 -0
 - data/spec/lib/slack-notifier/payload_middleware_spec.rb +32 -0
 - data/spec/lib/slack-notifier/util/http_client_spec.rb +34 -0
 - data/spec/lib/slack-notifier/{link_formatter_spec.rb → util/link_formatter_spec.rb} +30 -19
 - data/spec/lib/slack-notifier_spec.rb +62 -128
 - data/spec/spec_helper.rb +20 -5
 - metadata +30 -9
 - data/lib/slack-notifier/default_http_client.rb +0 -51
 - data/lib/slack-notifier/link_formatter.rb +0 -62
 - data/spec/lib/slack-notifier/default_http_client_spec.rb +0 -37
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 47af99d5a1eeca46a62425be8842bc6ff89d9d51
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 3d0519d10cb7a251a49b32b0d27b2e0616f08c54
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 0d9a915eb0ebc25b3d1d4042055419cf8628404cf9282fffa41a4f4dfada1eb8aac4c02c9b7415226895a160ee326f0c82d048fa84ede13f829dac19130b2cc8
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 314a2d7812c2d699f201753e15fbcd6c34c778f863123f2e70e7731d8753a338e984bbcb3dd4cd125f01509990b79fc84ac8a3b7daf5b2e70f5484c66cede356
         
     | 
    
        data/lib/slack-notifier.rb
    CHANGED
    
    | 
         @@ -1,81 +1,56 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
            require  
     | 
| 
       3 
     | 
    
         
            -
            require  
     | 
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "uri"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "json"
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
            require_relative  
     | 
| 
       6 
     | 
    
         
            -
            require_relative  
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative "slack-notifier/util/http_client"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require_relative "slack-notifier/util/link_formatter"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require_relative "slack-notifier/util/escape"
         
     | 
| 
      
 8 
     | 
    
         
            +
            require_relative "slack-notifier/payload_middleware"
         
     | 
| 
      
 9 
     | 
    
         
            +
            require_relative "slack-notifier/config"
         
     | 
| 
       7 
10 
     | 
    
         | 
| 
       8 
11 
     | 
    
         
             
            module Slack
         
     | 
| 
       9 
12 
     | 
    
         
             
              class Notifier
         
     | 
| 
       10 
     | 
    
         
            -
                attr_reader :endpoint 
     | 
| 
      
 13 
     | 
    
         
            +
                attr_reader :endpoint
         
     | 
| 
       11 
14 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
                def initialize webhook_url, options={}
         
     | 
| 
       13 
     | 
    
         
            -
                  @endpoint 
     | 
| 
       14 
     | 
    
         
            -
                  @default_payload = options
         
     | 
| 
       15 
     | 
    
         
            -
                end
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
                def ping message, options={}
         
     | 
| 
       18 
     | 
    
         
            -
                  if message.is_a?(Hash)
         
     | 
| 
       19 
     | 
    
         
            -
                    message, options = nil, message
         
     | 
| 
       20 
     | 
    
         
            -
                  end
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                  if attachments = options[:attachments] || options["attachments"]
         
     | 
| 
       23 
     | 
    
         
            -
                    wrap_array(attachments).each do |attachment|
         
     | 
| 
       24 
     | 
    
         
            -
                      ["text", :text].each do |key|
         
     | 
| 
       25 
     | 
    
         
            -
                        attachment[key] = LinkFormatter.format(attachment[key]) if attachment.has_key?(key)
         
     | 
| 
       26 
     | 
    
         
            -
                      end
         
     | 
| 
       27 
     | 
    
         
            -
                    end
         
     | 
| 
       28 
     | 
    
         
            -
                  end
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                  payload      = default_payload.merge(options)
         
     | 
| 
       31 
     | 
    
         
            -
                  client       = payload.delete(:http_client) || http_client
         
     | 
| 
       32 
     | 
    
         
            -
                  http_options = payload.delete(:http_options)
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                  unless message.nil?
         
     | 
| 
       35 
     | 
    
         
            -
                    payload.merge!(text: LinkFormatter.format(message))
         
     | 
| 
       36 
     | 
    
         
            -
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
                def initialize webhook_url, options={}, &block
         
     | 
| 
      
 16 
     | 
    
         
            +
                  @endpoint = URI.parse webhook_url
         
     | 
| 
       37 
17 
     | 
    
         | 
| 
       38 
     | 
    
         
            -
                   
     | 
| 
       39 
     | 
    
         
            -
                   
     | 
| 
      
 18 
     | 
    
         
            +
                  config.http_client(options.delete(:http_client)) if options.key?(:http_client)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  config.defaults options
         
     | 
| 
      
 20 
     | 
    
         
            +
                  config.instance_exec(&block) if block_given?
         
     | 
| 
       40 
21 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
                   
     | 
| 
      
 22 
     | 
    
         
            +
                  middleware.set config.middleware
         
     | 
| 
       42 
23 
     | 
    
         
             
                end
         
     | 
| 
       43 
24 
     | 
    
         | 
| 
       44 
     | 
    
         
            -
                def  
     | 
| 
       45 
     | 
    
         
            -
                   
     | 
| 
      
 25 
     | 
    
         
            +
                def config
         
     | 
| 
      
 26 
     | 
    
         
            +
                  @_config ||= Config.new
         
     | 
| 
       46 
27 
     | 
    
         
             
                end
         
     | 
| 
       47 
28 
     | 
    
         | 
| 
       48 
     | 
    
         
            -
                def  
     | 
| 
       49 
     | 
    
         
            -
                   
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
      
 29 
     | 
    
         
            +
                def ping message, options={}
         
     | 
| 
      
 30 
     | 
    
         
            +
                  if message.is_a?(Hash)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    options = message
         
     | 
| 
      
 32 
     | 
    
         
            +
                  else
         
     | 
| 
      
 33 
     | 
    
         
            +
                    options[:text] = message
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
       51 
35 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
                  default_payload[:channel] = channel
         
     | 
| 
      
 36 
     | 
    
         
            +
                  post options
         
     | 
| 
       54 
37 
     | 
    
         
             
                end
         
     | 
| 
       55 
38 
     | 
    
         | 
| 
       56 
     | 
    
         
            -
                def  
     | 
| 
       57 
     | 
    
         
            -
                   
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
      
 39 
     | 
    
         
            +
                def post payload={}
         
     | 
| 
      
 40 
     | 
    
         
            +
                  params  = {}
         
     | 
| 
      
 41 
     | 
    
         
            +
                  client  = payload.delete(:http_client) || config.http_client
         
     | 
| 
      
 42 
     | 
    
         
            +
                  payload = config.defaults.merge(payload)
         
     | 
| 
       59 
43 
     | 
    
         | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
                   
     | 
| 
       62 
     | 
    
         
            -
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
                  params[:http_options] = payload.delete(:http_options) if payload.key?(:http_options)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  params[:payload]      = middleware.call(payload).to_json
         
     | 
| 
       63 
46 
     | 
    
         | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
                HTML_ESCAPE = { '&' => '&',  '>' => '>',   '<' => '<' }
         
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
                def escape(text)
         
     | 
| 
       68 
     | 
    
         
            -
                  text.gsub(HTML_ESCAPE_REGEXP, HTML_ESCAPE)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  client.post endpoint, params
         
     | 
| 
       69 
48 
     | 
    
         
             
                end
         
     | 
| 
       70 
49 
     | 
    
         | 
| 
       71 
     | 
    
         
            -
                 
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
                    object.to_ary || [object]
         
     | 
| 
       76 
     | 
    
         
            -
                  else
         
     | 
| 
       77 
     | 
    
         
            -
                    [object]
         
     | 
| 
      
 50 
     | 
    
         
            +
                private
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                  def middleware
         
     | 
| 
      
 53 
     | 
    
         
            +
                    @middleware ||= PayloadMiddleware::Stack.new(self)
         
     | 
| 
       78 
54 
     | 
    
         
             
                  end
         
     | 
| 
       79 
     | 
    
         
            -
                end
         
     | 
| 
       80 
55 
     | 
    
         
             
              end
         
     | 
| 
       81 
56 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,37 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            module Slack
         
     | 
| 
      
 3 
     | 
    
         
            +
              class Notifier
         
     | 
| 
      
 4 
     | 
    
         
            +
                class Config
         
     | 
| 
      
 5 
     | 
    
         
            +
                  def initialize
         
     | 
| 
      
 6 
     | 
    
         
            +
                    @http_client = Util::HTTPClient
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @defaults    = {}
         
     | 
| 
      
 8 
     | 
    
         
            +
                    @middleware  = [:format_message, :format_attachments]
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  def http_client client=nil
         
     | 
| 
      
 12 
     | 
    
         
            +
                    return @http_client if client.nil?
         
     | 
| 
      
 13 
     | 
    
         
            +
                    raise ArgumentError, "the http client must respond to ::post" unless client.respond_to?(:post)
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    @http_client = client
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def defaults new_defaults=nil
         
     | 
| 
      
 19 
     | 
    
         
            +
                    return @defaults if new_defaults.nil?
         
     | 
| 
      
 20 
     | 
    
         
            +
                    raise ArgumentError, "the defaults must be a Hash" unless new_defaults.is_a?(Hash)
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                    @defaults = new_defaults
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  def middleware *args
         
     | 
| 
      
 26 
     | 
    
         
            +
                    return @middleware if args.empty?
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                    @middleware =
         
     | 
| 
      
 29 
     | 
    
         
            +
                      if args.length == 1 && args.first.is_a?(Array) || args.first.is_a?(Hash)
         
     | 
| 
      
 30 
     | 
    
         
            +
                        args.first
         
     | 
| 
      
 31 
     | 
    
         
            +
                      else
         
     | 
| 
      
 32 
     | 
    
         
            +
                        args
         
     | 
| 
      
 33 
     | 
    
         
            +
                      end
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            module Slack
         
     | 
| 
      
 3 
     | 
    
         
            +
              class Notifier
         
     | 
| 
      
 4 
     | 
    
         
            +
                class PayloadMiddleware
         
     | 
| 
      
 5 
     | 
    
         
            +
                  class << self
         
     | 
| 
      
 6 
     | 
    
         
            +
                    def registry
         
     | 
| 
      
 7 
     | 
    
         
            +
                      @registry ||= {}
         
     | 
| 
      
 8 
     | 
    
         
            +
                    end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    def register middleware, name
         
     | 
| 
      
 11 
     | 
    
         
            +
                      registry[name] = middleware
         
     | 
| 
      
 12 
     | 
    
         
            +
                    end
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            require_relative "payload_middleware/stack"
         
     | 
| 
      
 19 
     | 
    
         
            +
            require_relative "payload_middleware/base"
         
     | 
| 
      
 20 
     | 
    
         
            +
            require_relative "payload_middleware/format_message"
         
     | 
| 
      
 21 
     | 
    
         
            +
            require_relative "payload_middleware/format_attachments"
         
     | 
| 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            module Slack
         
     | 
| 
      
 3 
     | 
    
         
            +
              class Notifier
         
     | 
| 
      
 4 
     | 
    
         
            +
                class PayloadMiddleware
         
     | 
| 
      
 5 
     | 
    
         
            +
                  class Base
         
     | 
| 
      
 6 
     | 
    
         
            +
                    class << self
         
     | 
| 
      
 7 
     | 
    
         
            +
                      def middleware_name name
         
     | 
| 
      
 8 
     | 
    
         
            +
                        PayloadMiddleware.register self, name.to_sym
         
     | 
| 
      
 9 
     | 
    
         
            +
                      end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                      def options default_opts
         
     | 
| 
      
 12 
     | 
    
         
            +
                        @default_opts = default_opts
         
     | 
| 
      
 13 
     | 
    
         
            +
                      end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                      def default_opts
         
     | 
| 
      
 16 
     | 
    
         
            +
                        @default_opts ||= {}
         
     | 
| 
      
 17 
     | 
    
         
            +
                      end
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    attr_reader :notifier, :options
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                    def initialize notifier, opts={}
         
     | 
| 
      
 23 
     | 
    
         
            +
                      @notifier = notifier
         
     | 
| 
      
 24 
     | 
    
         
            +
                      @options  = self.class.default_opts.merge opts
         
     | 
| 
      
 25 
     | 
    
         
            +
                    end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                    # rubocop:disable Lint/UnusedMethodArgument
         
     | 
| 
      
 28 
     | 
    
         
            +
                    def call payload={}
         
     | 
| 
      
 29 
     | 
    
         
            +
                      raise NoMethodError, "method `call` not defined for class #{self.class}"
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
                    # rubocop:enable Lint/UnusedMethodArgument
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,37 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            module Slack
         
     | 
| 
      
 3 
     | 
    
         
            +
              class Notifier
         
     | 
| 
      
 4 
     | 
    
         
            +
                class PayloadMiddleware
         
     | 
| 
      
 5 
     | 
    
         
            +
                  class FormatAttachments < Base
         
     | 
| 
      
 6 
     | 
    
         
            +
                    middleware_name :format_attachments
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                    options formats: [:html, :markdown]
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    def call payload={}
         
     | 
| 
      
 11 
     | 
    
         
            +
                      attachments = payload.fetch(:attachments, payload["attachments"])
         
     | 
| 
      
 12 
     | 
    
         
            +
                      wrap_array(attachments).each do |attachment|
         
     | 
| 
      
 13 
     | 
    
         
            +
                        ["text", :text].each do |key|
         
     | 
| 
      
 14 
     | 
    
         
            +
                          if attachment.key?(key)
         
     | 
| 
      
 15 
     | 
    
         
            +
                            attachment[key] = Util::LinkFormatter.format(attachment[key], options)
         
     | 
| 
      
 16 
     | 
    
         
            +
                          end
         
     | 
| 
      
 17 
     | 
    
         
            +
                        end
         
     | 
| 
      
 18 
     | 
    
         
            +
                      end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                      payload
         
     | 
| 
      
 21 
     | 
    
         
            +
                    end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                    private
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                      def wrap_array object
         
     | 
| 
      
 26 
     | 
    
         
            +
                        if object.nil?
         
     | 
| 
      
 27 
     | 
    
         
            +
                          []
         
     | 
| 
      
 28 
     | 
    
         
            +
                        elsif object.respond_to?(:to_ary)
         
     | 
| 
      
 29 
     | 
    
         
            +
                          object.to_ary || [object]
         
     | 
| 
      
 30 
     | 
    
         
            +
                        else
         
     | 
| 
      
 31 
     | 
    
         
            +
                          [object]
         
     | 
| 
      
 32 
     | 
    
         
            +
                        end
         
     | 
| 
      
 33 
     | 
    
         
            +
                      end
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            module Slack
         
     | 
| 
      
 3 
     | 
    
         
            +
              class Notifier
         
     | 
| 
      
 4 
     | 
    
         
            +
                class PayloadMiddleware
         
     | 
| 
      
 5 
     | 
    
         
            +
                  class FormatMessage < Base
         
     | 
| 
      
 6 
     | 
    
         
            +
                    middleware_name :format_message
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                    options formats: [:html, :markdown]
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    def call payload={}
         
     | 
| 
      
 11 
     | 
    
         
            +
                      return payload unless payload[:text]
         
     | 
| 
      
 12 
     | 
    
         
            +
                      payload[:text] = Util::LinkFormatter.format(payload[:text], options)
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                      payload
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            module Slack
         
     | 
| 
      
 3 
     | 
    
         
            +
              class Notifier
         
     | 
| 
      
 4 
     | 
    
         
            +
                class PayloadMiddleware
         
     | 
| 
      
 5 
     | 
    
         
            +
                  class Stack
         
     | 
| 
      
 6 
     | 
    
         
            +
                    attr_reader :notifier,
         
     | 
| 
      
 7 
     | 
    
         
            +
                                :stack
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                    def initialize notifier
         
     | 
| 
      
 10 
     | 
    
         
            +
                      @notifier = notifier
         
     | 
| 
      
 11 
     | 
    
         
            +
                      @stack    = []
         
     | 
| 
      
 12 
     | 
    
         
            +
                    end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                    def set *middlewares
         
     | 
| 
      
 15 
     | 
    
         
            +
                      middlewares =
         
     | 
| 
      
 16 
     | 
    
         
            +
                        if middlewares.length == 1 && middlewares.first.is_a?(Hash)
         
     | 
| 
      
 17 
     | 
    
         
            +
                          middlewares.first
         
     | 
| 
      
 18 
     | 
    
         
            +
                        else
         
     | 
| 
      
 19 
     | 
    
         
            +
                          middlewares.flatten
         
     | 
| 
      
 20 
     | 
    
         
            +
                        end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                      @stack = middlewares.map do |key, opts|
         
     | 
| 
      
 23 
     | 
    
         
            +
                        PayloadMiddleware.registry.fetch(key).new(*[notifier, opts].compact)
         
     | 
| 
      
 24 
     | 
    
         
            +
                      end
         
     | 
| 
      
 25 
     | 
    
         
            +
                    end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                    def call payload={}
         
     | 
| 
      
 28 
     | 
    
         
            +
                      stack.inject payload do |pld, middleware|
         
     | 
| 
      
 29 
     | 
    
         
            +
                        middleware.call(pld)
         
     | 
| 
      
 30 
     | 
    
         
            +
                      end
         
     | 
| 
      
 31 
     | 
    
         
            +
                    end
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            module Slack
         
     | 
| 
      
 3 
     | 
    
         
            +
              class Notifier
         
     | 
| 
      
 4 
     | 
    
         
            +
                module Util
         
     | 
| 
      
 5 
     | 
    
         
            +
                  module Escape
         
     | 
| 
      
 6 
     | 
    
         
            +
                    HTML_REGEXP  = /[&><]/
         
     | 
| 
      
 7 
     | 
    
         
            +
                    HTML_REPLACE = { "&" => "&", ">" => ">", "<" => "<" }.freeze
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                    def self.html string
         
     | 
| 
      
 10 
     | 
    
         
            +
                      string.gsub(HTML_REGEXP, HTML_REPLACE)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    end
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,53 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "net/http"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module Slack
         
     | 
| 
      
 6 
     | 
    
         
            +
              class Notifier
         
     | 
| 
      
 7 
     | 
    
         
            +
                module Util
         
     | 
| 
      
 8 
     | 
    
         
            +
                  class HTTPClient
         
     | 
| 
      
 9 
     | 
    
         
            +
                    class << self
         
     | 
| 
      
 10 
     | 
    
         
            +
                      def post uri, params
         
     | 
| 
      
 11 
     | 
    
         
            +
                        HTTPClient.new(uri, params).call
         
     | 
| 
      
 12 
     | 
    
         
            +
                      end
         
     | 
| 
      
 13 
     | 
    
         
            +
                    end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    attr_reader :uri, :params, :http_options
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                    def initialize uri, params
         
     | 
| 
      
 18 
     | 
    
         
            +
                      @uri          = uri
         
     | 
| 
      
 19 
     | 
    
         
            +
                      @http_options = params.delete(:http_options) || {}
         
     | 
| 
      
 20 
     | 
    
         
            +
                      @params       = params
         
     | 
| 
      
 21 
     | 
    
         
            +
                    end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                    def call
         
     | 
| 
      
 24 
     | 
    
         
            +
                      http_obj.request request_obj
         
     | 
| 
      
 25 
     | 
    
         
            +
                    end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                    private
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                      def request_obj
         
     | 
| 
      
 30 
     | 
    
         
            +
                        req = Net::HTTP::Post.new uri.request_uri
         
     | 
| 
      
 31 
     | 
    
         
            +
                        req.set_form_data params
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                        req
         
     | 
| 
      
 34 
     | 
    
         
            +
                      end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                      def http_obj
         
     | 
| 
      
 37 
     | 
    
         
            +
                        http = Net::HTTP.new uri.host, uri.port
         
     | 
| 
      
 38 
     | 
    
         
            +
                        http.use_ssl = (uri.scheme == "https")
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                        http_options.each do |opt, val|
         
     | 
| 
      
 41 
     | 
    
         
            +
                          if http.respond_to? "#{opt}="
         
     | 
| 
      
 42 
     | 
    
         
            +
                            http.send "#{opt}=", val
         
     | 
| 
      
 43 
     | 
    
         
            +
                          else
         
     | 
| 
      
 44 
     | 
    
         
            +
                            warn "Net::HTTP doesn't respond to `#{opt}=`, ignoring that option"
         
     | 
| 
      
 45 
     | 
    
         
            +
                          end
         
     | 
| 
      
 46 
     | 
    
         
            +
                        end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                        http
         
     | 
| 
      
 49 
     | 
    
         
            +
                      end
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,63 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            module Slack
         
     | 
| 
      
 3 
     | 
    
         
            +
              class Notifier
         
     | 
| 
      
 4 
     | 
    
         
            +
                module Util
         
     | 
| 
      
 5 
     | 
    
         
            +
                  class LinkFormatter
         
     | 
| 
      
 6 
     | 
    
         
            +
                    # http://rubular.com/r/19cNXW5qbH
         
     | 
| 
      
 7 
     | 
    
         
            +
                    HTML_PATTERN = / <a (?:.*?) href=['"](.+?)['"] (?:.*?)> (.+?) <\/a> /x
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                    # http://rubular.com/r/guJbTK6x1f
         
     | 
| 
      
 10 
     | 
    
         
            +
                    MARKDOWN_PATTERN = /\[ ([^\[\]]*?) \] \( ((https?:\/\/.*?) | (mailto:.*?)) \) /x
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                    class << self
         
     | 
| 
      
 13 
     | 
    
         
            +
                      def format string, opts={}
         
     | 
| 
      
 14 
     | 
    
         
            +
                        LinkFormatter.new(string, opts).formatted
         
     | 
| 
      
 15 
     | 
    
         
            +
                      end
         
     | 
| 
      
 16 
     | 
    
         
            +
                    end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                    attr_reader :formats
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    def initialize string, formats: [:html, :markdown]
         
     | 
| 
      
 21 
     | 
    
         
            +
                      @formats = formats
         
     | 
| 
      
 22 
     | 
    
         
            +
                      @orig    = string.respond_to?(:scrub) ? string.scrub : string
         
     | 
| 
      
 23 
     | 
    
         
            +
                    end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                    # rubocop:disable Style/GuardClause
         
     | 
| 
      
 26 
     | 
    
         
            +
                    def formatted
         
     | 
| 
      
 27 
     | 
    
         
            +
                      sub_markdown_links(sub_html_links(@orig))
         
     | 
| 
      
 28 
     | 
    
         
            +
                    rescue => e
         
     | 
| 
      
 29 
     | 
    
         
            +
                      if RUBY_VERSION < "2.1" && e.message.include?("invalid byte sequence")
         
     | 
| 
      
 30 
     | 
    
         
            +
                        raise e, "#{e.message}. Consider including the 'string-scrub' gem to strip invalid characters"
         
     | 
| 
      
 31 
     | 
    
         
            +
                      else
         
     | 
| 
      
 32 
     | 
    
         
            +
                        raise e
         
     | 
| 
      
 33 
     | 
    
         
            +
                      end
         
     | 
| 
      
 34 
     | 
    
         
            +
                    end
         
     | 
| 
      
 35 
     | 
    
         
            +
                    # rubocop:enable Style/GuardClause
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                    private
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                      def sub_html_links string
         
     | 
| 
      
 40 
     | 
    
         
            +
                        return string unless formats.include?(:html)
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                        string.gsub(HTML_PATTERN) do
         
     | 
| 
      
 43 
     | 
    
         
            +
                          slack_link Regexp.last_match[1], Regexp.last_match[2]
         
     | 
| 
      
 44 
     | 
    
         
            +
                        end
         
     | 
| 
      
 45 
     | 
    
         
            +
                      end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                      def sub_markdown_links string
         
     | 
| 
      
 48 
     | 
    
         
            +
                        return string unless formats.include?(:markdown)
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                        string.gsub(MARKDOWN_PATTERN) do
         
     | 
| 
      
 51 
     | 
    
         
            +
                          slack_link Regexp.last_match[2], Regexp.last_match[1]
         
     | 
| 
      
 52 
     | 
    
         
            +
                        end
         
     | 
| 
      
 53 
     | 
    
         
            +
                      end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                      def slack_link link, text=nil
         
     | 
| 
      
 56 
     | 
    
         
            +
                        "<#{link}" \
         
     | 
| 
      
 57 
     | 
    
         
            +
                        "#{text && !text.empty? ? "|#{text}" : ''}" \
         
     | 
| 
      
 58 
     | 
    
         
            +
                        ">"
         
     | 
| 
      
 59 
     | 
    
         
            +
                      end
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
                end
         
     | 
| 
      
 62 
     | 
    
         
            +
              end
         
     | 
| 
      
 63 
     | 
    
         
            +
            end
         
     |