Class: InstagramConnect::Account
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- InstagramConnect::Account
- Defined in:
- app/models/instagram_connect/account.rb
Overview
A connected Instagram professional account. Holds the (encrypted) access token and the identity the Graph client sends as. One row per connected account — the gem supports connecting several.
Constant Summary collapse
- ENCRYPTED_ENVELOPE =
An Active Record Encryption envelope, as stored. With support_unencrypted_data on, a decrypt that FAILS (rotated or missing keys) hands the envelope back instead of raising — so an unreadable token reaches Meta as this JSON blob and comes back as the baffling "Cannot parse access token", with every call dead and nothing saying why.
/\A\{"p":/- TOKEN_UNREADABLE_MESSAGE =
"Stored access token cannot be decrypted with the current encryption " \ "keys — reconnect this Instagram account to store a fresh one.".freeze
Class Method Summary collapse
-
.enable_token_encryption! ⇒ Object
Called from the engine initializer (and specs) when token encryption is enabled.
Instance Method Summary collapse
-
#api_token ⇒ Object
Every Instagram messaging call and the webhook subscription are Page-token operations.
-
#client ⇒ Object
The only place a Client should be built.
-
#refresh_access_token! ⇒ Object
Refresh via the account's auth strategy and persist the rotated token.
- #subscribed_field_list ⇒ Object
- #token_expired? ⇒ Boolean
-
#token_readable? ⇒ Boolean
False when the stored token cannot be decrypted with the keys this process has.
Class Method Details
.enable_token_encryption! ⇒ Object
Called from the engine initializer (and specs) when token encryption is enabled. Kept as an explicit toggle so a host without Active Record Encryption configured can opt out via config.encrypt_tokens = false.
22 23 24 25 |
# File 'app/models/instagram_connect/account.rb', line 22 def self.enable_token_encryption! encrypts :access_token encrypts :page_access_token end |
Instance Method Details
#api_token ⇒ Object
Every Instagram messaging call and the webhook subscription are Page-token operations. Falling back to the user token keeps a freshly connected account working until the readiness pass swaps in the Page one.
37 38 39 |
# File 'app/models/instagram_connect/account.rb', line 37 def api_token page_access_token.presence || access_token end |
#client ⇒ Object
The only place a Client should be built. Constructing one directly picks up the global auth path, which is wrong for any host with accounts on both paths — and wrong silently, which is worse.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'app/models/instagram_connect/account.rb', line 56 def client # Refuse to build a client around a token Meta can only reject, and # record WHY on the row so the host's health screen can say it out loud # instead of every screen quietly rendering empty. unless token_readable? update_columns(readiness_error: TOKEN_UNREADABLE_MESSAGE.truncate(255)) raise InstagramConnect::TokenUnreadableError, TOKEN_UNREADABLE_MESSAGE end InstagramConnect::Client.new( access_token: api_token, ig_user_id: ig_user_id, config: InstagramConnect.configuration.for_auth_path(auth_path) ) end |
#refresh_access_token! ⇒ Object
Refresh via the account's auth strategy and persist the rotated token. Refreshes via the strategy this row was connected with, not the globally configured one.
83 84 85 86 87 |
# File 'app/models/instagram_connect/account.rb', line 83 def refresh_access_token! strategy = InstagramConnect::Auth.for(InstagramConnect.configuration.for_auth_path(auth_path)) data = strategy.refresh_token(access_token: access_token) update!(access_token: data[:access_token], token_expires_at: data[:expires_at]) end |
#subscribed_field_list ⇒ Object
72 73 74 |
# File 'app/models/instagram_connect/account.rb', line 72 def subscribed_field_list subscribed_fields.to_s.split(",").map(&:strip).reject(&:empty?) end |
#token_expired? ⇒ Boolean
76 77 78 |
# File 'app/models/instagram_connect/account.rb', line 76 def token_expired? token_expires_at.present? && token_expires_at <= Time.current end |
#token_readable? ⇒ Boolean
False when the stored token cannot be decrypted with the keys this process has. Recovery is always the same: reconnect the account, which writes fresh tokens under the current keys.
44 45 46 47 |
# File 'app/models/instagram_connect/account.rb', line 44 def token_readable? token = api_token.to_s token.present? && !token.match?(ENCRYPTED_ENVELOPE) end |