Skip to content

ComicIvans/mail-signatures

Repository files navigation

Generador de firmas para el correo

Este script de Python permite generar las firmas para el correo siguiendo un archivo de configuración correspondiente a la entidad para la que es la firma (que incluye cosas como fuentes y colores) y otro archivo con los datos de las personas para las que generar la firma.

Aquí también se guardarán todas las firmas HTML que vaya haciendo para los correos electrónicos, principalmente para:

Las firmas partieron de una base que supongo que será de @jesusjmma y, actualmente, utilizan iconos de Tabler Icons


Características

  • ✅ Generación de firmas HTML a partir de plantillas Jinja2
  • ✅ Soporte para múltiples configuraciones de organizaciones
  • ✅ Validación de datos CSV y configuración JSON
  • ✅ CLI con argumentos para automatización
  • ✅ Previsualización de firmas generadas
  • ✅ Compatibilidad mejorada con clientes de correo (uso de tablas HTML)
  • ✅ Macros reutilizables para componentes comunes
  • ✅ Accesibilidad mejorada (ARIA, textos alternativos, semántica)

Ejemplos de firmas

A continuación hay unas capturas de cómo se deberían de ver las firmas.

Ejemplo de firma de la DEFC

Cuando los iconos cargan, la firma se debería de ver así:

Firma de Iván Salido Cobo como Asesor de la DEFC en la que los iconos cargan

Y cuando no cargan, así:

Firma de Iván Salido Cobo como Asesor de la DEFC en la que los iconos no cargan

Ejemplo de firma de la DGE

Cuando los iconos cargan, la firma se debería de ver así:

Firma de Iván Salido Cobo como Vicecoordinador Académico de la DGE en la que los iconos cargan

Y cuando no cargan, así:

Firma de Iván Salido Cobo como Vicecoordinador Académico de la DGE en la que los iconos no cargan

Ejemplo de firma de AMAT

Cuando los iconos cargan, la firma se debería de ver así:

Firma de Iván Salido Cobo como Secretario de AMAT en la que los iconos cargan

Y cuando no cargan, así:

Firma de Iván Salido Cobo como Secretario de AMAT en la que los iconos no cargan

Ejemplo de firma de CREUP

Cuando los iconos cargan, la firma se debería de ver así:

Firma de Iván Salido Cobo como Vocal de Digitalización y Transparencia de CREUP en la que los iconos cargan

Y cuando no cargan, así:

Firma de Iván Salido Cobo como Vocal de Digitalización y Transparencia de CREUP en la que los iconos no cargan

Ejemplo de firma del ENEM

Cuando los iconos cargan, la firma se debería de ver así:

Firma de Iván Salido Cobo como Secretario y Tesorero del XXVI ENEM en la que los iconos cargan

Y cuando no cargan, así:

Firma de Iván Salido Cobo como Secretario y Tesorero del XXVI ENEM en la que los iconos no cargan

Cómo usar las firmas

En Thunderbird

Simplemente hay que irse a la configuración de la cuenta, marcar la casilla de utilizar un archivo como firma y seleccionar el archivo de firma descargado:

Captura de pantalla de la ventana de configuración de la cuenta de Thunderbird

En Gmail

Primero hay que abrir en el navegador el archivo HTML de la firma, seleccionarlo todo con Ctrl + A y copiarlo con Ctrl + C.

En otra ventana con Gmail, hay que irse a los ajustes, ver todos los ajustes y, en la pestaña «General», al apartado de «Firma». Se crea una firma nueva y, en el campo de texto, se pega la firma con Ctrl + V.

No olvidar tampoco cambiar los «Valores predeterminados de firma» a la firma recién creada para que aparezca y guardar los cambios con el botón del final de la página.

Captura de pantalla de la firma y los ajustes de Gmail

En Webmail

El archivo de firma es un HTML y tiene la siguiente estructura:

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title></title>
  </head>
  <body>
    <div>...</div>
  </body>
</html>

Pues para webmail recomiendo solo copiar la parte de

<div>...</div>

Y pegarla en el apartado de configuración de Webmail, en «Identidades», dándole al botón que hay más a la derecha que parece < >. Este botón es para editar la firma como HTML. Se abrirá una ventana donde hay que pegar el código copiado, sustituyendo todo lo que hubiera antes.

Captura de pantalla de la ventana de configuración de la cuenta de Webmail

¿Por qué la recomendación de copiar solo esa parte de la firma HTML?

