class ExceptionNotifier::TeamsNotifier

Attributes

httparty[RW]

Public Class Methods

new(options = {}) click to toggle source
Calls superclass method ExceptionNotifier::BaseNotifier::new
# File lib/exception_notifier/teams_notifier.rb, line 17
def initialize(options = {})
  super
  @default_options = options
  @httparty = HTTParty
end

Public Instance Methods

call(exception, options = {}) click to toggle source
# File lib/exception_notifier/teams_notifier.rb, line 23
def call(exception, options = {})
  @options = options.merge(@default_options)
  @exception = exception
  @backtrace = exception.backtrace ? clean_backtrace(exception) : nil

  @env = @options.delete(:env)

  @application_name = @options.delete(:app_name) || rails_app_name
  @gitlab_url = @options.delete(:git_url)
  @jira_url = @options.delete(:jira_url)

  @webhook_url = @options.delete(:webhook_url)
  raise ArgumentError, "You must provide 'webhook_url' parameter." unless @webhook_url

  if @env.nil?
    @controller = @request_items = nil
  else
    @controller = @env['action_controller.instance'] || MissingController.new

    request = ActionDispatch::Request.new(@env)

    @request_items = { url: request.original_url,
                       http_method: request.method,
                       ip_address: request.remote_ip,
                       parameters: request.filtered_parameters,
                       timestamp: Time.current }

    if request.session['warden.user.user.key']
      current_user = User.find(request.session['warden.user.user.key'][0][0])
      @request_items[:current_user] = { id: current_user.id, email: current_user.email }
    end
  end

  payload = message_text

  @options[:body] = payload.to_json
  @options[:headers] ||= {}
  @options[:headers]['Content-Type'] = 'application/json'
  @options[:debug_output] = $stdout

  @httparty.post(@webhook_url, @options)
end

Private Instance Methods

activity_title() click to toggle source
# File lib/exception_notifier/teams_notifier.rb, line 103
def activity_title
  errors_count = @options[:accumulated_errors_count].to_i

  "#{errors_count > 1 ? errors_count : 'A'} *#{@exception.class}* occurred" +
    (@controller ? " in *#{controller_and_method}*." : '.')
end
controller_and_method() click to toggle source
# File lib/exception_notifier/teams_notifier.rb, line 168
def controller_and_method
  if @controller
    "#{@controller.controller_name}##{@controller.action_name}"
  else
    ''
  end
end
details() click to toggle source
# File lib/exception_notifier/teams_notifier.rb, line 91
def details
  details = {
    'title' => 'Details',
    'facts' => []
  }

  details['facts'].push message_request unless @request_items.nil?
  details['facts'].push message_backtrace unless @backtrace.nil?

  details
end
env_name() click to toggle source
# File lib/exception_notifier/teams_notifier.rb, line 196
def env_name
  Rails.env if defined?(Rails) && Rails.respond_to?(:env)
end
hash_presentation(hash) click to toggle source
# File lib/exception_notifier/teams_notifier.rb, line 176
def hash_presentation(hash)
  text = []

  hash.each do |key, value|
    text << "* **#{key}** : `#{value}`"
  end

  text.join("  \n")
end
message_backtrace(size = 3) click to toggle source
# File lib/exception_notifier/teams_notifier.rb, line 117
def message_backtrace(size = 3)
  text = []
  size = @backtrace.size < size ? @backtrace.size : size
  text << '```'
  size.times { |i| text << '* ' + @backtrace[i] }
  text << '```'

  {
    'name' => 'Backtrace',
    'value' => text.join("  \n").to_s
  }
end
message_request() click to toggle source
# File lib/exception_notifier/teams_notifier.rb, line 110
def message_request
  {
    'name' => 'Request',
    'value' => "#{hash_presentation(@request_items)}\n  "
  }
end
message_text() click to toggle source
# File lib/exception_notifier/teams_notifier.rb, line 68
def message_text
  text = {
    '@type' => 'MessageCard',
    '@context' => 'http://schema.org/extensions',
    'summary' => "#{@application_name} Exception Alert",
    'title' => "⚠️ Exception Occurred in #{env_name} ⚠️",
    'sections' => [
      {
        'activityTitle' => activity_title,
        'activitySubtitle' => @exception.message.to_s
      }
    ],
    'potentialAction' => []
  }

  text['sections'].push details
  text['potentialAction'].push gitlab_view_link unless @gitlab_url.nil?
  text['potentialAction'].push gitlab_issue_link unless @gitlab_url.nil?
  text['potentialAction'].push jira_issue_link unless @jira_url.nil?

  text
end
rails_app_name() click to toggle source
# File lib/exception_notifier/teams_notifier.rb, line 186
def rails_app_name
  return unless defined?(Rails) && Rails.respond_to?(:application)

  if ::Gem::Version.new(Rails.version) >= ::Gem::Version.new('6.0')
    Rails.application.class.module_parent_name.underscore
  else
    Rails.application.class.parent_name.underscore
  end
end