Página de inicio de Proton

Filtro Sieve (filtros personalizados avanzados)

Lectura
41 min
Categoría
Recibir y leer correos electrónicos

Proton Mail ofrece a los usuarios varias formas de filtrar correos electrónicos automáticamente asignándoles etiquetas o clasificándolos en carpetas. En general, existen tres métodos:

  1. Añadir remitentes a la Lista de direcciones bloqueadas y la Lista de direcciones permitidas de manera que siempre o nunca se coloquen en la carpeta de spam;
  2. Crear un filtro personalizado utilizando la interfaz interactiva de Proton Mail;
  3. [El más avanzado] Crear un filtro personalizado en Sieve.

De estos métodos, crear un filtro personalizado en Sieve ofrece la mayor versatilidad, pero también es más complicado de usar. Por esta razón, consideramos que Sieve es una función avanzada para usuarios con cierta experiencia técnica. Para la mayoría de los usuarios, la interfaz interactiva es adecuada para crear los filtros personalizados que necesitas.

Índice de contenidos

¿Qué es Sieve?

Sieve es un lenguaje de programación que se utiliza para filtrar correos electrónicos. Puedes crear filtros en Sieve escribiendo reglas sencillas. Por ejemplo, «Asignar a todos los mensajes de Kyle la etiqueta verde». La combinación de estas reglas puede crear un sistema de filtrado sofisticado.

Puedes escribir reglas de Sieve desde cero, tomarlas prestadas de ejemplos como los de este artículo o utilizar software que facilite la tarea.

De hecho, ya te ofrecemos una forma de crear filtros Sieve utilizando la interfaz interactiva, que utiliza tus datos de entrada para generar filtros Sieve. Otra buena forma de aprender Sieve es crear filtros con la interfaz interactiva y luego editarlos en Sieve, ya que la propia interfaz interactiva utiliza un subconjunto de Sieve.

Por ejemplo, compara el siguiente filtro creado con la interfaz interactiva…


… con el código del mismo filtro visto en el editor de Sieve:

Este artículo te presentará Sieve y te explicará cómo escribir tus propios filtros Sieve. Si necesitas más información sobre el uso de Sieve, hay muchos otros tutoriales en línea que te pueden ayudar. Si tienes preguntas sobre Sieve en Proton Mail que no se resuelven en esta página, siempre puedes ponerte en contacto con nuestro equipo de soporte aquí.

Primeros pasos

Para empezar a crear filtros Sieve, inicia sesión en mail.proton.me(ventana nueva) y ve a Ajustes → Todos los ajustes → Proton Mail → Filtros → Añadir filtro Sieve.

Un script de Sieve está compuesto por una lista de comandos. En la mayoría de los scripts, comienza con un comando require. El comando require carga una extensión que proporciona una funcionalidad determinada. Por ejemplo, para asignar una etiqueta o colocar un mensaje en una carpeta, necesitamos el comando fileinto.

Para cargar este comando simplemente escribimos:

require "fileinto";

Para cargar varias extensiones puedes usar una lista:

require ["fileinto", "imap4flags"];

En este caso, imap4flags carga una extensión que te permite marcar el correo como leído. Después del comando require, a menudo realizarás algunas pruebas en el mensaje entrante. Esto se hace combinando if y otro comando como address o header.

Por último, si las pruebas tienen éxito, puedes aplicar una acción a un mensaje. Por ejemplo, supongamos que queremos poner todos los correos electrónicos de un remitente específico en la misma carpeta y marcar el correo entrante como leído. Esto se podría escribir así:

require ["fileinto", "imap4flags"];
# I don't really like Spott
if address :is "from" "Spott.Tenerman@northpark.example.com"
{ 
    addflag "\\Seen";
    fileinto "enemies";
}

Ten en cuenta que el signo # indica un comentario y no se interpreta como parte del script de Sieve. Además, la carpeta o la etiqueta que establezcas (aquí, enemies) tiene que existir en tu entorno: puedes aprender a crear carpetas y etiquetas aquí. Después de introducir este filtro, pulsa el botón GUARDAR. Tu filtro se ejecutará a partir de ahora para cada correo electrónico entrante.

Por supuesto, es posible que quieras poner los correos electrónicos de varios remitentes en la misma carpeta. En este caso, puedes pasar una lista de cadenas al comando address (una cadena(ventana nueva) es una serie de caracteres, en este caso, una dirección de correo electrónico):

require ["fileinto", "imap4flags"];
# I don't really like Spott and Kyyyhel
if address :is "from" ["Spott.Tenerman@northpark.example.com", "Kyhel.Broski@northpark.example.com"]
{ 
    addflag "\\Seen";
    fileinto "enemies";
}

Ten en cuenta que, siempre que puedes pasar una cadena a una condición de prueba, normalmente también es posible pasar una lista. A continuación, intentará encontrar una coincidencia probando cualquiera de las cadenas de la lista. Esto no se aplica a comandos como fileinto, addflag, etc.

Pero Sieve es más potente que el simple hecho de reordenar tu buzón. También te permite rechazar correos electrónicos con un mensaje de respuesta:

require "reject";
# Reject mails that spell my name wrong
if header :contains "subject" "Kyhel"
{
    reject "My name is not Kyhel";
}

Uso de pruebas

Combinar pruebas en Sieve

Como te mostramos en la sección de Primeros pasos, puedes realizar pruebas utilizando el comando if en los mensajes entrantes para determinar si un correo electrónico debe verse afectado por un comando require.

Además del comando if, existen otros comandos de prueba que te permiten estructurar tu script de forma sencilla.

Else

El comando else te permite hacer algo cuando el comando if no ha ejecutado sus acciones. Un ejemplo de esto es:

require ["fileinto"];
# If the subject contains something incomprehensible, then put the mail into the kenny folder
if header :contains "subject" "mmph mmph"
{
    fileinto "Kenny";
} else { 
    fileinto "Understandable";
}

Aquí, el correo electrónico se moverá a la carpeta Kenny si el asunto es exactamente mmph mmph. En el otro caso (es decir, cuando el asunto no es exactamente mmph mmph), el correo electrónico se moverá a la carpeta Understandable.

Elsif

El comando elsif es la contracción de else if. Al igual que el comando else, se ejecutará si la condición if es falsa, pero solo si la condición elsif es correcta. Si el comando elsif no es correcto, se ejecutará el siguiente bloque elsif o else.

