Class: InstagramConnect::AccountReadinessJob
- Inherits:
-
ApplicationJob
- Object
- ActiveJob::Base
- ApplicationJob
- InstagramConnect::AccountReadinessJob
- Defined in:
- app/jobs/instagram_connect/account_readiness_job.rb
Overview
Closes the gap between "an operator clicked Connect" and "events actually flow", then keeps it closed.
Two things stand in that gap and neither has a dashboard equivalent:
1. TOKEN GRADE. The OAuth exchange returns a long-lived *user* token, but
every Instagram messaging call and the subscription below are Page
token operations. This swaps in the Page token. Page tokens minted from
a long-lived user token do not expire, so the expiry is cleared with it.
2. PAGE SUBSCRIPTION. Ticking webhook fields in the app dashboard
subscribes the *app*. Meta delivers nothing until the *Page* lists the
app in its subscribed_apps, which is a per-Page Graph call.
Both steps read before they write, so a scheduled run costs two GETs and changes nothing once an account is healthy. That is the point: a token Meta rotates, or a subscription dropped when an app moves between Development and Live mode, heals itself rather than becoming a console command nobody remembers to run.
This lives in the gem rather than in a host because the field list has to track what Ingest can actually parse. Maintained separately, the two drift and the host silently receives events it drops.
Constant Summary collapse
- HTTP_TIMEOUT =
15
Class Method Summary collapse
- .connectable ⇒ Object
-
.enqueue_if_needed ⇒ Object
Cheap negative check so an install with no connected account never enqueues anything.
- .subscribed_fields ⇒ Object
Instance Method Summary collapse
Class Method Details
.connectable ⇒ Object
45 46 47 |
# File 'app/jobs/instagram_connect/account_readiness_job.rb', line 45 def self.connectable Account.active.where.not(page_id: [ nil, "" ]) end |
.enqueue_if_needed ⇒ Object
Cheap negative check so an install with no connected account never enqueues anything.
37 38 39 40 41 42 43 |
# File 'app/jobs/instagram_connect/account_readiness_job.rb', line 37 def self.enqueue_if_needed return :nothing_to_do if InstagramConnect.configuration.app_id.blank? return :nothing_to_do unless connectable.exists? perform_later :enqueued end |
.subscribed_fields ⇒ Object
31 32 33 |
# File 'app/jobs/instagram_connect/account_readiness_job.rb', line 31 def self.subscribed_fields Ingest::Registry.subscribable_fields end |
Instance Method Details
#perform ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'app/jobs/instagram_connect/account_readiness_job.rb', line 49 def perform return if InstagramConnect.configuration.app_id.blank? self.class.connectable.find_each do |account| # Cleared up front rather than on success, so a step that records a soft # failure (no Page token, say) is not immediately wiped by the same pass # completing without raising. account.update_columns(readiness_error: nil) if account.readiness_error.present? ensure_page_token(account) ensure_subscription(account) rescue StandardError => e # One unhealthy account must not stop the rest, and the next run retries # anyway. The reason is kept on the row so a health screen can show it. account.update_columns(readiness_error: "#{e.class}: #{e.}".truncate(255)) logger&.error("[InstagramConnect] readiness failed for account=#{account.id}: #{e.}") end end |