Simplemente porque pegando todo el contenido del archivo se pone un espacio en blanco al principio de la firma y es molesto eliminarlo manualmente.

Cómo usar el script

Para generar firmas, primero hay que clonar o descargar este repositorio y tener instalado uv.

Uso básico

# Modo interactivo (por defecto)
uv run main.py

# Especificar archivo de configuración
uv run main.py -c signatures.json

# Seleccionar perfil por ID (sin interacción)
uv run main.py -p ENEM

# Especificar archivo CSV de firmas
uv run main.py -l mis_firmas.csv

# Generar índice de previsualización
uv run main.py --preview

# Modo verbose (más información)
uv run main.py -v

# Modo silencioso (solo errores)
uv run main.py -q

# Combinar opciones
uv run main.py -c config.json -p CREUP -l firmas.csv --preview

Opciones de línea de comandos

Opción Descripción
-c, --config Archivo JSON de configuración (por defecto: signatures.json)
-p, --profile Seleccionar automáticamente el perfil con el ID especificado
-l, --list Archivo CSV con la lista de firmas
--preview Generar un index.html con todas las firmas para previsualización
-v, --verbose Mostrar información detallada
-q, --quiet Modo silencioso (solo errores)

Configuración (signatures.json)

Lo primero que debes hacer es asegurarte de que tienes definida la configuración del tipo de firma en el archivo signatures.json. El archivo debe de seguir la siguiente estructura:

[
  {
    "id": "EJEMPLO",
    "template": "original",
    "output_path": "EJEMPLO",
    "main_font": "Montserrat",
    "name_font": "Open Sans",
    "name_image": {
      "image": "https://example.com/logo.png",
      "description": "Logo de Mi Organización"
    },
    "color": "#3EB1C8",
    "organization": "Mi Organización",
    "organization_extra": "Entidad Superior (opcional)",
    "phone": "123 456 789",
    "phone_country_code": "+34",
    "internal_phone": "12345",
    "opt_mail": "info@ejemplo.es",
    "max_width": 315,
    "links": [
      {
        "url": "https://ejemplo.es",
        "image": "https://example.com/web-icon.png",
        "alt": "🌐",
        "description": "Sitio web de ejemplo"
      }
    ],
    "sponsor_text": "Con la colaboración de:",
    "sponsors": [
      {
        "url": "https://sponsor.com",
        "image": "https://sponsor.com/logo.png",
        "alt": "Sponsor",
        "description": "Patrocinador principal",
        "width": 100,
        "height": 50
      }
    ],
    "supporter_text": "Con el apoyo de:",
    "supporters": [
      {
        "url": "https://supporter.com",
        "image": "https://supporter.com/logo.png",
        "alt": "Supporter",
        "description": "Colaborador",
        "height": 55
      }
    ],
    "footer_address": "Calle Ejemplo, 123, 12345 Ciudad",
    "footer_text": "Texto legal opcional..."
  }
]

Campos de configuración