require ["fileinto", "imap4flags"];
# If the subject contains something incomprehensible, then put the mail into the kenny folder
if header :contains "subject" "mmph mmph"
{
    fileinto "Kenny";
# Kyhel sends me only speeches
} elsif address :is "from" "Kyhel.Broski@northpark.example.com" { 
    fileinto "Speeches";
} else { 
# otherwise the mail is important, so add a star.
    addflag "\\Flagged";
}

Ten en cuenta que solo uno de los bloques if, elsif o else se ejecutará en una sola ejecución.

Anyof

A veces, necesitas ejecutar un comando cuando uno de varios test tiene éxito. Para ello, puedes usar el comando anyof. Esto se hace escribiendo anyof seguido de un paréntesis ‘(’, las instrucciones que quieras probar separadas por comas y un paréntesis de cierre ‘)’.精密

require ["fileinto", "imap4flags"];
# Kenny either sends from kenny@northpark.example.com or puts "mmph mmph" in the subject.
   if anyof(address :is "from" "kenny@northpark.example.com", header :contains "subject" "mmph mmph")
{
    fileinto "Kenny";
}

Este script pondrá los mensajes que provengan de kenny@northpark.example.com o que contengan mmph mmph en la línea del asunto en la carpeta Kenny.

Allof

También existe la contraparte de anyof: allof. Esto te permite ejecutar un comando solo cuando se cumplen todas las condiciones dadas:

require ["fileinto", "imap4flags"];
# Kenny always sends me mails with mmph mmph
if allof(address :is "from" "Kenny@northpark.example.com", header :contains "subject" "mmph mmph")
{
    fileinto "Kenny";
}


Este script pondrá los mensajes que provengan de kenny@northpark.example.com y contengan mmph mmph en la línea del asunto en la carpeta Kenny.

Not

Por último, a veces necesitas aplicar un comando si algo no coincide. Añadir not delante de la instrucción se asegurará de que eso ocurra:

require ["fileinto", "imap4flags"];
# If a subject line does not contain real guitar put it into the young people folder
if not header :contains "subject" "real guitar"
{
    fileinto "Young people";
}

Lo cual equivale a:

require ["fileinto", "imap4flags"];
# The else part will be evaluated if the condition is not true
if header :contains "subject" "real guitar"
{
    # do nothing
} else {
    fileinto "Young people";
}

Esto pone todos los correos electrónicos que no contienen real guitar en la línea del asunto en la carpeta Young people.

Por supuesto, es posible combinar todas estas pruebas juntas. Por ejemplo, puede que quieras destacar un correo electrónico si no proviene de Kenny y tampoco contiene mmph mmph en el asunto:

require ["fileinto", "imap4flags"];
if not anyof (    header :contains "subject" "mmph mmph", 
    address :is "from" "Kyhel.Broski@northpark.example.com" ) { 
    addflag "\\Flagged";
}

Realizar pruebas en los encabezados

Usando el comando address puedes realizar pruebas en los encabezados de dirección, como los encabezados from, to y sender. Puedes extraer diferentes partes de la dirección de correo electrónico usando uno de los siguientes marcadores:

  • :localpart — la parte antes del símbolo de arroba (@)
  • :domain — la parte después del símbolo de arroba (@)
  • :all — la dirección completa

El siguiente fragmento de código explica el uso de este comando:

require ["fileinto", "imap4flags"];
# Northpark people are made of paper, springfield are mostly yellow
if address :domain "from" "northpark.example.com"
{
    fileinto "PaperPeople";
} elsif address :domain "from" "springfield.example.com"{
    fileinto "YellowPeople";
}
if address :localpart "from" "chef"
{
    addflag "\\Flagged";
}

En resumen, este script pondrá todo lo enviado desde el dominio northpark.example.com en PaperPeople y desde springfield.example.com en YellowPeople.

Además, sin importar desde qué dominio se envíe un correo electrónico, si la parte antes de la @ es igual a chef (por ejemplo, chef@example.com), el mensaje se marcará. Otro uso interesante es almacenar automáticamente todo lo enviado a una dirección en una carpeta:

require ["fileinto", "imap4flags"];
# Put support mail in a separate organized folder
if address :localpart "to" "support"
{
    fileinto "Support";
}

Avanzado

El comando envelope te permite realizar más pruebas. En general, la prueba de address solo recupera el valor del encabezado. Sin embargo, en la sesión SMTP se puede especificar una dirección from diferente a la del encabezado.

En la interfaz de encabezados de Proton Mail, envelope-from equivale al encabezado return-path y envelope-to equivale al encabezado x-original-to.

Usando el comando envelope puedes recuperar las direcciones reales de to: y from: del sobre. Ten en cuenta que no existen otros campos además de esos dos, por lo que sender no existe en este comando. Ten en cuenta que envelope forma parte de una extensión y, por lo tanto, requiere que primero utilices require con esta extensión.

require ["fileinto", "imap4flags", "envelope"];
# Northpark people are made of paper, springfield are mostly purple
if envelope :domain "from" "northpark.example.com"
{
    fileinto "PaperPeople";
} elsif envelope :domain "from" "springfield.example.com"{
    fileinto "PurplePeople";
}
if envelope :localpart "from" "chef"
{
    addflag "\\Flagged";
}

Uso de comparadores para evaluar dos valores

Cuando una prueba evalúa dos valores, es posible especificar cómo se hace esta comparación utilizando diferentes marcadores llamados comparadores. Anteriormente ya usamos dos comparadores: :is y :contains, que comprueban que la cadena dada sea exactamente igual al valor específico, y que el valor específico contenga la cadena dada, como en la siguiente prueba.

require ["fileinto", "imap4flags"];
if not anyof (
    header :contains "subject" "mmph mmph", # the subject contains mmph mmph 
    address :is "from" "Kyhel.Broski@northpark.example.com" # the recipient is exactly Kyhel.Broski@northpark.example.com
) { 
    addflag "\\Flagged";
}

El comparador :matches también se puede utilizar para definir un formato más específico. Comparará ambos valores desde el principio hasta el final, al igual que el comparador :is. Sin embargo, en el caso de :matches, el valor que hayas definido puede contener los valores ? y *. El signo de interrogación coincidirá con un carácter y la estrella (llamada comodín) coincidirá con cero o más caracteres.

