Skip to content
Menu Academia

O ciclo de vida de formulários pela CLI: criar, configurar, enviar, transicionar

Crie um formulário de ponta a ponta — estados de workflow, audiências de permissão, roteamento de aprovação, lógica de perguntas — depois conduza todo o ciclo de vida das suas respostas pela CLI ou API, incluindo botões callback_form.

deep-diveDesenvolvedorOps12 min read

Formulários no Dailybot não são apenas um coletor de respostas — eles carregam estados de workflow, três audiências de permissão independentes, roteamento de aprovação e um atalho de ChatOps, e cada uma dessas superfícies é programável de ponta a ponta. Este passo a passo constrói um formulário do zero, conecta seu ciclo de vida e conduz respostas por ele — além do detalhe que conecta formulários de volta ao envio de mensagens: os botões callback_form.

Criando um formulário: tudo de uma vez vs. incremental

Um formulário precisa de um nome e pelo menos uma perguntacreate com um conjunto de perguntas vazio falha com 400 questions_required. Dois estilos de autoria, mesmo vocabulário de flags:

# One-shot: everything in a single call
FID=$(dailybot form create -n "Code Release Form" --active \
  --state "Draft:#9CA3AF" --state "Review:#F59E0B" --state "Released:#10B981" \
  --report-channel "$RELEASES_CHANNEL_UUID" \
  --approval --approver-team "Release Managers" \
  --command release \
  --questions-file q.json --json | jq -r '.uuid')

# Incremental: create bare, then shape it
dailybot form create -n "Code Release Form" --questions-file q.json --json
dailybot form config "$FID" --state "Draft:#9CA3AF" --state "Review:#F59E0B"

form config é uma atualização parcial completa: envie apenas as flags que quer mudar, e o resto permanece como está. É um superset estrito de form edit (apenas nome + canais de relatório) — prefira config para qualquer coisa além disso.

Estados de workflow — forma de escrita vs. forma de leitura

dailybot form config "$FID" \
  --state "Draft:#9CA3AF" --state "Review:#F59E0B" --state "Released:#10B981"

# Turn the workflow off entirely
dailybot form config "$FID" --no-workflow

Você escreve {label, color} por estado, ordenado pela posição da flag — o servidor deriva key (rótulo slugificado) e order (posição) para você. form get retorna cada estado como {key, label, color, order} dentro de workflow.states, mais workflow.enabled: true. Passar qualquer flag --state habilita o workflow; habilitá-lo com zero estados é inválido (workflow_requires_states); máximo de 20 estados.

Audiências de permissão — três controles independentes

--can-edit, --can-see e --can-change-states são independentes, cada uma sendo everyone / owner_and_admins / restricted:

dailybot form config "$FID" \
  --can-see everyone \
  --can-edit owner_and_admins \
  --change-states-user [email protected] \
  --change-states-team "Release Managers"

Passar uma flag --change-states-user/-team implica restricted para aquela audiência automaticamente. Cada audiência é substituição completa: os usuários/equipes que você envia se tornam o conjunto novo inteiro; uma audiência restricted com listas vazias significa “somente owner + admins.”

Roteamento de aprovação e o comando de ChatOps

dailybot form config "$FID" \
  --approval --approver-team "Release Managers" --approver-user [email protected] \
  --command release

Novos envios passam pela lista de aprovadores (substituição completa; --no-approvers a limpa, --no-approval desativa o roteamento) antes de contar como finais. --command release vincula @dailybot release como um atalho de ChatOps que abre este formulário — o charset do comando é [a-z0-9][a-z0-9_-]{0,30}, único por organização (command_already_exists se já estiver em uso); --no-command o desvincula.

Formulários públicos

dailybot form create -n "Q3 NPS Survey" \
  --anonymous --public --brand --require-identity \
  --report-channel "$SURVEYS_CHANNEL_UUID" --questions-file nps.json

