Explorer
/opt/struktur/asol-runtime/buffer_bridge.py
← Zurück ↓ Download
import json
import os
from urllib.request import Request, urlopen

API_URL = "https://api.buffer.com"

class BufferError(RuntimeError):
    pass

def _gql(token, query, variables=None):
    payload = {"query": query}
    if variables is not None:
        payload["variables"] = variables
    req = Request(API_URL, data=json.dumps(payload).encode("utf-8"), headers={
        "Authorization": "Bearer " + token,
        "Content-Type": "application/json",
    })
    with urlopen(req, timeout=20) as response:
        data = json.load(response)
    if data.get("errors"):
        raise BufferError(data["errors"][0].get("message", "Buffer GraphQL error"))
    return data.get("data") or {}

def _account(token):
    return _gql(token, "{ account { organizations { id name } } }")

def channels(token, organization_id=None):
    if not organization_id:
        orgs = _account(token).get("account", {}).get("organizations", [])
        if len(orgs) != 1:
            raise BufferError("Buffer account must expose exactly one organization")
        organization_id = orgs[0]["id"]
    query = '''query Channels($org: OrganizationId!) {
      channels(input: {organizationId: $org}) { id name displayName service isQueuePaused }
    }'''
    return _gql(token, query, {"org": organization_id}).get("channels", [])

def create_draft(token, platform, text, organization_id=None):
    service = "instagram" if platform == "reels" else platform
    matches = [c for c in channels(token, organization_id) if c.get("service") == service]
    if len(matches) != 1:
        raise BufferError(f"Expected exactly one Buffer channel for {service}, found {len(matches)}")
    channel = matches[0]
    mutation = '''mutation CreateDraft($input: CreatePostInput!) {
      createPost(input: $input) {
        ... on PostActionSuccess { post { id text } }
        ... on MutationError { message }
      }
    }'''
    variables = {"input": {
        "text": text,
        "channelId": channel["id"],
        "schedulingType": "automatic",
        "mode": "addToQueue",
        "saveToDraft": True,
    }}
    result = _gql(token, mutation, variables).get("createPost") or {}
    if result.get("message"):
        raise BufferError(result["message"])
    post = result.get("post")
    if not post or not post.get("id"):
        raise BufferError("Buffer returned no post id")
    return {"post_id": post["id"], "channel_id": channel["id"], "channel": channel.get("displayName") or channel.get("name"), "service": service}

def token_from_env(name):
    token = os.environ.get(name, "").strip()
    if not token:
        raise BufferError(f"Missing {name}")
    return token