Con este formato, puedes crear esta prueba:

require ["fileinto", "imap4flags"];
if header :matches "subject" "mmph*" { 
    addflag "\\Flagged";
}

En este ejemplo, la prueba tendrá éxito si el asunto del mensaje comienza con mmph y luego contiene cualquier carácter o caracteres después de este. En otras palabras, el correo electrónico se marcará cuando el asunto comience con ‘mmph’. Tanto ‘mmph mmph’ como ‘mmph mmph Hello’ coincidirán; ‘Hello mmph’ y ‘Springfield sales’ no.

La estrella también se puede usar en medio del valor y varias veces, de la siguiente manera:

require ["fileinto", "imap4flags"];
if header :matches "subject" "mmph *mmph *mmph" { 
    addflag "\\Flagged";
}

Esta prueba coincidirá si el asunto comienza con ‘mmph ’ (con un espacio), contiene otro ‘mmph ’ (con un espacio) y termina con ‘mmph’ (sin espacio). Los asuntos que coinciden son ‘mmph mmph mmph’, ‘mmph mmph mmphmmph’ o ‘mmph is mmph and mmph’.

Este comparador :matches puede ser muy útil con la comparación de direcciones. Como sabrás, Proton Mail tiene varios dominios: protonmail.com y proton.me. Si quieres comprobar si un mensaje proviene de un usuario de Proton Mail, puedes usar este script:

require ["fileinto", "imap4flags"];
# Put support mail in a separate organized folder
if address :domain :matches "from" "protonmail.*"
{
    fileinto "Internal";
}

Si por alguna razón necesitas coincidir exactamente con el carácter * o ?, puedes escaparlos añadiendo \\ antes: \\* coincidirá con una estrella y \\? coincidirá con un signo de interrogación.

Ten en cuenta que también admitimos la extensión regex, que además define el comparador :regex. Este comparador es una versión más precisa de :matches, pero es muy compleja. Para más información, lee la documentación oficial(ventana nueva).

En algunos casos (como verás más adelante en este artículo), puede que quieras comparar valores numéricos. El paquete relational está hecho para este uso. Este paquete define el comparador :value, el cual va seguido del tipo de comparación.

Te permite comprobar si un valor es mayor que (siendo el tipo de comparación “gt”), mayor o igual que (“ge”), igual a (“eq”), menor o igual que (“le”) o menor que (“lt”) el valor dado.

Al comparar valores numéricos, el paquete comparator-i;ascii-numeric también es muy útil. Le indica al intérprete del script que el contenido de la cadena es un número y no una cadena normal. Se puede usar añadiendo a la prueba :comparator “i;ascii-numeric”.

Con toda esta información, podemos crear el siguiente script:

require ["fileinto", "relational", "comparator-i;ascii-numeric"];  
if header :value "ge" :comparator "i;ascii-numeric" "subject" "2"   
{    
 fileinto "Dummy example";
}

Esta prueba moverá el mensaje a la carpeta Dummy example si el asunto es mayor o igual a 2. Si el asunto no es un número, sino un texto, la prueba fallará. Como tal, este ejemplo parece muy tonto, pero está pensado para usarse en combinación con otras extensiones como date, que definiremos más adelante en este artículo.

Comparación utilizando el contexto en Sieve

También puedes acceder a la información relacionada con tu cuenta y al contexto de Proton Mail en general mediante extensiones. Por ejemplo, puedes comprobar si la dirección del remitente está en tu lista de contactos.

Acceder a tu lista de contactos

Puedes acceder a tu lista de contactos usando la extensión extlists. En combinación con las pruebas de encabezado, puedes comprobar si un contacto está en tu lista de contactos.

require ["fileinto", "extlists"];  
# Checks that the sender is in your personal address book
if header :list "from" ":addrbook:personal?label=Family"   
{    
 fileinto "Known"; 
}

Esta prueba marcará un mensaje con la etiqueta Known si el remitente está incluido en la lista :addrbook:personal?label=Family. La lista se puede dividir en dos partes. Primero, :addrbook:personal significa que la dirección está en tu libreta de direcciones personal. Segundo, label=Family reduce aún más la lista, especificando que, además de estar en tu libreta de direcciones, el contacto también debe pertenecer al grupo de contactos Family. Si lo necesitas, puedes cambiar esta etiqueta a otro grupo de contactos. Podrías usar :addrbook:personal?label=Work si quieres, en cuyo caso la prueba tendría éxito solo si el remitente está en tu libreta de direcciones y en el grupo de contactos Work.

De manera más general, una lista respeta el esquema URI de etiquetas(ventana nueva) y puedes añadir parámetros adicionales para reducir tus filtros. Luego puedes usar esta lista de la siguiente manera:

require ["fileinto", "extlists"];  
# replace :your:list:here by the list you want to use
if header :list "from" ":your:list:here"
{    
 # some actions... 
}

Hemos proporcionado cuatro listas diferentes:

  • :addrbook:personal¹ comprueba si una dirección está en tu lista de contactos. La lista acepta el parámetro label que coincide con un grupo de contactos específico. Este parámetro puede declinarse en cuatro subversiones:
    • :addrbook:personal?label=something coincidirá con un contacto que esté en el grupo de contactos “something”;
    • :addrbook:personal?label.starts-with=something coincidirá con un contacto que pertenezca al menos a un grupo que comience por “something”;
    • :addrbook:personal?label.ends-with=something coincidirá con un contacto que pertenezca al menos a un grupo que termine por “something”;
    • :addrbook:personal?label.contains=something coincidirá con un contacto que pertenezca al menos a un grupo que contenga “something”.

También puedes acceder a información criptográfica sobre el correo electrónico coincidente:

  • :addrbook:personal?keypinning=true coincidirá con un contacto que tenga una clave de confianza. Cambiar true a false coincidirá con un contacto que no tenga una clave de confianza;
  • :addrbook:personal?encryption=true coincidirá con un contacto para el cual el cifrado esté activado. Cambiar true a false coincidirá con un contacto para el cual el cifrado no esté configurado o esté desactivado;
  • :addrbook:personal?signing=true coincidirá con un contacto que tenga la firma activada. Cambiar true a false coincidirá con un contacto que tenga la firma desactivada.
  • :addrbook:myself¹ coincide con cada dirección que te pertenezca;
  • :addrbook:organization coincide con cada dirección que pertenezca a alguien de la organización de la que eres miembro;
  • :incomingdefaults:inbox comprueba si la dirección está en tu lista blanca;
  • :incomingdefaults:spam comprueba si la dirección está en tu lista negra.

