tumblr_publish_agent.rb 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. module Agents
  2. class TumblrPublishAgent < Agent
  3. include TumblrConcern
  4. cannot_be_scheduled!
  5. gem_dependency_check { defined?(Tumblr::Client) }
  6. description <<-MD
  7. The Tumblr Publish Agent publishes Tumblr posts from the events it receives.
  8. #{'## Include `tumblr_client` and `omniauth-tumblr` in your Gemfile to use this Agent!' if dependencies_missing?}
  9. To be able to use this Agent you need to authenticate with Tumblr in the [Services](/services) section first.
  10. **Required fields:**
  11. `blog_name` Your Tumblr URL (e.g. "mustardhamsters.tumblr.com")
  12. `post_type` One of [text, photo, quote, link, chat, audio, video, reblog]
  13. -------------
  14. You may leave any of the following optional fields blank. Including a field not allowed for the specified `post_type` will cause a failure.
  15. **Any post type**
  16. * `state` published, draft, queue, private
  17. * `tags` Comma-separated tags for this post
  18. * `tweet` off, text for tweet
  19. * `date` GMT date and time of the post as a string
  20. * `format` html, markdown
  21. * `slug` short text summary at end of the post URL
  22. **Text** `title` `body`
  23. **Photo** `caption` `link` `source`
  24. **Quote** `quote` `source`
  25. **Link** `title` `url` `description`
  26. **Chat** `title` `conversation`
  27. **Audio** `caption` `external_url`
  28. **Video** `caption` `embed`
  29. **Reblog** `id` `reblog_key` `comment`
  30. -------------
  31. [Full information on field options](https://www.tumblr.com/docs/en/api/v2#posting)
  32. 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.
  33. MD
  34. def validate_options
  35. errors.add(:base, "expected_update_period_in_days is required") unless options['expected_update_period_in_days'].present?
  36. end
  37. def working?
  38. event_created_within?(interpolated['expected_update_period_in_days']) && most_recent_event && most_recent_event.payload['success'] == true && !recent_error_logs?
  39. end
  40. def default_options
  41. {
  42. 'expected_update_period_in_days' => "10",
  43. 'blog_name' => "{{blog_name}}",
  44. 'post_type' => "{{post_type}}",
  45. 'options' => {
  46. 'state' => "{{state}}",
  47. 'tags' => "{{tags}}",
  48. 'tweet' => "{{tweet}}",
  49. 'date' => "{{date}}",
  50. 'format' => "{{format}}",
  51. 'slug' => "{{slug}}",
  52. 'title' => "{{title}}",
  53. 'body' => "{{body}}",
  54. 'caption' => "{{caption}}",
  55. 'link' => "{{link}}",
  56. 'source' => "{{source}}",
  57. 'quote' => "{{quote}}",
  58. 'url' => "{{url}}",
  59. 'description' => "{{description}}",
  60. 'conversation' => "{{conversation}}",
  61. 'external_url' => "{{external_url}}",
  62. 'embed' => "{{embed}}",
  63. 'id' => "{{id}}",
  64. 'reblog_key' => "{{reblog_key}}",
  65. 'comment' => "{{comment}}",
  66. },
  67. }
  68. end
  69. def receive(incoming_events)
  70. # if there are too many, dump a bunch to avoid getting rate limited
  71. if incoming_events.count > 20
  72. incoming_events = incoming_events.first(20)
  73. end
  74. incoming_events.each do |event|
  75. blog_name = interpolated(event)['blog_name']
  76. post_type = interpolated(event)['post_type']
  77. options = interpolated(event)['options']
  78. begin
  79. post = publish_post(blog_name, post_type, options)
  80. if !post.has_key?('id')
  81. log("Failed to create #{post_type} post on #{blog_name}: #{post.to_json}, options: #{options.to_json}")
  82. return
  83. end
  84. expanded_post = get_post(blog_name, post["id"])
  85. create_event :payload => {
  86. 'success' => true,
  87. 'published_post' => "["+blog_name+"] "+post_type,
  88. 'post_id' => post["id"],
  89. 'agent_id' => event.agent_id,
  90. 'event_id' => event.id,
  91. 'post' => expanded_post
  92. }
  93. end
  94. end
  95. end
  96. def publish_post(blog_name, post_type, options)
  97. options_obj = {
  98. :state => options['state'],
  99. :tags => options['tags'],
  100. :tweet => options['tweet'],
  101. :date => options['date'],
  102. :format => options['format'],
  103. :slug => options['slug'],
  104. }
  105. case post_type
  106. when "text"
  107. options_obj[:title] = options['title']
  108. options_obj[:body] = options['body']
  109. tumblr.text(blog_name, options_obj)
  110. when "photo"
  111. options_obj[:caption] = options['caption']
  112. options_obj[:link] = options['link']
  113. options_obj[:source] = options['source']
  114. tumblr.photo(blog_name, options_obj)
  115. when "quote"
  116. options_obj[:quote] = options['quote']
  117. options_obj[:source] = options['source']
  118. tumblr.quote(blog_name, options_obj)
  119. when "link"
  120. options_obj[:title] = options['title']
  121. options_obj[:url] = options['url']
  122. options_obj[:description] = options['description']
  123. tumblr.link(blog_name, options_obj)
  124. when "chat"
  125. options_obj[:title] = options['title']
  126. options_obj[:conversation] = options['conversation']
  127. tumblr.chat(blog_name, options_obj)
  128. when "audio"
  129. options_obj[:caption] = options['caption']
  130. options_obj[:external_url] = options['external_url']
  131. tumblr.audio(blog_name, options_obj)
  132. when "video"
  133. options_obj[:caption] = options['caption']
  134. options_obj[:embed] = options['embed']
  135. tumblr.video(blog_name, options_obj)
  136. when "reblog"
  137. options_obj[:id] = options['id']
  138. options_obj[:reblog_key] = options['reblog_key']
  139. options_obj[:comment] = options['comment']
  140. tumblr.reblog(blog_name, options_obj)
  141. end
  142. end
  143. def get_post(blog_name, id)
  144. obj = tumblr.posts(blog_name, {
  145. :id => id
  146. })
  147. obj["posts"].first
  148. end
  149. end
  150. end