webhook_agent.rb 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. module Agents
  2. class WebhookAgent < Agent
  3. cannot_be_scheduled!
  4. cannot_receive_events!
  5. description do <<-MD
  6. The Webhook Agent will create events by receiving webhooks from any source. In order to create events with this agent, make a POST request to:
  7. ```
  8. https://#{ENV['DOMAIN']}/users/#{user.id}/web_requests/#{id || ':id'}/#{options['secret'] || ':secret'}
  9. ```
  10. #{'The placeholder symbols above will be replaced by their values once the agent is saved.' unless id}
  11. Options:
  12. * `secret` - A token that the host will provide for authentication.
  13. * `expected_receive_period_in_days` - How often you expect to receive
  14. events this way. Used to determine if the agent is working.
  15. * `payload_path` - JSONPath of the attribute in the POST body to be
  16. used as the Event payload. If `payload_path` points to an array,
  17. Events will be created for each element.
  18. * `verbs` - Comma-separated list of http verbs your agent will accept.
  19. For example, "post,get" will enable POST and GET requests. Defaults
  20. to "post".
  21. MD
  22. end
  23. event_description do
  24. <<-MD
  25. The event payload is based on the value of the `payload_path` option,
  26. which is set to `#{interpolated['payload_path']}`.
  27. MD
  28. end
  29. def default_options
  30. { "secret" => "supersecretstring",
  31. "expected_receive_period_in_days" => 1,
  32. "payload_path" => "some_key"
  33. }
  34. end
  35. def receive_web_request(params, method, format)
  36. # check the secret
  37. secret = params.delete('secret')
  38. return ["Not Authorized", 401] unless secret == interpolated['secret']
  39. #check the verbs
  40. verbs = (interpolated['verbs'] || 'post').split(/,/).map { |x| x.strip.downcase }.select { |x| x.present? }
  41. return ["Please use #{verbs.join('/').upcase} requests only", 401] unless verbs.include?(method)
  42. [payload_for(params)].flatten.each do |payload|
  43. create_event(payload: payload)
  44. end
  45. ['Event Created', 201]
  46. end
  47. def working?
  48. event_created_within?(interpolated['expected_receive_period_in_days']) && !recent_error_logs?
  49. end
  50. def validate_options
  51. unless options['secret'].present?
  52. errors.add(:base, "Must specify a secret for 'Authenticating' requests")
  53. end
  54. end
  55. def payload_for(params)
  56. Utils.value_at(params, interpolated['payload_path']) || {}
  57. end
  58. end
  59. end