Combinado con la extensión de variables (que se describe en el siguiente párrafo), las variables de coincidencia se verán alteradas. La variable de coincidencia ${0} siempre contendrá la última dirección de correo electrónico que aparezca en la lista especificada. Si la lista se marcó con la nota 1, la variable de coincidencia ${1} contendrá el nombre a mostrar.

Por ejemplo, con las siguientes listas, puedes crear un filtro que elimine cualquier correo electrónico recibido de cualquier persona que no sea de tu familia o que no esté en tu lista blanca:

require "extlists";  
# checks that the sender is not in the contact group Family, whilelisted or yourself
if not anyof(
    header :list "from" ":addrbook:personal?label=Family", 
    header :list "from" ":incomingdefaults:inbox",
    header :list "from" ":addrbook:myself"
) {    
  discard; # permanently delete the email
}

Si se cumple esa condición, se ejecutará la acción discard. Esta acción elimina el correo electrónico de forma inmediata y permanente. También podrías simplemente moverlo a la carpeta de la papelera usando una acción fileinto en lugar de descartar: fileinto “trash”;.

Creación de variables

Otra herramienta útil a la hora de administrar el contexto es la definición de variables. Una variable es una ubicación de almacenamiento temporal en la que puedes introducir texto y etiquetarlo con un nombre. Más adelante, podrás reutilizar este contenido llamándolo por su nombre. Por ejemplo, podrías tener el siguiente script:

require ["reject", "variables"];
# First check who is the sender
if allof(
    address :is "from" "Kenny@northpark.example.com", 
    header :contains "subject" "mmph mmph"
) {
    # It's from Kenny!
    # Create the variable message containing 'mmph mmph'
    set "message" "mmph mmph";
} else {
    # Create the variable message containing 'Sorry, I don't want emails today!'
    set "message" "Sorry, I don't want emails today!";
}
# Then, reject the message
reject "${message}";

El objetivo de este script es rechazar un correo electrónico con un mensaje personalizado. Si el correo electrónico original es de kenny y su asunto es ‘mmph mmph’, se crea la variable ‘message’, que contiene mmph mmph. En el otro caso, el mensaje se completará con ‘Sorry, I don’t want emails today!’. Después, en el último paso, reutilizamos esta variable en el comando de rechazo.

Sieve no define variables de forma nativa, por lo que se definen en la extensión variables, que debe solicitarse al principio de tu script. Hay dos formas de definir una variable.

  • Creación explícita de una variable:

Se proporciona la acción set para crear una variable.

require "variables";
# Create a variable called "labelname" and containing the string "Work".
set "labelname" "Work";

La primera cadena es el nombre de tu variable y la segunda es el valor de tu variable. De este modo, el ejemplo anterior crea una variable llamada labelname que contiene Work.

Una vez definida una variable, puedes llamarla añadiendo el siguiente formato en una cadena: ${name}, donde name es el nombre de tu variable. Al ejecutarse, se reemplazará por el valor de la variable. (Si no has definido la variable, se reemplazará por una cadena vacía). Por lo tanto, en el siguiente script:

require "variables";
require "fileinto";
# Create a variable called "labelname" and containing the string "Work".
set "labelname" "Work";
# Move the email in "${foldername}/${labelname}" which becomes after variable resolution "/Work";
fileinto "${foldername}/${labelname}";

Tu correo electrónico se etiquetará con la etiqueta /Work. Como ya hemos definido la variable labelname, se sustituye por Work. Sin embargo, foldername no está definida, por lo que simplemente se elimina.

  • Asignación implícita de una variable:

El caso de uso más interesante de las variables es cuando se utiliza una prueba de coincidencia :matches. Tomemos el siguiente ejemplo, donde el remitente del correo electrónico es test@proton.me:

require "variables";
require "fileinto";
# do a matches test 
if header :matches "from" "*@*" {
    # The first * matches "test", the second "protonmail".  
    # Thus, the first matching variable contains "test"
    fileinto "${1}";
}

Cuando se utiliza con la extensión de variables, el resultado de una operación match se almacenará en las variables. Se establecerán varias variables con un nombre numérico. Primero, la variable 0 contendrá la coincidencia completa (en nuestro ejemplo, será la dirección completa: test@proton.me). Luego, el primer grupo de coincidencia se asignará a la variable 1 (en nuestro ejemplo, será test), el segundo grupo de coincidencia se asignará a la segunda variable (proton.me), y así sucesivamente hasta el último grupo de coincidencia.

En nuestro ejemplo, se ejecuta el comando fileinto. La ubicación se define como ${1}, que se reconoce como una variable y, por lo tanto, se reemplaza por su valor, calculado anteriormente: test.

Ten en cuenta que también es posible asignar variables en una prueba de coincidencia :regex, utilizando grupos de coincidencia de expresiones regulares.

Transformación de variables

Una buena posibilidad es la transformación de variables. Para ello, se puede utilizar la palabra clave set con una combinación de etiquetas que permiten cambiar el valor antes de asignarlo a la variable.

  • :lower cambiará el valor de una variable a minúsculas;
  • :upper cambiará el valor de una variable a mayúsculas;
  • :lowerfirst cambiará la primera letra del valor de la variable a minúscula;
  • :upperfirst cambiará la primera letra del valor de la variable a mayúscula;
  • :quotewildcard entrecomillará cualquier comodín que contenga la cadena, de modo que se pueda utilizar literalmente en una instrucción de coincidencia;
  • :length devolverá la longitud del valor.

Ten en cuenta que también puedes reutilizar una variable definida en otra acción set. Vamos a mejorar nuestros ejemplos anteriores:

require "variables";
require "fileinto";
# Set labelname to WORK, and modify it to lowercase with the first letter in upper case 
set :lower :upperfirst "labelname" "WORK";
set :lower :upperfirst "foldername" "geneva";
# Create a variable that is a combination of foldername and labelname
set "location" "${foldername}/${labelname}";
fileinto "${location}";

