Documentação

Disponível hoje: Bot de Discord com a função Conectar contas com sistemas.

Regra de ouro: o bot não pode guardar senha, e nem pedir a senha de ninguém. Tudo o que ele recebe é o ID e o nome da pessoa depois que ela autoriza no site do Bup. Quem pedir senha no chat está fora das regras e a aplicação pode ser excluída.

Autenticação

Toda chamada leva a chave da sua aplicação no cabeçalho Authorization: Bearer bup_sk_.... A chave fica visível só no momento em que é criada ou gerada de novo. Sem chave válida, a API responde 401 invalid_api_key.

Conectar contas

1. Crie o pedido

Quando alguém usar o comando de conectar no seu bot, peça um link ao Bup passando o ID da pessoa no Discord.

# POST /api/v1/link
curl -X POST https://SEU-SITE/api/v1/link \
  -H "Authorization: Bearer bup_sk_SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{"external_id": "ID_DO_DISCORD"}'

# resposta 201
{ "code": "a1b2...", "url": "https://SEU-SITE/conectar?code=a1b2...", "expires_in": 600 }

2. Mande o link para a pessoa

Ela abre a url, entra na conta Bup e toca em Autorizar. A senha dela fica só no Bup. O link vale 10 minutos.

3. Consulte o resultado

# GET /api/v1/link?code=...
curl https://SEU-SITE/api/v1/link?code=a1b2... \
  -H "Authorization: Bearer bup_sk_SUA_CHAVE"

# status: pending | approved | denied | expired
{ "status": "approved", "external_id": "ID_DO_DISCORD", "user": { "id": 7, "name": "Maria" } }

Exemplo em discord.py

import aiohttp, asyncio
KEY = "bup_sk_SUA_CHAVE"  # guarde em variável de ambiente, nunca no código público
H = {"Authorization": f"Bearer {KEY}"}

async def conectar(ctx):
    async with aiohttp.ClientSession(headers=H) as s:
        r = await (await s.post("https://SEU-SITE/api/v1/link", json={"external_id": str(ctx.author.id)})).json()
        await ctx.author.send(f"Autorize aqui: {r['url']}")
        for _ in range(60):
            await asyncio.sleep(5)
            st = await (await s.get(f"https://SEU-SITE/api/v1/link?code={r['code']}")).json()
            if st["status"] == "approved":
                return await ctx.author.send(f"Conectado como {st['user']['name']}!")
            if st["status"] in ("denied", "expired"): break

Erros

400

Faltou o external_id.

401

Chave ausente, errada ou já substituída.

404

Código inexistente ou de outra aplicação.

Boas práticas

Guarde a chave em variável de ambiente, nunca em repositório público. Não registre a url de autorização em canais abertos: envie na DM. Se suspeitar de vazamento, gere uma nova chave no painel.

Criar App