about summary refs log tree commit diff
path: root/app/services/post_status_service.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/services/post_status_service.rb')
-rw-r--r--app/services/post_status_service.rb14
1 files changed, 14 insertions, 0 deletions
diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb
index 6ce434a13..958cc2890 100644
--- a/app/services/post_status_service.rb
+++ b/app/services/post_status_service.rb
@@ -11,8 +11,14 @@ class PostStatusService < BaseService
   # @option [String] :spoiler_text
   # @option [Enumerable] :media_ids Optional array of media IDs to attach
   # @option [Doorkeeper::Application] :application
+  # @option [String] :idempotency Optional idempotency key
   # @return [Status]
   def call(account, text, in_reply_to = nil, options = {})
+    if options[:idempotency].present?
+      existing_id = redis.get("idempotency:status:#{account.id}:#{options[:idempotency]}")
+      return Status.find(existing_id) if existing_id
+    end
+
     media  = validate_media!(options[:media_ids])
     status = account.statuses.create!(text: text,
                                       thread: in_reply_to,
@@ -30,6 +36,10 @@ class PostStatusService < BaseService
     DistributionWorker.perform_async(status.id)
     Pubsubhubbub::DistributionWorker.perform_async(status.stream_entry.id)
 
+    if options[:idempotency].present?
+      redis.setex("idempotency:status:#{account.id}:#{options[:idempotency]}", 3_600, status.id)
+    end
+
     status
   end
 
@@ -63,4 +73,8 @@ class PostStatusService < BaseService
   def process_hashtags_service
     @process_hashtags_service ||= ProcessHashtagsService.new
   end
+
+  def redis
+    Redis.current
+  end
 end