Volver a la wiki

Runbook · Integración Zoho ↔ Workspace · setup, autorización, troubleshooting

Runbook operativo para todo lo relacionado con la integración Zoho (Calendar + Mail) del workspace tras el pivot s68 (17-05-2026).

Arquitectura en una frase

D1 sigue siendo SoT único para tasks (KanbanMini intacto). Zoho Calendar + Mail entran como canales de acción explícita desde TaskModal — la task es el hub, Zoho es el brazo ejecutor. Per-user OAuth (cada miembro del staff autoriza su propia cuenta).

Quién debe leer esto

Para el usuario final

Autorizar mi cuenta Zoho (primera vez)

  1. Inicia sesión en el workspace con tu email @esfericlabs.com.
  2. Visita https://workspace.crearack.com/settings/integrations/zoho/.
  3. En tu propia card pulsa “Conectar Zoho”.
  4. Zoho te pide login con tus credenciales y muestra el consent screen. Acepta todos los permisos.
  5. Volverás a la página con tu card marcada como “Conectado”.

Crear una task con evento Calendar (manual)

  1. Modal “Nueva tarea” → título + assignees + due_date.
  2. Despliega ”+ Crear evento” → ajusta start/end → “Añadir a la tarea”.
  3. (Opcional) ”+ Vincular email” → busca un email del Mail → selecciona.
  4. Pulsa Crear.
  5. La task aparece en KanbanMini con badge 1 evento (o 2 eventos).

Crear/cerrar una task (automático)

Cuando creas una task con assignees + due_date, automáticamente:

Cuando pasas la task a Completada:

Cuando borras la task:

Truco operativo

Si refrescas el Zoho Calendar y no aparecen los cambios, recarga con Ctrl+Shift+R o reset de sesión. El cliente Zoho cachea aggressivamente. Los eventos sí están creados — es solo cosmética del navegador.

Para el administrador (Edu)

Autorizar Zoho en nombre de Dani o Txell (modo admin)

Útil para pre-configurar las cuentas antes del onboarding.

1. mail.zoho.eu → avatar → Sign out (CADA VEZ entre miembros)
2. (cerrar la pestaña de mail.zoho.eu)
3. https://workspace.crearack.com/api/oauth/zoho/start?as=<TeamMember>
   donde <TeamMember> = Edu | Dani | Txell
4. Zoho pide login fresh → metes credenciales del miembro correcto → Accept
5. Verifica en /settings/integrations/zoho que la card muestra el email correcto
6. Repetir desde 1 para el siguiente miembro

FOOTGUN crítico: si NO haces logout en mail.zoho.eu entre cada ?as=, Zoho usa la sesión activa anterior y el token se guarda mapeado al wrong team_member. Ver memoria feedback_zoho_logout_between_admin_oauth.

Revocar el token de un miembro

Solo Edu puede revocar otros (endpoint admin):

https://workspace.crearack.com/api/zoho/admin-revoke?member=Dani
https://workspace.crearack.com/api/zoho/admin-revoke?member=Txell

Cada miembro puede revocar el suyo desde /settings/integrations/zoho con el botón “Revocar” en su propia card.

Verificar estado de las 3 cuentas

https://workspace.crearack.com/api/zoho/status

Devuelve JSON con members[] (los 3) + current (el actor del request).

Diagnosticar fallo de DELETE/UPDATE auto-events

https://workspace.crearack.com/api/zoho/calendar/debug-close

Auto-detecta la task más reciente con auto_end_planned y ejecuta el DELETE síncrono devolviendo el response Zoho raw. Útil cuando un cierre de task no borra el evento “Fin previsto” en Zoho.

Para el operador de incidentes

Síntoma: el panel dice “sesión actual desconocida” / botón Re-autorizar no aparece

Causa: el header Cf-Access-Authenticated-User-Email no llega y el mapeo STAFF_EMAIL_TO_NAME en functions/_lib/staff.ts no resuelve al usuario.

Fix:

  1. Verificar que el email CF Access del usuario está en STAFF_EMAIL_TO_NAME. Si no, actualizar el código.
  2. Si está, comprobar que CF Access tiene “Include identity in JWT” activado. El fallback JWT decode requiere el claim email en el JWT.

