module Agents class TwitterActionAgent < Agent include TwitterConcern cannot_be_scheduled! description <<~MD The Twitter Action Agent is able to retweet or favorite tweets from the events it receives. #{twitter_dependencies_missing if dependencies_missing?} It expects to consume events generated by twitter agents where the payload is a hash of tweet information. The existing TwitterStreamAgent is one example of a valid event producer for this Agent. To be able to use this Agent you need to authenticate with Twitter in the [Services](/services) section first. Set `expected_receive_period_in_days` to the maximum amount of time that you'd expect to pass between Events being received by this Agent. Set `retweet` to either true or false. Set `favorite` to either true or false. Set `emit_error_events` to true to emit an Event when the action failed, otherwise the action will be retried. MD def validate_options unless options['expected_receive_period_in_days'].present? errors.add(:base, "expected_receive_period_in_days is required") end unless retweet? || favorite? errors.add(:base, "at least one action must be true") end if emit_error_events?.nil? errors.add(:base, "emit_error_events must be set to 'true' or 'false'") end end def working? last_receive_at && last_receive_at > interpolated['expected_receive_period_in_days'].to_i.days.ago && !recent_error_logs? end def default_options { 'expected_receive_period_in_days' => '2', 'favorite' => 'false', 'retweet' => 'true', 'emit_error_events' => 'false' } end def retweet? boolify(options['retweet']) end def favorite? boolify(options['favorite']) end def emit_error_events? boolify(options['emit_error_events']) end def receive(incoming_events) tweets = tweets_from_events(incoming_events) begin twitter.favorite(tweets) if favorite? twitter.retweet(tweets) if retweet? rescue Twitter::Error => e case e when Twitter::Error::AlreadyRetweeted, Twitter::Error::AlreadyFavorited error e.message else raise e unless emit_error_events? end if emit_error_events? create_event payload: { 'success' => false, 'error' => e.message, 'tweets' => Hash[tweets.map { |t| [t.id, t.text] }], 'agent_ids' => incoming_events.map(&:agent_id), 'event_ids' => incoming_events.map(&:id) } end end end def tweets_from_events(events) events.map do |e| Twitter::Tweet.new( id: e.payload["id"], text: e.payload["expanded_text"] || e.payload["full_text"] || e.payload["text"] ) end end end end