Gera certificados em PDF a partir do template do evento e do export de check-in da bilheteria, e envia por e-mail: um e-mail por caixa, anexos com nome legível, log idempotente. Na Python Nordeste 2026 isso virou 281 certificados (participantes, 6 turmas de tutorial, palestrantes e instrutores) entregues em 155 caixas de e-mail, num envio só, sem duplicata.
Este repositório foi inteiramente escrito por IA. Os dois scripts, este README e o AGENTS.md foram produzidos pelo Claude (Anthropic), em sessões de Claude Code conduzidas por Luis Gustavo Mota, da organização da PyNe 2026. As regras de negócio (quem recebe, como desempatar, texto dos e-mails) foram decisões humanas da organização; o código, as medições de template e os textos daqui são do modelo. Leve isso em conta ao revisar: o código foi auditado em uso real, mas ninguém digitou uma linha dele à mão.
Os scripts funcionam de verdade, mas quase tudo neles é fato do NOSSO evento, não parâmetro: as colunas do export do Pretix, o formato do nome do produto ("Tutoriais - manhã – Título, 13/08, das 09:30 às 11:30"), a geometria dos templates feitos no Canva (medida dos próprios PDFs e gravada em constantes), as regras de quem recebe certificado.
Se o seu evento usa outra bilheteria (não Pretix), outro CFP (não pretalx), ou outro template, não rode às cegas. O caminho certo é entregar este repositório a um agente de IA (ou a um humano paciente) junto com o AGENTS.md, que lista o que é específico e como re-derivar cada parte. Foi pensado pra isso: a Python Brasil 2026 (acontecendo agora, outubro) é o primeiro teste dessa reutilização.
- Dados de presença. O export de check-in do Pretix (xlsx), baixado do painel do
organizador no navegador. Na PyNe, a coleta (achar nomes, conferir os check-ins das
atividades) foi feita com o Claude operando o Chrome pela extensão oficial, mas
qualquer jeito de obter o xlsx serve. Colunas usadas:
Nome do participante,Produto,Check-in realizado,Email,Data do pedido. - Quem recebe. Só quem tem check-in. Detalhe importante da PyNe: no evento principal o check-in era obrigatório pra entrar; nos tutoriais não (teve gente que registrou check-in dias depois, a pedido da organização). Essa regra é SUA decisão num outro evento.
- Qual certificado. A coluna
Produtodiz a atividade.Ingresso/Meiaviram certificado de participante;Tutoriais – <título>, <data>, das HH:MM às HH:MMvira certificado de tutorial, com título e carga horária extraídos do próprio nome do produto (nada digitado à mão). Palestrantes e instrutores vieram de um CSV montado à mão a partir da programação publicada (pretalx):Duração,Tipo,Nome,E-mail,Título da Atividade. - Check-in em dois tutoriais do mesmo horário (sala cheia, pessoa remanejada):
vale o check-in mais tarde. Empate no minuto o script não decide: avisa e você
resolve na mão (
EXCECOES). - Nomes. Title Case pt-br (
ALDO VICTORviraAldo Victor, partículas em minúsculo), grafias com e sem acento da mesma pessoa são unificadas, abreviações viram o nome mais completo (Pedro Silva+Pedro Henrique Silva= a mesma pessoa, vale o maior), e erros de digitação entram emNOMES_CORRIGIDOS. - Geração. O template PDF nunca é editado: o script desenha o nome (e, nos
tutoriais, o parágrafo inteiro com os placeholders trocados) numa camada por cima,
usando as fontes verdadeiras do template e texto justificado como no original.
Saída:
envios/<email>/<lote>/Certificado - Nome.pdf+ umindice.csv. - Envio. SMTP do Gmail com senha de app, um e-mail por caixa (quem comprou
ingresso pra outras pessoas recebe tudo junto, com os nomes nos arquivos), texto
singular/plural/grupo conforme o caso, pausa de 2s, log em
enviados.csvque torna o reenvio idempotente, e confirmação digitandoENVIAR. O envio é sempre rodado por um humano, nunca pelo agente.
Dependências de geração: pip install openpyxl pypdf pikepdf reportlab fonttools.
O envio é só biblioteca padrão.
# gerar
python gerar_certificados.py --tutoriais # lista os tutoriais achados no export
python gerar_certificados.py --conflitos # choques de horário e como resolveu
python gerar_certificados.py --evento principal
python gerar_certificados.py --evento fastapi # qualquer trecho do título serve
python gerar_certificados.py --ministrantes Tutorial
python gerar_certificados.py --ministrantes Palestra
# enviar (rodado por humano, nessa ordem)
python enviar_certificados.py --lote tudo --dry-run
python enviar_certificados.py --lote tudo --teste voce@gmail.com # 3 exemplos pra você
python enviar_certificados.py --lote tudo # pede confirmaçãoSe você é um agente adaptando isto pra outro evento: leia AGENTS.md antes de tocar em qualquer arquivo. Ele lista o que é fato da PyNe disfarçado de código, as sete armadilhas que custaram horas (MediaBox do Canva, fontes variáveis, justificação...), e a ordem certa de re-derivar tudo.
