Plant Cerebro
← datos
datoactivo21/09

Los avisos de objetivos salen por Apps Script con MailApp, no por el worker; y por qué

Decidido el 2-sep-2026 con Gabriel: cuando un líder propone un objetivo le llega un mail a

Dirección, y cuando Dirección aprueba o devuelve le llega al líder.

Sale del Apps Script de la planilla BASE OBJETIVOS, no del worker. El worker no puede

mandar mail sin contratar un proveedor y guardar una API key; el Apps Script usa MailApp,

manda desde plant.com.ar y no necesita ninguna credencial nueva. Trigger cada 15 minutos

(pi_avisos), separado del refresco diario de la planilla (pi_actualizar), para que los

avisos no esperen 24 horas.

Se agregó al scope de OAuth antes de la primera autorización, a propósito: si se agregaba

después, Gabriel tenía que volver a autorizar.

Dedup: Script Property PI_ULTIMO_AVISO guarda el último n de la bitácora notificado.

En la primera corrida se pone al día sin mandar la historia por mail — si no, salían 7

mails de eventos viejos de golpe.

Se agregó el motivo de devolución al panel (/aprobar acepta motivo, va al evento y al

mail). Sin eso el mail decía "te lo devolvieron" y nada más, que es peor que no avisar.

Los mails siguen las reglas de Gmail que ya costaron un bloque invisible: Verdana, **fondo claro

con texto oscuro siempre**, bloques de color con <table bgcolor> + style, jerarquía con

border-left:5px, y sin URLs (Gmail las reescribe y mutila el texto visible). Se referencia

"el panel de Objetivos" por nombre. Hay pi_mailPrueba() que manda las tres plantillas con

datos reales a quien la corre, para revisarlas antes de que le lleguen al equipo.

Remitente: avisos@plant.com.ar — es la decisión D8 del plan de tableros. Quedó

registrado ahí que un Grupo de Google o un alias es gratis (no consume licencia de Workspace;

sólo una cuenta completa nueva paga), y que la idea es un remitente no-reply para que los líderes

no le contesten al mail.

No usar GmailApp. Para mandar con otro remitente exige el scope https://mail.google.com/,

que en la pantalla de consentimiento dice *"leer, redactar, enviar y eliminar permanentemente

correos de Gmail"* — acceso total a la casilla del CEO para un script que manda tres avisos por mes.

Gabriel estuvo a punto de aceptarlo; frenarlo fue lo correcto.

En su lugar: API de Gmail directa con UrlFetchApp + ScriptApp.getOAuthToken(), y los scopes

declarados a mano en appsscript.json (hay que activar "Mostrar el archivo de manifiesto" en

Configuración del proyecto). Quedan seis, todos mínimos: spreadsheets.currentonly,

script.external_request, script.scriptapp, userinfo.email, gmail.send (mandar, no leer

ni borrar) y gmail.settings.basic (ver qué remitentes están habilitados).

POST /gmail/v1/users/me/messages/send con un RFC822 crudo en base64 web-safe; el asunto va en

RFC 2047 para que no se rompan los acentos. Gmail valida que el From sea un remitente habilitado.

El remitente sólo funciona si la dirección está dada de alta como "Enviar como"

en la cuenta que autorizó el script. Si no lo está, pi_enviar() manda

igual desde la cuenta y lo deja anotado en el log con replyTo al alias — un aviso que llega con

el remitente equivocado es mejor que uno que no llega. Se cambia sin tocar código con la propiedad

PI_REMITENTE. pi_alias() lista qué direcciones puede usar la cuenta.

No-reply: el Reply-To apunta siempre a avisos@, salga de donde salga, para que una

respuesta nunca caiga en la casilla personal; y el pie del mail lo dice ("no respondas a este

correo, la casilla no se lee").

Cambiar los scopes obliga a re-autorizar.

avisos@plant.com.ar es un Grupo de Google en modo "solo anuncio", no una casilla. Ese modo

es justo lo que traba la configuración: Gmail exige mandar un **código de verificación a esa

dirección** para habilitarla en "Enviar como", y un grupo solo-anuncio no le entrega a nadie.

Mauro chocó con lo mismo el 1-sep ("me pide que se verifique desde la casilla").

Se destraba así: en groups.google.com abrir temporalmente "Quién puede publicar" a cualquiera,

estar como miembro con entrega de todos los mensajes, hacer la verificación en Gmail (tildando

"Tratar como alias"), y volver el grupo a solo-anuncio. El alias sobrevive. Hay que hacerlo

por persona: cada cuenta que quiera mandar como avisos@ necesita su propia entrada.

Diseño de los mails: la estructura salió del aviso "Pedidos pendientes categoría A" de Mauro

— cabecera negra con la marca, banda lila con el título, tarjeta blanca sobre fondo gris. Es mejor

que un cuerpo suelto. Lo que NO se le copió: sus dos columnas width="50%" no colapsan en celular,

y sus listas alfabéticas no priorizan (19 marcas sin decir cuál urge). Nuestros mails van con

números y contexto en vez de listas.

Ver plant-objetivos-panel.

Datos/plant-avisos-objetivos-mail