Explorer
/opt/struktur/asol-runtime/buffer_publish.py
← Zurück ↓ Download
import os
from buffer_bridge import BufferError, _gql, channels


def _pick_channel(token, platform):
    service = platform.lower()
    matches = [c for c in channels(token) if c.get('service') == service]
    if len(matches) != 1:
        raise BufferError(f'Expected exactly one Buffer channel for {service}, found {len(matches)}')
    return matches[0]


def create_post(token, platform, text, action='draft', due_at=None,
                media_url=None, media_kind='image', first_comment=None,
                link_url=None, post_type='post'):
    platform = platform.lower()
    if platform not in ('facebook', 'instagram', 'linkedin'):
        raise BufferError('Unsupported platform')
    channel = _pick_channel(token, platform)
    action = (action or 'draft').lower()
    if action not in ('draft', 'now', 'schedule', 'queue'):
        raise BufferError('Unsupported publish action')
    if action == 'schedule' and not due_at:
        raise BufferError('Scheduled publishing requires due_at')
    if platform == 'instagram' and action != 'draft' and not media_url:
        raise BufferError('Instagram publishing requires image or video')
    inp = {
        'text': text or '',
        'channelId': channel['id'],
        'schedulingType': 'automatic',
        'assets': [],
    }
    if action == 'draft':
        inp.update(mode='addToQueue', saveToDraft=True)
    elif action == 'now':
        inp.update(mode='shareNow', saveToDraft=False)
    elif action == 'queue':
        inp.update(mode='addToQueue', saveToDraft=False)
    else:
        inp.update(mode='customScheduled', dueAt=due_at, saveToDraft=False)
    if media_url:
        kind = 'video' if media_kind == 'video' else 'image'
        inp['assets'] = [{kind: {'url': media_url}}]
    meta = {}
    if platform == 'facebook':
        cfg = {'type': post_type or 'post'}
        if first_comment: cfg['firstComment'] = first_comment
        if link_url and not media_url: cfg['linkAttachment'] = {'url': link_url}
        meta['facebook'] = cfg
    elif platform == 'linkedin':
        cfg = {}
        if first_comment: cfg['firstComment'] = first_comment
        if link_url and not media_url: cfg['linkAttachment'] = {'url': link_url}
        if cfg: meta['linkedin'] = cfg
    else:
        cfg = {'type': post_type or 'post', 'shouldShareToFeed': True}
        if first_comment: cfg['firstComment'] = first_comment
        meta['instagram'] = cfg
    if meta:
        inp['metadata'] = meta
    mutation = '''mutation CreatePost($input: CreatePostInput!) {
      createPost(input: $input) {
        ... on PostActionSuccess { post { id text dueAt } }
        ... on MutationError { message }
      }
    }'''
    result = _gql(token, mutation, {'input': inp}).get('createPost') or {}
    if result.get('message'):
        raise BufferError(result['message'])
    post = result.get('post') or {}
    if not post.get('id'):
        raise BufferError('Buffer returned no post id')
    return {'post_id': post['id'], 'due_at': post.get('dueAt'),
            'channel_id': channel['id'], 'channel': channel.get('displayName') or channel.get('name')}