--public expõe uma public_url (https://app.dailybot.com/forms/<uuid>/responses/create/) que qualquer pessoa pode abrir sem uma conta Dailybot; null quando desligado. Combine com --require-identity para tornar email + nome de quem envia obrigatórios, e --brand para exibir o logo da organização. Diferente do anonimato de check-ins, --anonymous em um formulário pode ser alternado livremente em ambas as direções.

Autoria de perguntas

O modelo de pergunta tem exatamente quatro tipos — text, multiple_choice (precisa de --options "A,B,C"), boolean (sem opções), numeric:

dailybot form questions add "$FID" --type text \
  --question "Service name?" --short-question "Service" --required

dailybot form questions add "$FID" --type multiple_choice --options "Standard,Hotfix" \
  --question "Release type?" --short-question "Type" --required

--short-question (o título do relatório, ≤ 512 caracteres) é obrigatório em add — passe-o explicitamente, ou --ai-short-question para deixar o servidor gerar um. Em edit, o título do relatório não é obrigatório (edições são parciais). --variation adiciona até 10 formas alternativas de fraseado mostradas a diferentes respondentes.

Lógica condicional

dailybot form questions add "$FID" \
  --type multiple_choice --options "Yes,No" \
  --question "Did all tests pass?" --short-question "Tests passed" \
  --jump-if-equals "No" --jump-to 5 --else-jump-to 3

O objeto completo (o que --logic-file aceita, e o que as flags inline constroem):

{
  "rules": {
    "rules_if": [
      {"conditions": [{"operator": "is_equal_to", "comparison_value": "No", "logic_connector": "and"}],
       "then": {"action": "jump_to", "target": 5}}
    ],
    "rules_else": {"action": "jump_to", "target": -1}
  }
}

rules_else é obrigatório; target: -1 significa “pular para o final.” Os saltos são somente para frente — o alvo deve exceder o índice da pergunta atual, ou ser -1. As ações são jump_to (índice de pergunta), trigger_checkin (um UUID de check-in), ou trigger_form (encadear para outro formulário inteiro — útil para rotear uma resposta “Hotfix” para um formulário dedicado de intake de hotfix). Excluir ou reordenar perguntas ajusta automaticamente qualquer alvo de salto órfão.

# Reorder — pass the COMPLETE set of question UUIDs, in the new order
dailybot form questions reorder "$FID" "$Q3" "$Q1" "$Q2"

Lendo o vocabulário do ciclo de vida

Toda resposta em um formulário com workflow habilitado carrega cinco campos — nunca infira uma transição a partir de um rótulo, sempre leia allowed_transitions:

Campo Significado
current_state O estado efetivo da resposta agora
allowed_transitions [{to_state, label}] — movimentos que este chamador pode fazer, computados pelo servidor
can_change_state Se o chamador está na audiência de mudança de estado
allow_reopen_from_final_state Se um estado terminal é reversível
state_history Log somente-append de {from_state, to_state, actor_name, at}

Enviando, atualizando, transicionando

# Submit
dailybot form submit "$FID" --content '{"<q_summary>":"Auth service v2.1","<q_type>":"Standard"}' --yes

# Automation submission, no submitter shown, with provenance
dailybot form submit "$FID" --content '{"<q_summary>":"done"}' --yes --automation \
  --guest-name "Release Bot" --guest-email "[email protected]" \
  --source "workflow:production-deploy"

# Update an in-progress response (own responses only — never another user's)
dailybot form update "$FID" "$RID" --content '{"<q_summary>":"Auth service v2.1.1"}' --yes

# Transition once allowed_transitions is non-empty
dailybot form transition "$FID" "$RID" released --yes

--automation esconde o remetente por completo nas notificações de canal; --anonymous o substitui por um nome gerado aleatoriamente; combinados, automation prevalece para a notificação. Nenhum dos dois afeta quem é o dono da resposta. transition aceita tanto a chave técnica to_state quanto o label de exibição (sem diferenciar maiúsculas/minúsculas, resolvido automaticamente) da própria lista allowed_transitions daquela resposta — nunca um estado que você apenas espera que exista. As atualizações são estritamente próprias-apenas do lado do servidor, mesmo para admins (form_response_not_found caso contrário, e não um vazamento de permissão).

Conectando o envio de mensagens a formulários: callback_form

Um botão de send-message com callback_form abre exatamente este formulário para o usuário que clicou, através da UI normal de formulários — sem request externo, sem encaminhamento de payload, sem contornar o ciclo de vida acima:

curl -sS -X POST 'https://api.dailybot.com/v1/send-message/' \
  -H 'X-API-KEY: $DAILYBOT_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "message": "Ready to log a release?",
    "target_channels": ["C0123456789"],
    "buttons": [
      {"label": "Open release form", "button_type": "interactive", "value": "open_release_form",
       "callback_form": "'"$FID"'"}
    ]
  }'

callback_form aceita apenas o UUID do formulário (liste com dailybot form list --json) — nomes e slugs são rejeitados. Um formulário desconhecido ou arquivado retorna 400 button_callback_form_not_found. Uma vez aberto, tudo acima — tipos de pergunta, lógica condicional, estados de workflow, transições — se aplica exatamente como se o usuário tivesse aberto o formulário diretamente.

Referências cruzadas

Navegue pelo hub de Soluções para o passeio voltado ao produto do ciclo de vida de formulários.

FAQ

Qual é o mínimo necessário para criar um formulário?
Um nome e pelo menos uma pergunta. dailybot form create -n NAME sem perguntas falha rapidamente com 400 questions_required — semeie ao menos uma pergunta inline via --questions-file ou --interactive, ou adicione uma logo depois via form questions add.
Como funcionam os estados de workflow de um formulário?
Passe uma ou mais flags --state "Label:#color" em create ou config — passar qualquer flag --state habilita o workflow, e a ordem das flags define a sequência de estados. O servidor deriva uma chave slugificada e uma ordem numérica para você; você só escreve {label, color}. --no-workflow limpa os estados e desliga o workflow.
Qual a diferença entre um botão callback_form e enviar um formulário pela CLI?
callback_form é um campo em um botão de send-message que abre um formulário interno do Dailybot para o usuário que clicou preencher, através da UI normal de formulários — sem request externo, sem encaminhamento de payload. Ele conecta o envio de mensagens ao ciclo de vida de um formulário existente, em vez de pré-preenchê-lo ou contorná-lo.
Como movo a resposta de um formulário entre estados de workflow?
dailybot form transition <form_uuid> <response_uuid> <to_state> --yes, onde to_state pode ser tanto a chave técnica quanto o rótulo de exibição da própria lista allowed_transitions daquela resposta — nunca um nome de estado que você apenas supõe estar disponível.
Qual a diferença entre form config e form edit?
form config é um superset completo de atualização parcial cobrindo nome, estados de workflow, as três audiências de permissão, roteamento de aprovação e o comando de ChatOps — envie apenas as flags que quer alterar. form edit só altera o nome e os canais de relatório; prefira form config para qualquer coisa além disso.