class Agents::HttpRequestAgent

Constants

MIME_RE

Public Instance Methods

check() click to toggle source
# File lib/huginn_http_request_agent/http_request_agent.rb, line 189
def check
  handle interpolated['payload'].presence || {}, headers
end
default_options() click to toggle source
# File lib/huginn_http_request_agent/http_request_agent.rb, line 91
def default_options
  {
    'endpoint' => "http://www.example.com",
    'expected_receive_period_in_days' => '1',
    'content_type' => 'json',
    'method' => 'get',
    'payload' => {
      'key' => 'value',
      'something' => 'the event contained {{ somekey }}'
    },
    'headers' => {},
    'emit_events' => 'true',
    'no_merge' => 'false',
    'output_mode' => 'clean',
    'log_requests' => 'false'
  }
end
method() click to toggle source
# File lib/huginn_http_request_agent/http_request_agent.rb, line 119
def method
  (interpolated['method'].presence || 'post').to_s.downcase
end
receive(incoming_events) click to toggle source
# File lib/huginn_http_request_agent/http_request_agent.rb, line 175
def receive(incoming_events)
  incoming_events.each do |event|
    interpolate_with(event) do
      outgoing = interpolated['payload'].presence || {}

      if boolify(interpolated['no_merge'])
        handle outgoing, event, headers(interpolated[:headers])
      else
        handle outgoing.merge(event.payload), event, headers(interpolated[:headers])
      end
    end
  end
end
validate_options() click to toggle source
# File lib/huginn_http_request_agent/http_request_agent.rb, line 123
def validate_options
  unless options['endpoint'].present?
    errors.add(:base, "endpoint is a required field")
  end

  if options['payload'].present? && %w[get delete].include?(method) && !(options['payload'].is_a?(Hash) || options['payload'].is_a?(Array))
    errors.add(:base, "if provided, payload must be a hash or an array")
  end

  if options['payload'].present? && %w[post put patch].include?(method)
    if !(options['payload'].is_a?(Hash) || options['payload'].is_a?(Array)) && options['content_type'] !~ MIME_RE
      errors.add(:base, "if provided, payload must be a hash or an array")
    end
  end

  if options['content_type'] =~ MIME_RE && options['payload'].is_a?(String) && boolify(options['no_merge']) != true
    errors.add(:base, "when the payload is a string, `no_merge` has to be set to `true`")
  end

  if options['content_type'] == 'form' && options['payload'].present? && options['payload'].is_a?(Array)
    errors.add(:base, "when content_type is a form, if provided, payload must be a hash")
  end

  if options.has_key?('emit_events') && boolify(options['emit_events']).nil?
    errors.add(:base, "if provided, emit_events must be true or false")
  end

  if options.has_key?('log_requests') && boolify(options['log_requests']).nil?
    errors.add(:base, "If provided, log_requests must be true or false")
  end

  validate_event_headers_options!

  unless %w[post get put delete patch].include?(method)
    errors.add(:base, "method must be 'post', 'get', 'put', 'delete', or 'patch'")
  end

  if options['no_merge'].present? && !%[true false].include?(options['no_merge'].to_s)
    errors.add(:base, "if provided, no_merge must be 'true' or 'false'")
  end

  if options['output_mode'].present? && !options['output_mode'].to_s.include?('{') && !%[clean merge].include?(options['output_mode'].to_s)
    errors.add(:base, "if provided, output_mode must be 'clean' or 'merge'")
  end

  unless headers.is_a?(Hash)
    errors.add(:base, "if provided, headers must be a hash")
  end

  validate_web_request_options!
end
working?() click to toggle source
# File lib/huginn_http_request_agent/http_request_agent.rb, line 109
def working?
  return false if recent_error_logs?

  if interpolated['expected_receive_period_in_days'].present?
    return false unless last_receive_at && last_receive_at > interpolated['expected_receive_period_in_days'].to_i.days.ago
  end

  true
end

Private Instance Methods

event_headers_key() click to toggle source
Calls superclass method
# File lib/huginn_http_request_agent/http_request_agent.rb, line 271
def event_headers_key
  super || 'headers'
end
handle(data, event = Event.new, headers) click to toggle source
# File lib/huginn_http_request_agent/http_request_agent.rb, line 195
def handle(data, event = Event.new, headers)
  url = interpolated(event.payload)[:endpoint]

  case method
  when 'get'
    content_type = interpolated(event.payload)['content_type']

    case content_type
    when 'json'
      headers['Content-Type'] ||= 'application/json; charset=utf-8'
      url = faraday.build_url(url, data.compact)
    else
      params = data
      body = nil
    end

  when 'delete'
    params = data
    body = nil
  when 'post', 'put', 'patch'
    params = nil
    content_type = nil

    if has_file_pointer?(event)
      data[interpolated(event.payload)['upload_key'].presence || 'file'] = get_upload_io(event)
    else
      content_type = interpolated(event.payload)['content_type']
    end

    case content_type
    when 'json'
      headers['Content-Type'] ||= 'application/json; charset=utf-8'
      body = data.to_json
    when 'xml'
      headers['Content-Type'] ||= 'text/xml; charset=utf-8'
      body = data.to_xml(root: (interpolated(event.payload)[:xml_root] || 'post'))
    when MIME_RE
      headers['Content-Type'] ||= content_type
      body = data.to_s
    else
      body = data
    end
  else
    error "Invalid method '#{method}'"
  end

  if boolify(interpolated['log_requests'])
    log({ method: method, url: url, body: body, headers: headers })
  end

  response = faraday.run_request(method.to_sym, url, body, headers) { |request|

    # open/read timeout in seconds
    if interpolated['timeout'].to_i
        request.options.timeout = interpolated['timeout'].to_i
    end

    # connection open timeout in seconds
    if interpolated['open_timeout'].to_i
        request.options.open_timeout = interpolated['open_timeout'].to_i
    end

    request.params.update(params) if params
  }

  if boolify(interpolated['emit_events'])
    new_event = interpolated['output_mode'].to_s == 'merge' ? event.payload.dup : {}
    create_event payload: new_event.merge(
      body: response.body,
      status: response.status
    ).merge(
      event_headers_payload(response.headers)
    )
  end
end