twitter_user_agent.rb 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. module Agents
  2. class TwitterUserAgent < Agent
  3. include TwitterConcern
  4. can_dry_run!
  5. cannot_receive_events!
  6. description <<~MD
  7. The Twitter User Agent either follows the timeline of a specific Twitter user or follows your own home timeline including both your tweets and tweets from people whom you are following.
  8. #{twitter_dependencies_missing if dependencies_missing?}
  9. To be able to use this Agent you need to authenticate with Twitter in the [Services](/services) section first.
  10. To follow a Twitter user set `choose_home_time_line` to `false` and provide the `username`.
  11. To follow your own home timeline set `choose_home_time_line` to `true`.
  12. Set `include_retweets` to `false` to not include retweets (default: `true`)
  13. Set `exclude_replies` to `true` to exclude replies (default: `false`)
  14. Set `expected_update_period_in_days` to the maximum amount of time that you'd expect to pass between Events being created by this Agent.
  15. Set `starting_at` to the date/time (eg. `Mon Jun 02 00:38:12 +0000 2014`) you want to start receiving tweets from (default: agent's `created_at`)
  16. MD
  17. event_description <<~MD
  18. Events are the raw JSON provided by the [Twitter API v1.1](https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline) with slight modifications. They should look something like this:
  19. #{tweet_event_description('full_text')}
  20. MD
  21. default_schedule "every_1h"
  22. def working?
  23. event_created_within?(interpolated['expected_update_period_in_days']) && !recent_error_logs?
  24. end
  25. def default_options
  26. {
  27. 'username' => 'tectonic',
  28. 'include_retweets' => 'true',
  29. 'exclude_replies' => 'false',
  30. 'expected_update_period_in_days' => '2',
  31. 'choose_home_time_line' => 'false'
  32. }
  33. end
  34. def validate_options
  35. if options[:expected_update_period_in_days].blank?
  36. errors.add(:base, "expected_update_period_in_days is required")
  37. end
  38. if !boolify(options[:choose_home_time_line]) && options[:username].blank?
  39. errors.add(:base, "username is required")
  40. end
  41. if options[:include_retweets].present? && !%w[true false].include?(options[:include_retweets].to_s)
  42. errors.add(:base, "include_retweets must be a boolean value (true/false)")
  43. end
  44. if options[:starting_at].present?
  45. begin
  46. Time.parse(options[:starting_at])
  47. rescue StandardError
  48. errors.add(:base, "Error parsing starting_at")
  49. end
  50. end
  51. end
  52. def check
  53. opts = {
  54. count: 200,
  55. include_rts: include_retweets?,
  56. exclude_replies: exclude_replies?,
  57. include_entities: true,
  58. contributor_details: true,
  59. tweet_mode: 'extended',
  60. since_id: memory[:since_id].presence,
  61. }.compact
  62. tweets =
  63. if choose_home_time_line?
  64. twitter.home_timeline(opts)
  65. else
  66. twitter.user_timeline(interpolated[:username], opts)
  67. end
  68. tweets.sort_by(&:id).each do |tweet|
  69. next unless tweet.created_at >= starting_at
  70. memory[:since_id] = [tweet.id, *memory[:since_id]].max
  71. create_event(payload: format_tweet(tweet))
  72. end
  73. end
  74. private
  75. def starting_at
  76. if interpolated[:starting_at].present?
  77. begin
  78. Time.parse(interpolated[:starting_at])
  79. rescue StandardError
  80. end
  81. end || created_at || Time.now # for dry-running
  82. end
  83. def choose_home_time_line?
  84. boolify(interpolated[:choose_home_time_line])
  85. end
  86. def include_retweets?
  87. # default to true
  88. boolify(interpolated[:include_retweets]) != false
  89. end
  90. def exclude_replies?
  91. # default to false
  92. boolify(interpolated[:exclude_replies]) || false
  93. end
  94. end
  95. end