Paso a paso, el filtro creará tres variables. El primer comando set creará la variable labelname. El contenido de la variable es Work. En efecto, el valor original WORK se transforma utilizando las etiquetas :lower y :upperfirst, cambiando a minúsculas como work y luego a Work.

El segundo comando set creará una segunda variable llamada foldername, que contendrá la cadena Geneva. En efecto, se utilizaron las etiquetas :lower y :upperfirst.

Por último, se crea la variable location. El valor “${foldername}/${labelname}” contiene dos variables: foldername y labelname. De este modo, el intérprete de Sieve reemplazará estas variables por sus valores: Work y Geneva.

Por último, la variable location se utiliza como argumento para el comando fileinto. Por lo tanto, el correo electrónico se moverá a la carpeta cuyo nombre es el valor de la variable location: Work/Geneva.

Los comparadores también se pueden aplicar a las variables de coincidencia:

require "variables";
require "fileinto";
if address :all :matches "from" "*@*" {
    set :lower :upperfirst "fileintovar" "${1}";
    fileinto "${fileintovar}";
}

Aquí, si el remitente del correo electrónico es test@proton.me, se marcará con la etiqueta Test.

Otra forma de cambiar el valor de una variable es utilizar la extensión vnd.proton.eval. Esta extensión define la nueva etiqueta :eval, que te permitirá realizar algunos cálculos sencillos:

require "variables";
require "fileinto";
require "vnd.proton.eval";
# do a match test on the sender address
if header :matches "from" "*" {
    # create a variable called length, containing the length of the first     
    # matching variable
    set :length "length" "${1}"; 
    # Create a variable called fileintovar containing the result of the expression written below
    set :eval "fileintovar" "${length} * 25 - 1 / 8+3";
    fileinto "${fileintovar}";
}

En este ejemplo, y considerando que el correo electrónico proviene de test@proton.me, el correo electrónico se marcará con el valor 478. En efecto, la longitud de la primera variable de coincidencia es 19, y el resultado de 19 * 25 – 1 / 8 + 3 se redondea hacia arriba a 478.

Esto puede parecer inútil al principio, pero esta extensión cobra más sentido combinada con otras operaciones.

Comparación con otros campos en Sieve

También es posible realizar coincidencias en encabezados específicos. Por ejemplo, para colocar todos los mensajes enviados a listas (que a menudo son mensajes de marketing o boletines), puedes hacer lo siguiente:

require "fileinto";
# Filter all lists into the same folder
if exists "list-unsubscribe"
{
    fileinto "advertisements";
}

Para clasificar los correos electrónicos de redes sociales en su propia carpeta, podrías escribir:

require "fileinto";
# Filter all lists into the same folder
if anyof(exists "x-facebook", exists "x-linkedin-id") {
    fileinto "social";
} elsif exists "list-unsubscribe"
{
    fileinto "advertisements";
}

Ten en cuenta que utilizamos:

anyof(exists "x-facebook", exists "x-linkedin-id")

en lugar de:

exists ["x-facebook", "x-linkedin-id"]

Ya que esto último comprueba si se han establecido tanto x-facebook como x-linkedin-id.

Para ver realmente qué valor contiene un encabezado, puedes utilizar la prueba de coincidencia header:

require "fileinto";
# Put all mails that have been sent without TLS/SSL into the same folder
if header :is "x-pm-transfer-encryption" "none" {
    fileinto "unencrypted";
}

Además de la operación :is, que realiza una coincidencia exacta, el comando header también admite :matches, que realiza coincidencias mediante comodines (por ejemplo, “*@*.com” coincidirá con cualquier dirección de correo electrónico que termine en punto com), y el comando :contains, que comprueba si el encabezado contiene una cadena determinada.

Para diseñar filtros de Sieve, puede resultar útil recuperar los encabezados de un correo electrónico. Para hacerlo en la interfaz web de Proton Mail, ve a Más () → Ver encabezados. Se abrirá una nueva ventana que contendrá todos los encabezados del correo electrónico.

Filtrar por tamaño de mensaje en Sieve

Es posible tratar los correos electrónicos grandes de forma diferente a los pequeños. Por ejemplo, es posible que quieras marcar los correos electrónicos grandes para poder eliminarlos y ahorrar espacio en el buzón. Esto se puede lograr de la siguiente manera:

require ["imap4flags"];
# Flag emails that probably have large attachments (> 2 MiB)
if size :over 2M # you can also use 2097152 if you want, they are synonymous
{
    addflag "\\Flagged";
}
# Automatically mark as read really small messages. They can't have much content anyway...
if size :under 1000
{
    addflag "\\Seen";
}

Como puedes ver, hay unidades disponibles si quieres especificar tamaños grandes, añadiendo la letra correspondiente a la unidad esperada justo después del número. Hay tres unidades disponibles: K para un kibioctet (o 1024 bytes), M para un mebioctet (or 1 048 576 bytes) y G para un gibioctet (o 1 073 741 824 bytes).

Ten en cuenta que «over» en este caso significa mayor que, y «under» significa menor que. Esto significa que si un mensaje tiene un tamaño de exactamente 1000 bytes, entonces ninguno

size :under 1000

ni

size :over 1000

coincidirá.

Ten en cuenta que los filtros de Sieve no tienen acceso al contenido real y solo muestran el tamaño cifrado.

Realizar acciones avanzadas en los mensajes

Puedes ejecutar diferentes reacciones a un mensaje en Sieve. Ya hemos presentado las acciones fileinto, addflag, discard y reject en las secciones anteriores. Aquí presentaremos acciones más avanzadas.

Mensajes de ausencia y pruebas de fecha

Puedes replicar la función de respuesta automática en Sieve usando el comando vacation. De hecho, la función de respuesta automática en tu Configuración se basa en Sieve para hacer su trabajo. Pero al usar las opciones de vacation dentro de un script, tienes muchas más posibilidades de personalizar tus respuestas automáticas. Por ejemplo, puedes adaptar mensajes específicos en función de las condiciones. Nota: Al igual que con la función de respuesta automática en la Configuración, la acción vacation solo está disponible en los planes de pago.

El comando vacation envía una respuesta de ausencia a cualquiera que intente ponerse en contacto contigo. A menudo se combina con las pruebas currentdate o date para enviar respuestas en un intervalo de tiempo específico.

