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

- 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:
Maciej Pienczyn 2026-03-12 12:58:24 +01:00
parent ba97a2122d
commit 147f36ab75

View File

@ -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)