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.
-
.page_subscribed_fields ⇒ Object
What
subscribed_appswill actually accept — the Page object names, minus the fields that only exist on theinstagramobject. -
.subscribed_fields ⇒ Object
What we ask Meta to deliver to the webhook endpoint.
Instance Method Summary collapse
Class Method Details
.connectable ⇒ Object
54 55 56 |
# File 'app/jobs/instagram_connect/account_readiness_job.rb', line 54 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.
46 47 48 49 50 51 52 |
# File 'app/jobs/instagram_connect/account_readiness_job.rb', line 46 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 |
.page_subscribed_fields ⇒ Object
What subscribed_apps will actually accept — the Page object names, minus
the fields that only exist on the instagram object. Sending an Instagram
name here fails the ENTIRE call, so the two lists are deliberately
separate rather than one list used twice.
40 41 42 |
# File 'app/jobs/instagram_connect/account_readiness_job.rb', line 40 def self.page_subscribed_fields Ingest::Registry.page_subscribable_fields end |
.subscribed_fields ⇒ Object
What we ask Meta to deliver to the webhook endpoint.
32 33 34 |
# File 'app/jobs/instagram_connect/account_readiness_job.rb', line 32 def self.subscribed_fields Ingest::Registry.subscribable_fields end |
Instance Method Details
#perform ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'app/jobs/instagram_connect/account_readiness_job.rb', line 58 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 |