telegram_agent.rb 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. require 'httmultiparty'
  2. require 'open-uri'
  3. require 'tempfile'
  4. module Agents
  5. class TelegramAgent < Agent
  6. cannot_be_scheduled!
  7. cannot_create_events!
  8. no_bulk_receive!
  9. description <<-MD
  10. The Telegram Agent receives and collects events and sends them via [Telegram](https://telegram.org/).
  11. It is assumed that events have either a `text`, `photo`, `audio`, `document` or `video` key. You can use the EventFormattingAgent if your event does not provide these keys.
  12. The value of `text` key is sent as a plain text message. You can also tell Telegram how to parse the message with `parse_mode`, set to either `html` or `markdown`.
  13. The value of `photo`, `audio`, `document` and `video` keys should be a url whose contents will be sent to you.
  14. **Setup**
  15. 1. Obtain an `auth_token` by [creating a new bot](https://telegram.me/botfather).
  16. 2a. If you would like to send messages to a public channel:
  17. 1. Add your bot to the channel as an administrator
  18. 2. Set `chat_id` to the name of your channel - e.g. `@YourHugginChannel`
  19. 2b. If you would like to send messages to a group:
  20. 1. Add the bot to the group
  21. 2. Obtain your group `chat_id` from the recently started conversation by visiting https://api.telegram.org/bot`<auth_token>`/getUpdates
  22. 2c. If you would like to send messages privately to yourself:
  23. 1. Send a private message to your bot by visiting https://telegram.me/YourHuginnBot
  24. 2. Obtain your private `chat_id` from the recently started conversation by visiting https://api.telegram.org/bot`<auth_token>`/getUpdates
  25. MD
  26. def default_options
  27. {
  28. auth_token: 'xxxxxxxxx:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  29. chat_id: 'xxxxxxxx'
  30. }
  31. end
  32. def validate_options
  33. errors.add(:base, 'auth_token is required') unless options['auth_token'].present?
  34. errors.add(:base, 'chat_id is required') unless options['chat_id'].present?
  35. errors.add(:base, 'parse_mode has invalid value: should be html or markdown') if interpolated['parse_mode'].present? and !['html', 'markdown'].include? interpolated['parse_mode']
  36. end
  37. def working?
  38. received_event_without_error? && !recent_error_logs?
  39. end
  40. def receive(incoming_events)
  41. incoming_events.each do |event|
  42. receive_event event
  43. end
  44. end
  45. private
  46. TELEGRAM_ACTIONS = {
  47. text: :sendMessage,
  48. photo: :sendPhoto,
  49. audio: :sendAudio,
  50. document: :sendDocument,
  51. video: :sendVideo
  52. }.freeze
  53. def telegram_bot_uri(method)
  54. "https://api.telegram.org/bot#{interpolated['auth_token']}/#{method}"
  55. end
  56. def receive_event(event)
  57. TELEGRAM_ACTIONS.each do |field, method|
  58. payload = load_field event, field
  59. next unless payload
  60. send_telegram_message method, field => payload
  61. unlink_file payload if payload.is_a? Tempfile
  62. end
  63. end
  64. def send_telegram_message(method, params)
  65. params[:chat_id] = interpolated['chat_id']
  66. params[:parse_mode] = interpolated['parse_mode'] if interpolated['parse_mode'].present?
  67. HTTMultiParty.post telegram_bot_uri(method), query: params
  68. end
  69. def load_field(event, field)
  70. payload = event.payload[field]
  71. return false unless payload.present?
  72. return payload if field == :text
  73. load_file payload
  74. end
  75. def load_file(url)
  76. file = Tempfile.new [File.basename(url), File.extname(url)]
  77. file.binmode
  78. file.write open(url).read
  79. file.rewind
  80. file
  81. end
  82. def unlink_file(file)
  83. file.close
  84. file.unlink
  85. end
  86. end
  87. end