From 9ed0c91a3702557b80d490bbf43677114aec31f8 Mon Sep 17 00:00:00 2001
From: Claire <claire.github-309c@sitedethib.com>
Date: Mon, 21 Aug 2023 16:09:26 +0200
Subject: [PATCH] Add auto-refresh of accounts we get new messages/edits of
 (#26510)

---
 app/lib/activitypub/activity/create.rb |  2 ++
 app/lib/activitypub/activity/update.rb |  2 ++
 app/models/account.rb                  |  8 ++++++++
 app/workers/account_refresh_worker.rb  | 14 ++++++++++++++
 4 files changed, 26 insertions(+)
 create mode 100644 app/workers/account_refresh_worker.rb

diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb
index 28cea8ec04..fedfa39dee 100644
--- a/app/lib/activitypub/activity/create.rb
+++ b/app/lib/activitypub/activity/create.rb
@@ -4,6 +4,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
   include FormattingHelper
 
   def perform
+    @account.schedule_refresh_if_stale!
+
     dereference_object!
 
     case @object['type']
diff --git a/app/lib/activitypub/activity/update.rb b/app/lib/activitypub/activity/update.rb
index 8e72e08237..0a7762ee39 100644
--- a/app/lib/activitypub/activity/update.rb
+++ b/app/lib/activitypub/activity/update.rb
@@ -2,6 +2,8 @@
 
 class ActivityPub::Activity::Update < ActivityPub::Activity
   def perform
+    @account.schedule_refresh_if_stale!
+
     dereference_object!
 
     if equals_or_includes_any?(@object['type'], %w(Application Group Organization Person Service))
diff --git a/app/models/account.rb b/app/models/account.rb
index 6b6cb8ee56..b1cb9eb5db 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -63,6 +63,8 @@ class Account < ApplicationRecord
     trust_level
   )
 
+  BACKGROUND_REFRESH_INTERVAL = 1.week.freeze
+
   USERNAME_RE   = /[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?/i
   MENTION_RE    = %r{(?<=^|[^/[:word:]])@((#{USERNAME_RE})(?:@[[:word:].-]+[[:word:]]+)?)}i
   URL_PREFIX_RE = %r{\Ahttp(s?)://[^/]+}
@@ -209,6 +211,12 @@ class Account < ApplicationRecord
     last_webfingered_at.nil? || last_webfingered_at <= 1.day.ago
   end
 
+  def schedule_refresh_if_stale!
+    return unless last_webfingered_at.present? && last_webfingered_at <= BACKGROUND_REFRESH_INTERVAL.ago
+
+    AccountRefreshWorker.perform_in(rand(6.hours.to_i), id)
+  end
+
   def refresh!
     ResolveAccountService.new.call(acct) unless local?
   end
diff --git a/app/workers/account_refresh_worker.rb b/app/workers/account_refresh_worker.rb
new file mode 100644
index 0000000000..08b5bab8da
--- /dev/null
+++ b/app/workers/account_refresh_worker.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class AccountRefreshWorker
+  include Sidekiq::Worker
+
+  sidekiq_options queue: 'pull', retry: 3, dead: false, lock: :until_executed, lock_ttl: 1.day.to_i
+
+  def perform(account_id)
+    account = Account.find_by(id: account_id)
+    return if account.nil? || account.last_webfingered_at > Account::BACKGROUND_REFRESH_INTERVAL.ago
+
+    ResolveAccountService.new.call(account)
+  end
+end
-- 
GitLab