app/models/agents/twitter_action_agent.rb
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