Campo Obligatorio Descripción
id Identificador de la configuración
template Plantilla a usar: original o wide-logo
output_path Carpeta de salida (por defecto usa id)
main_font Fuente principal del texto
name_font Fuente del nombre de la persona
name_image Objeto {image, url?, alt?, description?} (ver abajo)
color Color hexadecimal (ej: #3EB1C8)
organization Nombre de la organización
organization_extra Organización superior/adicional
phone Número de teléfono (sin código de país)
phone_country_code Código de país (ej: +34)
internal_phone Extensión interna
opt_mail Email alternativo (se muestra si no hay teléfono)
max_width Ancho máximo en píxeles
links Lista de enlaces sociales
sponsor_text Texto sobre los patrocinadores
sponsors Lista de patrocinadores
supporter_text Texto sobre los colaboradores
supporters Lista de colaboradores
footer_address Dirección postal
footer_text Texto legal del footer

Formato de name_image

Debe ser un objeto con las propiedades de la imagen:

"name_image": {
  "image": "https://example.com/logo.png",
  "url": "https://example.com",
  "alt": "Logo",
  "description": "Ir al sitio web"
}
Campo Obligatorio Descripción
image URL de la imagen
url URL del enlace (si hay, la imagen es clicable)
alt Texto alternativo (por defecto: 👤)
description Descripción (se usa en title y aria-label)

Formato de links

Campo Obligatorio Descripción
url URL del enlace
image URL del icono
alt Texto alternativo (emoji recomendado)
description Descripción (se usa en title y aria-label)

Formato de sponsors y supporters

Campo Obligatorio Descripción
url URL del enlace (si no hay, no es clicable)
image URL del logo
alt Texto alternativo
description Descripción (se usa en title y aria-label)
width Ancho en píxeles
height Alto en píxeles

Plantillas disponibles

Plantilla Descripción
original Diseño clásico con imagen circular y barra horizontal
wide-logo Logo ancho arriba con barra vertical al lado del contenido

Lista de firmas (CSV)

Una vez esté la configuración definida hay que crear la lista de firmas a generar, que es un archivo CSV (por defecto {id en minúsculas}_list.csv, ej: enem_list.csv).

Columnas obligatorias

name,position,mail

Columnas opcionales

Estas columnas, si tienen valor, sobrescriben la configuración general:

output,phone,phone_country_code,internal_phone,opt_mail,organization_extra,main_font,name_font,max_width,name_image,color,organization

Nota: Usa None en una celda para eliminar un valor opcional de la configuración general para esa firma específica.

Ejemplo de CSV

Name,Position,Mail,Output,Phone,internal_phone
Ana García,Presidenta,presidencia@ejemplo.es,Firma Presidenta,123 456 789,12345
Juan López,Secretario,secretaria@ejemplo.es,Firma Secretario,,None

Accesibilidad

Las firmas incluyen varias características para mejorar la accesibilidad:

Característica Descripción
role="presentation" Las tablas usadas para maquetación se marcan como decorativas para que los lectores de pantalla las ignoren
aria-hidden="true" Los elementos decorativos (barras de color, iconos dentro de enlaces) se ocultan a lectores de pantalla
aria-label Los enlaces con iconos usan description como etiqueta accesible descriptiva
alt en imágenes Todas las imágenes tienen texto alternativo (emoji por defecto: 👤, 🌐, etc.)
title en enlaces Los enlaces muestran tooltip con la descripción al pasar el ratón
role="img" en avatar La imagen del avatar/logo se marca explícitamente como imagen semántica

Tip: Para una accesibilidad óptima, configura alt (emoji o texto corto) y description (texto descriptivo completo) en los enlaces e imágenes.

Clientes de correo soportados

Las firmas ahora usan tablas HTML en lugar de flexbox para mejorar la compatibilidad con clientes de correo. Las pruebas no han sido muy exhaustivas, pero la firma en algunos sitios va bien 🟢, regulinchi (se ve bien en general pero puede fallar en algún detalle) 🟡 y mal 🔴. Esta es la lista:

🟢 Webmail

🟢 Thunderbird

🟢 Outlook web

🟢 Outlook móvil

🟢 Gmail web

🟢 Gmail móvil

🟡 Thunderbird móvil

🔴 Canary Mail

Estructura del proyecto

mail-signatures/
├── main.py              # Script principal
├── schemas.py           # Validación de datos
├── signatures.json      # Configuración de organizaciones
├── *_list.csv           # Listas de firmas por organización
├── templates/
│   ├── _base.html.j2    # Plantilla base con estructura común
│   ├── _macros.html.j2  # Macros reutilizables
│   ├── original.html.j2 # Plantilla clásica
│   └── wide-logo.html.j2# Plantilla con logo ancho
└── {OUTPUT}/            # Firmas generadas por organización

Desarrollo

Crear una nueva plantilla

  1. Crea un archivo templates/mi-plantilla.html.j2
  2. Extiende la plantilla base: {% extends "templates/_base.html.j2" %}
  3. Sobrescribe los bloques necesarios (header, content, links, sponsors, etc.)
  4. Añade el nombre mi-plantilla en el campo template de la configuración

Nota: También puedes crear una plantilla desde cero importando los macros directamente con {% from "templates/_macros.html.j2" import ... %}, pero extender _base.html.j2 es más sencillo.

Macros disponibles

Macro Descripción
social_link(link, size) Renderiza un enlace social individual
social_links_bar(links, size, max_width) Barra de enlaces sociales
sponsor_image(item, max_width) Imagen de sponsor/supporter
sponsors_section(text, items, color, max_width, with_bar) Sección completa de sponsors
footer(footer_address, footer_text, color, max_width) Footer con dirección y texto legal
contact_info(phone, phone_country_code, internal_phone, mail, opt_mail) Información de contacto
name_image_block(name_image, organization, size, rounded, wide) Bloque de imagen/avatar con nombre

About

Firmas HTML para los correos

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published