Supongamos que me voy de vacaciones desde el 14 de julio de 2017 hasta el 14 de agosto de 2017, en la hora de Colorado. Puedo usar el siguiente código de Sieve para establecer una respuesta automática:

require ["date", "vacation", "relational"];
if allof(currentdate :zone "US/Mountain" :value "ge" "date" "2017-07-14",
 currentdate :zone "US/Mountain" :value "le" "date" "2017-08-14")
{
    vacation "Queue you guys, I'm going on vacation.";
}

Uno de los argumentos opcionales para un comando vacation son los argumentos :handle y :days. Por defecto, Sieve no responderá varias veces al mismo remitente en un número específico de días, lo que se denomina tiempo de espera. Esto evita que envíes sin querer numerosos correos electrónicos automáticos.

Para controlar el tiempo de espera, puedes usar el parámetro :days. El argumento :days se utiliza para especificar el período durante el cual se conservan las direcciones y no se les responde, y siempre se especifica en días. A veces, tienes varios comandos vacation en tu script de Sieve, y necesitas asegurarte de que cada uno de ellos envíe una respuesta al menos una vez (si se cumple la regla). En ese caso, se puede utilizar la opción :handle. El argumento para :handle es una cadena que identifica el tipo de respuesta que se está enviando.

Para ver cómo funciona esto, supongamos que eres profesor. Los profesores suelen recibir tareas por correo electrónico. Es útil clasificarlas en su propia carpeta. Además, puedes rechazar cualquier entrega que llegue después de la fecha límite.

En tal caso, es posible que quieras usar handle para asegurarte de que las respuestas se envíen cuando sea necesario:

require ["date", "vacation", "reject", "fileinto", "relational"];
if header :contains "subject" "Homework assignment 1"
{
    # remind people not to forget the attachments
    if size :under 5000
    {
        vacation :handle "Homework assignment 1 - missing attachment" "Your message size is really low. Please make sure you didn't forget to add the homework as an attachment.";
    }
   
    # check if the student made the deadline
    if  currentdate :zone "US/Mountain" :value "le" "date" "2017-06-12"
    {
        fileinto "Homework Assignment 1";
    } else {
        reject "Too late, you missed the deadline.";
    }
}
if header :contains "subject" "Homework assignment 2"
{
    # remind people not to forget the attachments
    if size :under 5000
    {
        vacation :handle "Homework assignment 2 - missing attachment" "Your message size is really low. Please make sure you didn't forget to add the homework as an attachment.";
    }
   
    # check if the student made the deadline
    if  currentdate :zone "US/Mountain" :value "le" "date" "2017-06-12"
    {
        fileinto "Homework Assignment 2";
    } else {
        reject "Too late, you missed the deadline.";
    }
}

Aquí están todos los argumentos permitidos para la respuesta de ausencia, listados en el orden en que se deben pasar:

  • :days es el número de días que el autorrespondedor debe abstenerse de enviar una respuesta al mismo remitente después de enviar un mensaje de ausencia
  • :subject es un prefijo (por defecto auto) que el autorrespondedor debe usar para responder al remitente. Por ejemplo, «Homework Assignment 2» recibirá una respuesta con «late: Homework Assignment 2» si se pasa :subject “late”.
  • :mime indica que la primera línea de la respuesta utiliza un formato específico. Esto permite al remitente responder con mensajes HTML. Por ejemplo, para escribir una respuesta HTML, pasa el argumento :mime y escribe en la primera línea de la respuesta Content-Type : text/html.
  • :handle es una cadena que identifica el tipo de respuesta que se está enviando.

Ten en cuenta que el parámetro :zone en currentdate es un parámetro opcional y utilizará la hora local del servidor (Ginebra, Suiza, en el caso de Proton Mail) si no está establecido.