Ver memoria footguns_staff_email_mapping_workspace.

Síntoma: la task se cierra pero el evento “Fin previsto” sigue en Zoho

Causa probable: scope ZohoCalendar.event.DELETE no autorizado en el token actual, o el header etag no se está mandando en el DELETE.

Diagnóstico:

  1. /api/zoho/calendar/debug-close → mira el JSON.
    • Si devuelve status: 400 ETAG_MISSING → bug en el código (regresión).
    • Si devuelve status: 401 o 403 → token sin scope DELETE. Re-autorizar.
    • Si devuelve status: 204 o 200 → arreglado, sigue normal.
  2. Verificar que todos los miembros tienen scope DELETE/UPDATE en su autorización actual (re-autorizar tras cualquier cambio en ZOHO_SCOPES).

Ver memoria footguns_zoho_calendar_etag_required.

Síntoma: las 3 cards muestran la misma cuenta Zoho

Causa: Edu autorizó las 3 cuentas sin hacer logout en mail.zoho.eu entre cada ?as=. Zoho usó la misma sesión activa para los 3 consents.

Fix:

  1. Revocar los tokens cruzados: admin-revoke?member=Dani + admin-revoke?member=Txell.
  2. Re-autorizar siguiendo el protocolo arriba (logout entre cada).

Síntoma: hooks auto fallan silenciosamente

Los hooks onTaskCreated / onTaskUpdated / onTaskDeleted corren en context.waitUntil (background). Si fallan, log con console.warn. Para inspeccionar:

  1. wrangler tail crearacksl-workspace (en local con auth).
  2. Filtrar por [task-zoho-auto].
  3. Identificar la causa (scope, ETag, calendar no encontrado, etc).

Schema D1 relevante

TablaPropósito
zoho_oauth_tokensTokens per-user. PK team_member. Columnas: zoho_email, refresh_token, access_token, dc, granted_by_cf_email.
zoho_oauth_stateState efímero anti-CSRF del flujo OAuth (TTL 1h).
task_calendar_eventsVínculos task ↔ evento Calendar. PK (task_id, zoho_event_uid). Columna link_type distingue manual de los 3 tipos auto.
task_emailsVínculos task ↔ mensaje Mail. PK (task_id, zoho_message_id).

Endpoints relevantes

EndpointFunción
GET /api/meIdentidad del actor (resuelve email + team_member).
GET /api/zoho/statusEstado de las 3 cuentas + actor actual.
DELETE /api/zoho/statusRevocar token del actor (no de otros).
GET /api/oauth/zoho/start[?as=X]Inicia OAuth para sí mismo o (admin Edu) para otro.
GET /api/oauth/zoho/callbackCallback Zoho. Público (en PUBLIC_PATHS).
GET /api/zoho/admin-revoke?member=XRevocar token de cualquier miembro (solo Edu).
GET /api/zoho/calendar[?from=&to=]Eventos del calendar del actor.
POST /api/zoho/calendarCrear evento manual con organizer + attendees.
GET /api/zoho/mail/search?q=&from=&subject=Picker emails para vincular.
GET /api/zoho/mail/compose-url?subject=&body=Deep-link Zoho Mail compose.
GET/POST/DELETE /api/tasks/{id}/links/calendarCRUD vínculos eventos por task.
GET/POST/DELETE /api/tasks/{id}/links/emailCRUD vínculos emails por task.
GET /api/zoho/calendar/debug-closeDebug DELETE síncrono de auto_end_planned. Solo Edu.

Scopes Zoho activos (s68)

Cualquier cambio en estos scopes requiere re-autorización de las 3 cuentas.

Limitaciones conocidas

  1. Cambiar assignees de una task después de crear NO propaga a los eventos auto ya creados. Los nuevos assignees no aparecen como attendees.
  2. Refresh UI Zoho lento: los cambios aparecen tras refresh manual del navegador (~10-30 s).
  3. Sesión Zoho compartida en navegador entre cuentas → ojo al modo admin ?as= (ver footgun).
  4. Multi-region: solo testeado en dc=eu. Para dc=com o dc=in debería funcionar igual pero sin verificación.

Véase también

Subir