fix: use Page Access Token and fix deprecated Graph API fields
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
- Use config.access_token (Page Token) instead of User Token for feed/insights
- Remove deprecated 'type' field from feed, use attachments{media_type}
- Fetch insights individually to handle unavailable metrics gracefully
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ba97a2122d
commit
147f36ab75
@ -64,7 +64,7 @@ class FacebookGraphService:
|
||||
since_365d = int((now - timedelta(days=365)).timestamp())
|
||||
|
||||
data = self._get(f'{page_id}/feed', {
|
||||
'fields': 'created_time,message,type,shares,likes.summary(true),comments.summary(true)',
|
||||
'fields': 'created_time,message,shares,likes.summary(true),comments.summary(true),attachments{media_type}',
|
||||
'since': since_365d,
|
||||
'limit': 100,
|
||||
})
|
||||
@ -98,8 +98,9 @@ class FacebookGraphService:
|
||||
result['total_comments'] += comments
|
||||
result['total_shares'] += shares
|
||||
|
||||
# Post types
|
||||
ptype = post.get('type', 'status')
|
||||
# Post types (from attachments.media_type since 'type' is deprecated)
|
||||
attachments = post.get('attachments', {}).get('data', [])
|
||||
ptype = attachments[0].get('media_type', 'status') if attachments else 'status'
|
||||
result['post_types'][ptype] = result['post_types'].get(ptype, 0) + 1
|
||||
|
||||
# Recent posts (top 5 by date)
|
||||
@ -118,32 +119,42 @@ class FacebookGraphService:
|
||||
return result
|
||||
|
||||
def get_page_insights(self, page_id: str, days: int = 28) -> Dict:
|
||||
"""Get page insights (impressions, engaged users, reactions).
|
||||
"""Get page insights (views, engagements, reactions).
|
||||
|
||||
Note: Requires page access token, not user access token.
|
||||
The page token should be stored during OAuth connection.
|
||||
Fetches metrics individually to handle deprecated/unavailable ones gracefully.
|
||||
Requires page access token, not user access token.
|
||||
"""
|
||||
since = datetime.now() - timedelta(days=days)
|
||||
until = datetime.now()
|
||||
since = int((datetime.now() - timedelta(days=days)).timestamp())
|
||||
until = int(datetime.now().timestamp())
|
||||
|
||||
metrics = 'page_impressions,page_engaged_users,page_fans,page_views_total,page_post_engagements,page_fan_adds,page_fan_removes,page_actions_post_reactions_total'
|
||||
data = self._get(f'{page_id}/insights', {
|
||||
'metric': metrics,
|
||||
'period': 'day',
|
||||
'since': int(since.timestamp()),
|
||||
'until': int(until.timestamp()),
|
||||
})
|
||||
|
||||
if not data:
|
||||
return {}
|
||||
all_metrics = [
|
||||
'page_views_total',
|
||||
'page_post_engagements',
|
||||
'page_actions_post_reactions_total',
|
||||
# These may be deprecated or require additional permissions:
|
||||
'page_impressions',
|
||||
'page_engaged_users',
|
||||
'page_fans',
|
||||
'page_fan_adds',
|
||||
'page_fan_removes',
|
||||
]
|
||||
|
||||
result = {}
|
||||
for metric in data.get('data', []):
|
||||
name = metric.get('name', '')
|
||||
values = metric.get('values', [])
|
||||
if values:
|
||||
total = sum(v.get('value', 0) for v in values if isinstance(v.get('value'), (int, float)))
|
||||
result[name] = total
|
||||
for metric_name in all_metrics:
|
||||
data = self._get(f'{page_id}/insights', {
|
||||
'metric': metric_name,
|
||||
'period': 'day',
|
||||
'since': since,
|
||||
'until': until,
|
||||
})
|
||||
if not data:
|
||||
continue
|
||||
for metric in data.get('data', []):
|
||||
name = metric.get('name', '')
|
||||
values = metric.get('values', [])
|
||||
if values:
|
||||
total = sum(v.get('value', 0) for v in values if isinstance(v.get('value'), (int, float)))
|
||||
result[name] = total
|
||||
|
||||
return result
|
||||
|
||||
@ -455,13 +466,7 @@ def sync_facebook_to_social_media(db, company_id: int) -> dict:
|
||||
from oauth_service import OAuthService
|
||||
from database import SocialMediaConfig, CompanySocialMedia
|
||||
|
||||
# 1. Get valid page access token
|
||||
oauth = OAuthService()
|
||||
token = oauth.get_valid_token(db, company_id, 'meta', 'facebook')
|
||||
if not token:
|
||||
return {'success': False, 'error': 'no_token', 'message': 'Brak aktywnego tokenu Facebook'}
|
||||
|
||||
# 2. Get page_id from SocialMediaConfig
|
||||
# 1. Get page config
|
||||
config = db.query(SocialMediaConfig).filter(
|
||||
SocialMediaConfig.platform == 'facebook',
|
||||
SocialMediaConfig.company_id == company_id,
|
||||
@ -473,6 +478,15 @@ def sync_facebook_to_social_media(db, company_id: int) -> dict:
|
||||
|
||||
page_id = config.page_id
|
||||
|
||||
# 2. Use Page Access Token (from config) — required for feed/insights.
|
||||
# Fall back to User Access Token from OAuth if page token unavailable.
|
||||
token = config.access_token
|
||||
if not token:
|
||||
oauth = OAuthService()
|
||||
token = oauth.get_valid_token(db, company_id, 'meta', 'facebook')
|
||||
if not token:
|
||||
return {'success': False, 'error': 'no_token', 'message': 'Brak aktywnego tokenu Facebook'}
|
||||
|
||||
# 3. Fetch page info from Graph API
|
||||
fb = FacebookGraphService(token)
|
||||
page_info = fb.get_page_info(page_id)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user