1
0

tumblr_publish_agent.rb 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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,
  36. "expected_update_period_in_days is required") unless options['expected_update_period_in_days'].present?
  37. end
  38. def working?
  39. event_created_within?(interpolated['expected_update_period_in_days']) && most_recent_event && most_recent_event.payload['success'] == true && !recent_error_logs?
  40. end
  41. def default_options
  42. {
  43. 'expected_update_period_in_days' => "10",
  44. 'blog_name' => "{{blog_name}}",
  45. 'post_type' => "{{post_type}}",
  46. 'options' => {
  47. 'state' => "{{state}}",
  48. 'tags' => "{{tags}}",
  49. 'tweet' => "{{tweet}}",
  50. 'date' => "{{date}}",
  51. 'format' => "{{format}}",
  52. 'slug' => "{{slug}}",
  53. 'title' => "{{title}}",
  54. 'body' => "{{body}}",
  55. 'caption' => "{{caption}}",
  56. 'link' => "{{link}}",
  57. 'source' => "{{source}}",
  58. 'quote' => "{{quote}}",
  59. 'url' => "{{url}}",
  60. 'description' => "{{description}}",
  61. 'conversation' => "{{conversation}}",
  62. 'external_url' => "{{external_url}}",
  63. 'embed' => "{{embed}}",
  64. 'id' => "{{id}}",
  65. 'reblog_key' => "{{reblog_key}}",
  66. 'comment' => "{{comment}}",
  67. },
  68. }
  69. end
  70. def receive(incoming_events)
  71. # if there are too many, dump a bunch to avoid getting rate limited
  72. if incoming_events.count > 20
  73. incoming_events = incoming_events.first(20)
  74. end
  75. incoming_events.each do |event|
  76. blog_name = interpolated(event)['blog_name']
  77. post_type = interpolated(event)['post_type']
  78. options = interpolated(event)['options']
  79. begin
  80. post = publish_post(blog_name, post_type, options)
  81. if !post.has_key?('id')
  82. log("Failed to create #{post_type} post on #{blog_name}: #{post.to_json}, options: #{options.to_json}")
  83. return
  84. end
  85. expanded_post = get_post(blog_name, post["id"])
  86. create_event payload: {
  87. 'success' => true,
  88. 'published_post' => "[" + blog_name + "] " + post_type,
  89. 'post_id' => post["id"],
  90. 'agent_id' => event.agent_id,
  91. 'event_id' => event.id,
  92. 'post' => expanded_post
  93. }
  94. end
  95. end
  96. end
  97. def publish_post(blog_name, post_type, options)
  98. options_obj = {
  99. state: options['state'],
  100. tags: options['tags'],
  101. tweet: options['tweet'],
  102. date: options['date'],
  103. format: options['format'],
  104. slug: options['slug'],
  105. }
  106. case post_type
  107. when "text"
  108. options_obj[:title] = options['title']
  109. options_obj[:body] = options['body']
  110. tumblr.text(blog_name, options_obj)
  111. when "photo"
  112. options_obj[:caption] = options['caption']
  113. options_obj[:link] = options['link']
  114. options_obj[:source] = options['source']
  115. tumblr.photo(blog_name, options_obj)
  116. when "quote"
  117. options_obj[:quote] = options['quote']
  118. options_obj[:source] = options['source']
  119. tumblr.quote(blog_name, options_obj)
  120. when "link"
  121. options_obj[:title] = options['title']
  122. options_obj[:url] = options['url']
  123. options_obj[:description] = options['description']
  124. tumblr.link(blog_name, options_obj)
  125. when "chat"
  126. options_obj[:title] = options['title']
  127. options_obj[:conversation] = options['conversation']
  128. tumblr.chat(blog_name, options_obj)
  129. when "audio"
  130. options_obj[:caption] = options['caption']
  131. options_obj[:external_url] = options['external_url']
  132. tumblr.audio(blog_name, options_obj)
  133. when "video"
  134. options_obj[:caption] = options['caption']
  135. options_obj[:embed] = options['embed']
  136. tumblr.video(blog_name, options_obj)
  137. when "reblog"
  138. options_obj[:id] = options['id']
  139. options_obj[:reblog_key] = options['reblog_key']
  140. options_obj[:comment] = options['comment']
  141. tumblr.reblog(blog_name, options_obj)
  142. end
  143. end
  144. def get_post(blog_name, id)
  145. obj = tumblr.posts(blog_name, { id: })
  146. obj["posts"].first
  147. end
  148. end
  149. end