El parámetro zone acepta desfases de zona horaria, que son cadenas con el formato «+0100» que significan UTC+1, y zonas horarias reales en la base de datos de ICANN (ver https://en.wikipedia.org/wiki/List_of_tz_database_time_zones(ventana nueva)). La última opción suele ser más útil (aunque no es estándar de Sieve), ya que también codifica el horario de verano de cada zona horaria.

Puedes comparar fechas utilizando el parámetro normal :is/ :contains/ :matches. Así, por ejemplo, el siguiente comando de Sieve coincide con cualquier fecha de julio de 2017:

currentdate :zone "US/Mountain" :matches "date" "2017-07-??"

Pero en la mayoría de los casos, el parámetro :value es mucho más útil.

El último parámetro que necesitas pasar es el formato. El formato también codifica qué parte de la fecha quieres comparar. En el ejemplo dado, hemos utilizado el formato de fecha. Todos los formatos compatibles son:

  • year, el año codificado en el formato «0000» a «9999»
  • month, el mes codificado como «01» a «12»
  • day, el día codificado como «01» a «31»
  • date, codificado como aaaa-mm-dd
  • hour, la hora codificada como «00» a «23»
  • minute, el minuto codificado como «00» a «59»
  • second, el segundo codificado como «00» a «60» (60 es un segundo intercalar(ventana nueva), solo ocurre a las 23:59:60 cuando los científicos lo consideran necesario)
  • time, la hora como hh:mm:ss
  • iso8601, la fecha y hora de acuerdo con la norma ISO8601, por ejemplo: 2005-08-15T15:52:01+00:00
  • std11, la fecha y hora de acuerdo con la norma RFC2822, por ejemplo: Mon, 15 Aug 2005 15:52:01 +0000
  • zone, el desfase de zona horaria en el formato +/-zzzz, por ejemplo +0000 o -1200
  • julian, el número de días desde el 17 de noviembre de 1858 UTC
  • weekday, el día de la semana empezando por el domingo como 0 hasta el sábado como 6

Por último, también es posible obtener la fecha de un encabezado en lugar de usar currentdate. Este comando de fecha funciona de la misma manera que currentdate, excepto que requiere una cadena adicional antes de la cadena de formato: el nombre del encabezado. Por ejemplo:

date :zone "US/Mountain" :matches "received" "date" "2017-07-??"

Ten en cuenta que los encabezados no son necesariamente precisos: un remitente puede cambiarlos a su antojo y, por lo tanto, no son confiables.

Considerations:

  1. El autorrespondedor no responde a mensajes generados automáticamente, como listas de correo, correos electrónicos enviados por otro autorrespondedor o mensajes enviados por una dirección noreply.
  2. El autorrespondedor no enviará mensajes varias veces a la misma dirección de correo electrónico, excepto cuando el comando vacation tenga un :handle diferente.

Administrar la expiración

Una función única de Proton Mail es la capacidad de establecer un tiempo de expiración en los mensajes enviados, momento en el cual el mensaje se eliminará del buzón del destinatario.

También puedes usar esta función para administrar tus mensajes entrantes añadiendo un tiempo de expiración:

require "vnd.proton.expire"; 
# permanently delete all incoming and outgoing emails after 10 days
expire "day" "10";

El script anterior eliminará cualquier correo electrónico recibido después de 10 días. Este caso es un poco extremo, ya que se aplica a todos los correos electrónicos. En su lugar, probablemente deberías usar una condición para aplicar el script solo a un conjunto específico de correos electrónicos. Por ejemplo, podrías hacer que expire cualquier mensaje de alguien que no esté en tus contactos:

require ["extlists", "vnd.proton.expire"];
# permanently delete after 10 days any email not from me or from someone in my address book.
if not anyof(
    header :list "from" ":addrbook:personal",
    header :list "from" ":addrbook:myself"
) {
 expire "day" "10";
}

Nota: Si el tiempo de expiración especificado supera los 730 días, se limitará automáticamente a 730 días.

Limitaciones de Sieve

Hay varias limitaciones de Sieve que debes tener en cuenta.

  • Los mensajes enviados no se pueden mover manualmente ni mediante un filtro a la Bandeja de entrada o a Borradores. Permanecerán siempre en la carpeta Enviados y en las carpetas o etiquetas aplicadas por el usuario o el filtro.
  • Los mensajes recibidos no se pueden mover manualmente ni mediante un filtro a Borradores o Enviados.
  • Los borradores no se pueden mover manualmente ni mediante un filtro a la Bandeja de entrada o a Enviados.
  • Para los mensajes en Spam —o los mensajes archivados en spam durante el procesamiento—, no enviamos respuestas automáticas ni mensajes de ausencia. Si necesitas una función así, considera añadir una carpeta personalizada —mySpam, por ejemplo— y desactivar sus notificaciones.
  • Limitaciones de las respuestas automáticas y mensajes de ausencia

Nota sobre el soporte de expresiones regulares

La implementación de Sieve de Proton sigue el estándar de filtrado de correo electrónico de Sieve, que solo incluye un soporte mínimo para expresiones regulares. Algunas sintaxis abreviadas de expresiones regulares comunes, como \\b (límite de palabra), \\w (carácter de palabra), \\W (carácter que no es de palabra) y \\d (dígito), no se admiten en Sieve. Como resultado, el uso de estos caracteres abreviados en los filtros puede hacer que fallen de forma silenciosa. Esta limitación se debe al propio estándar de Sieve, que prioriza la sencillez y la compatibilidad entre plataformas. Para obtener todos los detalles, consulta el borrador de la RFC de expresiones regulares de Sieve.

Lista de acciones y pruebas compatibles

Paquetes

Sieve admite las siguientes extensiones. Puedes consultar la documentación oficial para obtener más información.

Fecha

  • Uso: date
  • Descripción: (ventana nueva)Proporciona una forma de comprobar la información de fecha.
  • Documentación: https://tools.ietf.org/html/rfc5260(ventana nueva)
  • Implementación: El comparador por defecto es i;ascii-numeric y no i;ascii-casemap. De hecho, la fecha no es útil con el comparador casemap.
  • Ver: Mensajes de ausencia y pruebas de Fecha

Sobre

FileInto

  • Uso: fileinto
  • Descripción: Aplica una etiqueta a un mensaje o lo mueve a una carpeta.
  • Documentación: https://tools.ietf.org/html/rfc5228#section-4.1(ventana nueva)
  • Implementación: Las barras diagonales indican la ruta completa de las carpetas y se deben escapar si el nombre de una etiqueta contiene una barra diagonal. Se admiten las siguientes opciones:
    • Work“: esta es la etiqueta o carpeta llamada ‘Trabajo’
    • Work/Project1“: esta es la subcarpeta ‘Proyecto1’ que está en la carpeta ‘Trabajo’
    • Work/Project1/Docs“: esta es la subcarpeta ‘Docs’ que está en la subcarpeta ‘Proyecto1’ que está en la carpeta ‘Trabajo’
    • Work/Misc\\/Others“: esta es la subcarpeta ‘Varios/Otros’ que está en la carpeta ‘Trabajo’
  • Ver: Primeros pasos

Imap4flags

Rechazar

Ausencia

Variables

Relacional

  • Uso: relational
  • Descripción: Proporciona operadores de coincidencia relacionales.
  • Documentación: https://tools.ietf.org/html/rfc5231

Regex

  • Uso: regex
  • Descripción: Proporciona los operadores de coincidencia de regex.
  • Documentación: https://tools.ietf.org/id/draft-ietf-sieve-regex-01.html

Comparador numérico ASCII

Listas almacenadas externamente

  • Uso: extlists
  • Descripción: Proporciona acceso a las listas de contactos.
  • Documentación: https://tools.ietf.org/html/rfc6134(ventana nueva)
  • Implementación: Se admiten las siguientes listas
    • addrbook:personal : Lista de contactos personales. Se admiten las siguientes consultas:
      • label[.starts-with / .ends-with / .contains]=<group: string>: operación contra un grupo de contactos;
      • keypinning=<value: true / false> definición de la clave pública del contacto;
      • encryption=<value: true / false> cifrado por defecto del contacto;
      • signing=<value: true / false>  firma por defecto del contacto.
    • :addrbook:myself Direcciones pertenecientes al usuario actual;
    • :addrbook:organization Direcciones pertenecientes a los miembros de la organización actual;
    • :incomingdefaults:inbox Lista blanca
    • :incomingdefaults:spam Lista negra
  • Ver: Acceso a tu lista de contactos

Eval

  • Uso: vnd.proton.eval
  • Descripción: Evalúa una función aritmética simple proporcionada en una cadena.
  • Documentación: Transformación de variables

Include

Expiración

Pruebas

Currentdate

  • Uso:
currentdate [":zone" <time-zone: string>] [COMPARATOR] [MATCH-TYPE] <date-part: string> <key-list: string-list>

Fecha

  • Uso:
date [":zone" <time-zone: string> / ":originalzone"] [MATCH-TYPE] <header-name: string> <date-part: string> <key-list: string-list

HasFlag

  • Uso:
hasflag [MATCH-TYPE] [COMPARATOR] <list-of-flags: string-list>
  • Descripción: Comprueba si un determinado mensaje tiene una determinada marca.
  • Paquete: imap4flags
  • Ver: Primeros pasos

Sobre

  • Uso:
envelope [COMPARATOR] [ADDRESS-PART] [MATCH-TYPE] <envelope-part: string-list> <key-list: string-list>

Dirección·

  • Uso:
address [COMPARATOR] [ADDRESS-PART] [MATCH-TYPE] <header-list: string-list> <key-list: string-list>
  • Descripción: Comprueba si los encabezados especificados, analizados como una dirección, coinciden con las claves especificadas.
  • Paquete: <por defecto>
  • Ver: Comparación con direcciones en Sieve

Encabezado

  • Uso:
header [COMPARATOR] [MATCH-TYPE] <header-names: string-list> <key-list: string-list>

HasExpiration

  • Uso:
hasexpiration
  • Descripción: Comprueba si un mensaje tiene establecido un tiempo de expiración.
  • Paquete: vnd.proton.expire

Exists

  • Uso:
exists <header-names: string-list>

Expiración

  • Uso:
expiration :comparator "i;ascii-numeric" [MATCH-TYPE] <unit: "day" / "minute" / "second"> <key-list: string-list>
  • Descripción: Compara el tiempo de expiración del mensaje con las claves dadas. La prueba fallará si se ejecuta en un mensaje que no expira.
  • Paquete: vnd.proton.expire

Tamaño

  • Uso:
size <":over" / ":under"> <limit: number>
  • Descripción: Comprueba si el tamaño total del mensaje (incluyendo los archivos adjuntos) está por encima o por debajo de un determinado límite.
  • Paquete: <por defecto>
  • Ver: Filtrar por tamaño del mensaje en Sieve

String

  • Uso:
string [MATCH-TYPE] [COMPARATOR] <source: string-list> <key-list: string-list>
  • Descripción: Evalúa si alguna de las cadenas de origen coincide con alguna clave.
  • Paquete: variables

Anyof

  • Uso:
anyof <tests: test-list>
  • Descripción: Realiza un OR lógico con las pruebas que se le proporcionan.
  • Paquete: <por defecto>
  • Ver: Primeros pasos

Allof

  • Uso:
allof <tests: test-list>
  • Descripción: Realiza un AND lógico con las pruebas que se le proporcionan.
  • Paquete: <por defecto>
  • Ver: Primeros pasos

Not

  • Uso:
not <test: test>
  • Descripción: Invierte el resultado de la prueba dada.
  • Paquete: <por defecto>
  • Ver: Primeros pasos

True

  • Uso:
true
  • Descripción: Siempre coincide.
  • Paquete: <por defecto>

False

  • Uso:
false
  • Descripción: Nunca coincide.
  • Paquete: <por defecto>

Acciones

Require

  • Uso:
require <packages: string-list>
  • Descripción: Carga una extensión especificada para que se puedan usar sus métodos o modificaciones.
  • Paquete: <por defecto>
  • Ver: Primeros pasos

FileInto

  • Uso:
fileinto <folder: string>
  • Descripción: Mueve el mensaje que se está procesando a una determinada carpeta.
  • Package: fileinto
  • Ver: Primeros pasos

Addflag

  • Uso:
addflag <list-of-flags: string-list>
  • Descripción: Añade la marca especificada al mensaje que se está procesando.
  • Package: imap4flags
  • Ver: Primeros pasos

Removeflag

  • Uso:
removeflag <list-of-flags: string-list>
  • Descripción: Elimina las marcas especificadas del mensaje que se está procesando.
  • Package: imap4flags

Setflag

  • Uso:
setflag <list-of-flags: string-list>
  • Descripción: Elimina todas las marcas y establece las marcas especificadas en el mensaje que se está procesando.
  • Package: imap4flags

Stop

  • Uso:
stop
  • Descripción: Detiene el procesamiento de todos los filtros Sieve. Los filtros Sieve posteriores no se ejecutarán.
  • Paquete: <por defecto>

Return

  • Uso:
return
  • Descripción: Detiene el procesamiento del filtro Sieve actual. Los filtros Sieve posteriores se seguirán ejecutando.
  • Paquete: include

Set

  • Uso:
set [MODIFIER] <name: string> <value: string>
  • Descripción: Crea nuevas variables asociando el nombre y el valor dados.
  • Paquete: variables
  • Ver: Creación de variables

Discard

  • Uso:
discard
  • Descripción: Descarta el mensaje al final de este filtro Sieve. Después de descartarlo, no se ejecutará ningún otro filtro Sieve.
  • Paquete: <por defecto>

Keep

  • Uso:
keep
  • Descripción: Revierte el último comando de descarte. Solo tendrá efecto si se encuentra en el mismo filtro Sieve. Si no se ha ejecutado ningún descarte, esto no hará nada.
  • Paquete: <por defecto>

Rechazar

  • Uso:
reject <reason: string>

Expire

  • Uso:
expire <unit: "day" / "minute" / "second"> <value: string>
  • Descripción: Hace expirar un mensaje transcurrido el tiempo indicado.
  • Paquete: vnd.proton.expire
  • Ver: Gestión de la expiración

Unexpire

  • Uso:
unexpire
  • Descripción: Elimina el tiempo de expiración de un mensaje.
  • Paquete: vnd.proton.expire

Ausencia

  • Uso:
vacation [":days" number] [":subject" string] [":mime"] [":handle" string] <reason: string>
  • Descripción: Envía una respuesta automática a la dirección SMTP del remitente con el motivo especificado como cuerpo.
  • Paquete: vacation (requiere una cuenta de pago)
  • Ver: Mensajes de vacaciones y pruebas de fecha

Valid External List

  • Uso:
valid_ext_list <ext-list-names: string-list>
  • Descripción: Comprueba si todas las listas externas especificadas son compatibles y válidas.
  • Paquete: extlists