cms.c2sgmbh/src/collections/SocialPlatforms.ts
Martin Porwoll b107d60183 feat(community): Phase 2.3 - Meta (Facebook + Instagram) Integration
Implements complete Meta Graph API integration for Facebook Pages
and Instagram Business Accounts.

Phase 2.3a - Meta OAuth & Base Infrastructure:
- Meta OAuth service with long-lived token support (60 days)
- MetaBaseClient with error handling and retry logic
- OAuth routes (/api/auth/meta, /api/auth/meta/callback)
- Type definitions for all Meta API responses

Phase 2.3b - Facebook Client:
- FacebookClient extending MetaBaseClient
- Page posts and comments retrieval
- Comment moderation (reply, hide, delete, like)
- Messenger conversations support
- Page insights and analytics
- FacebookSyncService for comment synchronization

Phase 2.3c - Instagram Client:
- InstagramClient for Business Accounts
- Media (posts/reels/carousels) retrieval
- Comment management with replies
- Mentions and Story-Mentions (24h expiry)
- Instagram Direct messaging
- Account and media insights
- InstagramSyncService for comment/mention sync

Additional changes:
- SocialPlatforms collection extended with oauthEndpoint field
- Environment variables documented (META_APP_ID, META_APP_SECRET)
- Module index with all exports

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 21:28:40 +00:00

252 lines
6.4 KiB
TypeScript

// src/collections/SocialPlatforms.ts
import type { CollectionConfig } from 'payload'
import { isCommunityManager, hasCommunityAccess } from '../lib/communityAccess'
/**
* SocialPlatforms Collection
*
* Definiert unterstützte Social Media Plattformen mit API-Konfiguration.
* Teil des Community Management Systems.
*/
export const SocialPlatforms: CollectionConfig = {
slug: 'social-platforms',
labels: {
singular: 'Social Platform',
plural: 'Social Platforms',
},
admin: {
group: 'Community',
useAsTitle: 'name',
defaultColumns: ['name', 'slug', 'isActive', 'apiStatus'],
},
access: {
read: hasCommunityAccess,
create: isCommunityManager,
update: isCommunityManager,
delete: isCommunityManager,
},
fields: [
{
type: 'row',
fields: [
{
name: 'name',
type: 'text',
required: true,
label: 'Name',
admin: { width: '50%' },
},
{
name: 'slug',
type: 'text',
required: true,
unique: true,
label: 'Slug',
admin: { width: '50%' },
},
],
},
{
type: 'row',
fields: [
{
name: 'icon',
type: 'text',
label: 'Icon (Emoji)',
admin: {
width: '25%',
placeholder: '📺',
},
},
{
name: 'color',
type: 'text',
label: 'Brand Color',
admin: {
width: '25%',
placeholder: '#FF0000',
},
},
{
name: 'isActive',
type: 'checkbox',
label: 'Aktiv',
defaultValue: true,
admin: { width: '25%' },
},
{
name: 'apiStatus',
type: 'select',
label: 'API Status',
options: [
{ label: 'Verbunden', value: 'connected' },
{ label: 'Eingeschränkt', value: 'limited' },
{ label: 'Nicht verbunden', value: 'disconnected' },
{ label: 'In Entwicklung', value: 'development' },
],
defaultValue: 'disconnected',
admin: { width: '25%' },
},
],
},
// API Configuration
{
name: 'apiConfig',
type: 'group',
label: 'API Konfiguration',
admin: {
condition: (data) => data?.isActive,
},
fields: [
{
name: 'apiType',
type: 'select',
label: 'API Type',
options: [
{ label: 'YouTube Data API v3', value: 'youtube_v3' },
{ label: 'LinkedIn API', value: 'linkedin' },
{ label: 'Instagram Graph API', value: 'instagram_graph' },
{ label: 'Facebook Graph API', value: 'facebook_graph' },
{ label: 'Meta Graph API (FB + IG)', value: 'meta_graph' },
{ label: 'Custom/Webhook', value: 'custom' },
],
},
{
name: 'baseUrl',
type: 'text',
label: 'Base URL',
admin: {
placeholder: 'https://www.googleapis.com/youtube/v3',
},
},
{
name: 'authType',
type: 'select',
label: 'Auth Type',
options: [
{ label: 'OAuth 2.0', value: 'oauth2' },
{ label: 'API Key', value: 'api_key' },
{ label: 'Bearer Token', value: 'bearer' },
],
},
{
name: 'oauthEndpoint',
type: 'text',
label: 'OAuth Endpoint',
admin: {
description: 'Relativer API-Pfad für OAuth-Initiation (z.B. /api/youtube/auth)',
placeholder: '/api/youtube/auth',
condition: (data, siblingData) => siblingData?.authType === 'oauth2',
},
},
{
name: 'scopes',
type: 'array',
label: 'OAuth Scopes',
admin: {
condition: (data, siblingData) => siblingData?.authType === 'oauth2',
},
fields: [{ name: 'scope', type: 'text', label: 'Scope' }],
},
{
name: 'tokenValidityDays',
type: 'number',
label: 'Token Gültigkeit (Tage)',
defaultValue: 60,
admin: {
description: 'Wie lange ist der Access Token gültig? (YouTube: unbegrenzt mit Refresh, Meta: 60 Tage)',
condition: (data, siblingData) => siblingData?.authType === 'oauth2',
},
},
],
},
// Interaction Types für diese Plattform
{
name: 'interactionTypes',
type: 'array',
label: 'Interaction Types',
fields: [
{
type: 'row',
fields: [
{
name: 'type',
type: 'text',
required: true,
label: 'Type',
admin: {
width: '30%',
placeholder: 'comment',
},
},
{
name: 'label',
type: 'text',
required: true,
label: 'Label',
admin: {
width: '30%',
placeholder: 'Kommentar',
},
},
{
name: 'icon',
type: 'text',
label: 'Icon',
admin: {
width: '20%',
placeholder: '💬',
},
},
{
name: 'canReply',
type: 'checkbox',
label: 'Reply möglich',
defaultValue: true,
admin: { width: '20%' },
},
],
},
],
},
// Rate Limits
{
name: 'rateLimits',
type: 'group',
label: 'Rate Limits',
fields: [
{
type: 'row',
fields: [
{
name: 'requestsPerMinute',
type: 'number',
label: 'Requests/Minute',
admin: { width: '33%' },
},
{
name: 'requestsPerDay',
type: 'number',
label: 'Requests/Tag',
admin: { width: '33%' },
},
{
name: 'quotaUnitsPerDay',
type: 'number',
label: 'Quota Units/Tag',
admin: {
width: '33%',
description: 'YouTube: 10.000/Tag',
},
},
],
},
],
},
],
timestamps: true,
}