El ciclo de vida de formularios desde la CLI: crear, configurar, enviar, transicionar
Crea un formulario de punta a punta — estados de workflow, audiencias de permisos, enrutamiento de aprobación, lógica de preguntas — y luego lleva su ciclo de vida completo de respuestas desde la CLI o la API, incluyendo botones callback_form.
Los formularios en Dailybot no son solo un recolector de respuestas — llevan estados de workflow, tres audiencias de permisos independientes, enrutamiento de aprobación, y un atajo de ChatOps, y cada una de esas superficies es scripteable de punta a punta. Este recorrido construye un formulario desde cero, arma su ciclo de vida, y lleva respuestas a través de él — más el detalle que conecta los formularios de vuelta con la mensajería: los botones callback_form.
Crear un formulario: de una sola vez vs. incremental
Un formulario necesita un nombre y al menos una pregunta — create con un conjunto de preguntas vacío falla con 400 questions_required. Dos estilos de autoría, el mismo vocabulario 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 es una actualización parcial completa: envía solo los flags que quieres cambiar, todo lo demás se mantiene igual. Es un superconjunto estricto de form edit (solo nombre + canales de reporte) — prefiere config para cualquier cosa más allá de eso.
Estados de workflow — forma de escritura vs. forma de lectura
dailybot form config "$FID" \
--state "Draft:#9CA3AF" --state "Review:#F59E0B" --state "Released:#10B981"
# Turn the workflow off entirely
dailybot form config "$FID" --no-workflow
Escribes {label, color} por estado, ordenados por posición del flag — el servidor deriva key (etiqueta en slug) y order (posición) por ti. form get devuelve cada estado como {key, label, color, order} dentro de workflow.states, más workflow.enabled: true. Pasar cualquier flag --state habilita el workflow; habilitarlo con cero estados es inválido (workflow_requires_states); máximo 20 estados.
Audiencias de permisos — tres controles independientes
--can-edit, --can-see, y --can-change-states son independientes, cada uno con valor 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"
Pasar un flag --change-states-user/-team implica restricted para esa audiencia automáticamente. Cada audiencia es de reemplazo completo — los usuarios/equipos que envías se convierten en el conjunto nuevo completo; una audiencia restricted con listas vacías significa “solo el dueño + admins.”
Enrutamiento de aprobación y el comando de ChatOps
dailybot form config "$FID" \
--approval --approver-team "Release Managers" --approver-user [email protected] \
--command release
Los envíos nuevos se enrutan a través de la lista de aprobadores (reemplazo completo; --no-approvers la limpia, --no-approval deshabilita el enrutamiento) antes de contar como finales. --command release vincula @dailybot release como un atajo de ChatOps que abre este formulario — el charset del comando es [a-z0-9][a-z0-9_-]{0,30}, único por organización (command_already_exists si ya está tomado); --no-command lo desvincula.
Formularios públicos
dailybot form create -n "Q3 NPS Survey" \
--anonymous --public --brand --require-identity \
--report-channel "$SURVEYS_CHANNEL_UUID" --questions-file nps.json
--public expone una public_url (https://app.dailybot.com/forms/<uuid>/responses/create/) que cualquiera puede abrir sin una cuenta de Dailybot; null cuando está apagado. Combínalo con --require-identity para hacer obligatorios el email y nombre de quien envía, y --brand para mostrar el logo de la organización. A diferencia de la anonimidad de los check-ins, --anonymous en un formulario se puede alternar libremente en ambas direcciones.
Autoría de preguntas
El modelo de preguntas tiene exactamente cuatro tipos — text, multiple_choice (necesita --options "A,B,C"), boolean (sin opciones), 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 (el título del reporte, ≤ 512 caracteres) es obligatorio en add — pásalo explícitamente, o usa --ai-short-question para que el servidor genere uno. En edit, el título del reporte no es obligatorio (las ediciones son parciales). --variation agrega hasta 10 frases alternativas mostradas a distintos encuestados.
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
El objeto completo (lo que acepta --logic-file, y lo que construyen los flags en línea):
{
"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 es obligatorio; target: -1 significa “saltar al final.” Los saltos son solo hacia adelante — el objetivo debe superar el índice de la pregunta actual, o ser -1. Las acciones son jump_to (índice de pregunta), trigger_checkin (un UUID de check-in), o trigger_form (encadenar a otro formulario por completo — útil para enrutar una respuesta “Hotfix” a un formulario de intake dedicado). Borrar o reordenar preguntas ajusta automáticamente cualquier objetivo de salto que quede colgando.
# Reorder — pass the COMPLETE set of question UUIDs, in the new order
dailybot form questions reorder "$FID" "$Q3" "$Q1" "$Q2"
Leer el vocabulario del ciclo de vida
Cada respuesta en un formulario con workflow habilitado lleva cinco campos — nunca infieras una transición a partir de una etiqueta, siempre lee allowed_transitions:
| Campo | Significado |
|---|---|
current_state |
El estado efectivo de la respuesta ahora mismo |
allowed_transitions |
[{to_state, label}] — movimientos que este llamante puede hacer, calculados por el servidor |
can_change_state |
Si quien llama está en la audiencia de cambio de estado |
allow_reopen_from_final_state |
Si un estado terminal es reversible |
state_history |
Log de solo-agregar {from_state, to_state, actor_name, at} |
Enviar, actualizar, transicionar
# 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 oculta al remitente por completo en las notificaciones del canal; --anonymous lo reemplaza con un nombre generado al azar; combinados, automation gana para la notificación. Ninguno afecta quién es dueño de la respuesta. transition acepta la key de máquina to_state o la etiqueta label de visualización (sin distinción de mayúsculas, resuelta automáticamente) de la propia allowed_transitions de esa respuesta — nunca un estado que simplemente esperas que exista. Las actualizaciones son estrictamente solo-propias del lado del servidor, incluso para admins (form_response_not_found en caso contrario, no una fuga de permisos).
Conectar la mensajería con los formularios: callback_form
Un botón de send-message con callback_form abre exactamente este formulario para el usuario que hizo clic, a través de la UI normal de formularios — sin request externo, sin reenvío de payload, sin saltarse el ciclo de vida de arriba:
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 recibe solo el UUID del formulario (listado vía dailybot form list --json) — nombres y slugs se rechazan. Un formulario desconocido o archivado devuelve 400 button_callback_form_not_found. Una vez abierto, todo lo de arriba — tipos de pregunta, lógica condicional, estados de workflow, transiciones — aplica exactamente igual que si el usuario hubiera abierto el formulario directamente.
Referencias cruzadas
- La API send-message, de punta a punta para el contrato completo de botones dentro del cual vive
callback_form. /es/developers/api/messaging#send-messagepara la referencia estructurada de campos./es/developers/clipara el grupo completo de comandosform.
Explora el hub de Soluciones para el recorrido orientado a producto del ciclo de vida de formularios.
FAQ
- ¿Qué es lo mínimo necesario para crear un formulario?
- Un nombre y al menos una pregunta. dailybot form create -n NAME sin preguntas falla rápido con 400 questions_required — siembra al menos una pregunta en línea vía --questions-file o --interactive, o agrega una inmediatamente después vía form questions add.
- ¿Cómo funcionan los estados de workflow de un formulario?
- Pasa uno o más flags --state "Label:#color" en create o config — pasar cualquier flag --state habilita el workflow, y el orden de los flags define la secuencia de estados. El servidor deriva una key en slug y un order numérico por ti; tú solo escribes {label, color}. --no-workflow limpia los estados y apaga el workflow.
- ¿En qué se diferencia un botón callback_form de enviar un formulario desde la CLI?
- callback_form es un campo de un botón de send-message que abre un formulario interno de Dailybot para que el usuario que hizo clic lo llene a través de la UI normal de formularios — sin request externo, sin reenvío de payload. Conecta la mensajería con el propio ciclo de vida de un formulario existente en lugar de prellenarlo o saltárselo.
- ¿Cómo muevo una respuesta de formulario entre estados de workflow?
- dailybot form transition <form_uuid> <response_uuid> <to_state> --yes, donde to_state puede ser la key de máquina o la etiqueta de visualización de la propia lista allowed_transitions de esa respuesta — nunca un nombre de estado que asumas que debería estar disponible.
- ¿Cuál es la diferencia entre form config y form edit?
- form config es un superconjunto de actualización parcial completo que cubre nombre, estados de workflow, las tres audiencias de permisos, enrutamiento de aprobación, y el comando de ChatOps — envía solo los flags que quieres cambiar. form edit solo toca el nombre y los canales de reporte; prefiere form config para cualquier cosa más allá de eso.