slack_agent.rb 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. module Agents
  2. class SlackAgent < Agent
  3. DEFAULT_USERNAME = 'Huginn'
  4. cannot_be_scheduled!
  5. cannot_create_events!
  6. gem_dependency_check { defined?(Slack) }
  7. description <<-MD
  8. The Slack Agent lets you receive events and send notifications to [Slack](https://slack.com/).
  9. #{'## Include `slack-notifier` in your Gemfile to use this Agent!' if dependencies_missing?}
  10. To get started, you will first need to configure an incoming webhook.
  11. - Go to `https://my.slack.com/services/new/incoming-webhook`, choose a default channel and add the integration.
  12. Your webhook URL will look like: `https://hooks.slack.com/services/some/random/characters`
  13. Once the webhook has been configured, it can be used to post to other channels or direct to team members. To send a private message to team member, use their @username as the channel. Messages can be formatted using [Liquid](https://github.com/cantino/huginn/wiki/Formatting-Events-using-Liquid).
  14. Finally, you can set a custom icon for this webhook in `icon`, either as [emoji](http://www.emoji-cheat-sheet.com) or an URL to an image. Leaving this field blank will use the default icon for a webhook.
  15. MD
  16. def default_options
  17. {
  18. 'webhook_url' => 'https://hooks.slack.com/services/...',
  19. 'channel' => '#general',
  20. 'username' => DEFAULT_USERNAME,
  21. 'message' => "Hey there, It's Huginn",
  22. 'icon' => '',
  23. }
  24. end
  25. def validate_options
  26. unless options['webhook_url'].present? ||
  27. (options['auth_token'].present? && options['team_name'].present?) # compatibility
  28. errors.add(:base, "webhook_url is required")
  29. end
  30. errors.add(:base, "channel is required") unless options['channel'].present?
  31. end
  32. def working?
  33. received_event_without_error?
  34. end
  35. def webhook_url
  36. case
  37. when url = interpolated[:webhook_url].presence
  38. url
  39. when (team = interpolated[:team_name].presence) && (token = interpolated[:auth_token])
  40. webhook = interpolated[:webhook].presence || 'incoming-webhook'
  41. # old style webhook URL
  42. "https://#{Rack::Utils.escape_path(team)}.slack.com/services/hooks/#{Rack::Utils.escape_path(webhook)}?token=#{Rack::Utils.escape(token)}"
  43. end
  44. end
  45. def username
  46. interpolated[:username].presence || DEFAULT_USERNAME
  47. end
  48. def slack_notifier
  49. @slack_notifier ||= Slack::Notifier.new(webhook_url, username: username)
  50. end
  51. def receive(incoming_events)
  52. incoming_events.each do |event|
  53. opts = interpolated(event)
  54. if /^:/.match(opts[:icon])
  55. slack_notifier.ping opts[:message], channel: opts[:channel], username: opts[:username], icon_emoji: opts[:icon], unfurl_links: opts[:unfurl_links]
  56. else
  57. slack_notifier.ping opts[:message], channel: opts[:channel], username: opts[:username], icon_url: opts[:icon], unfurl_links: opts[:unfurl_links]
  58. end
  59. end
  60. end
  61. end
  62. end