Página inicial da Proton

Filtro Sieve (filtros personalizados avançados)

Leitura
40 min
Categoria
Receber e ler e-mails

O Proton Mail oferece aos usuários várias maneiras de filtrar e-mails automaticamente, atribuindo marcadores ou organizando-os em pastas. Em geral, existem três métodos:

  1. Adicionar remetentes à Lista de bloqueio e Listas de permitidos para que eles sejam sempre ou nunca colocados na pasta de spam;
  2. Criar um filtro personalizado usando a interface interativa do Proton Mail;
  3. [Mais avançado] Criar um filtro personalizado no Sieve.

Desses métodos, criar um filtro personalizado no Sieve oferece a maior versatilidade, mas também é mais complicado de usar. Por esse motivo, consideramos o Sieve um recurso avançado para usuários com alguma experiência técnica. Para a maioria dos usuários, a interface interativa é adequada para criar os filtros personalizados de que você precisa.

Índice

O que é o Sieve?

O Sieve é uma linguagem de programação usada para filtrar e-mails. Você pode criar filtros no Sieve escrevendo regras simples. Por exemplo, “Atribuir o marcador verde a todas as mensagens de Kyle”. A combinação dessas regras pode criar um sistema de filtragem sofisticado.

Você pode escrever regras do Sieve do zero, emprestá-las de exemplos como os deste artigo ou usar um software que facilite o processo.

Na verdade, já oferecemos a você uma maneira de criar filtros do Sieve usando a interface interativa, que usa os seus dados de entrada para gerar filtros do Sieve. Outra boa maneira de aprender Sieve é criando filtros usando a interface interativa e editando-os no Sieve, já que a própria interface interativa usa um subconjunto do Sieve.

Por exemplo, compare o seguinte filtro criado usando a interface interativa…


… com o código para o mesmo filtro visualizado no editor do Sieve:

Este artigo apresentará o Sieve a você e explicará como escrever seus próprios filtros do Sieve. Se precisar de mais informações sobre como usar o Sieve, existem muitos outros tutoriais on-line que podem ajudar. Se tiver dúvidas sobre o Sieve no Proton Mail que não sejam respondidas nesta página, você sempre poderá entrar em contato com a equipe de suporte aqui.

Primeiros passos

Para começar a criar filtros do Sieve, entre em mail.proton.me(nova janela), vá em Configurações → Todas as configurações → Proton Mail → Filtros → Adicionar filtro Sieve.

Um script do Sieve é composto por uma lista de comandos. Na maioria dos scripts, ele começa com um comando require. O comando require carrega uma extensão que fornece uma determinada funcionalidade. Por exemplo, para atribuir um marcador ou colocar uma mensagem em uma pasta, precisamos do comando fileinto.

Para carregar esse comando, simplesmente escrevemos:

require "fileinto";

Para carregar várias extensões, você pode usar uma lista:

require ["fileinto", "imap4flags"];

Nesse caso, o imap4flags carrega uma extensão que permite marcar o e-mail como lido. Após o comando require, você geralmente realizará alguns testes na mensagem recebida. Isso é feito combinando if com outro comando, como address ou header.

Por fim, se os testes forem bem-sucedidos, você poderá aplicar uma ação a uma mensagem. Por exemplo, suponha que queiramos colocar todos os e-mails de um remetente específico na mesma pasta e marcar o e-mail recebido como lido. Isso poderia ser escrito como:

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

Observe que o sinal # indica um comentário e não é interpretado como parte do script do Sieve. Além disso, a pasta ou o marcador que você definir (enemies aqui) deve existir em seu ambiente: você pode aprender a criar pastas e marcadores aqui. Depois de inserir esse filtro, clique no botão SALVAR. Agora, seu filtro será executado para cada e-mail recebido.

Claro que você pode querer colocar e-mails de vários remetentes na mesma pasta. Nesse caso, você pode passar uma lista de strings para o comando address (uma string(nova janela) é uma série de caracteres, neste caso, um endereço de e-mail):

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";
}

Observe que, sempre que você puder passar uma string para uma condição de teste, geralmente também será possível passar uma lista. O sistema tentará encontrar uma correspondência testando qualquer uma das strings da lista. Isso não se aplica a comandos como fileinto, addflag, etc.

But Sieve is more powerful than just reordering your mailbox. It also allows you to reject emails with a response message:

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

Usar testes

Combinar testes no Sieve

Como mostramos a você na seção Primeiros passos, você pode realizar testes usando o comando if em mensagens recebidas para determinar se um e-mail deve ser afetado por um comando require.

Além do comando if, existem outros comandos de teste que permitem estruturar seu script de maneira simples.

Else

O comando else permite que você faça algo quando o comando if não executa suas ações. Um exemplo disso é:

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";
}

Aqui, o e-mail será movido para a pasta Kenny se o assunto for exatamente mmph mmph. Caso contrário (ou seja, quando o assunto não for exatamente mmph mmph), o e-mail será movido para a pasta Understandable.

Elsif

O elsif é a contração de else if. Assim como o comando else, ele será executado se a condição if estiver incorreta, mas apenas se a condição elsif estiver correta. Se o elsif não estiver correto, o próximo bloco elsif ou else será executado.

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";
}

Observe que apenas um dos blocos if, elsif ou else será executado em uma única execução.

Anyof

Às vezes, você precisa executar um comando quando um de vários testes for bem-sucedido. Para isso, você pode usar o comando anyof. Isso é feito escrevendo anyof seguido por um parêntese ‘(’, as instruções que você deseja testar separadas por vírgulas e um parêntese de fechamento ‘)’.

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 colocará as mensagens que vêm de kenny@northpark.example.com ou que contêm mmph mmph na linha de assunto na pasta Kenny.

Allof

O equivalente ao anyof também existe: allof. Isso permite que você execute um comando apenas quando todas as condições informadas forem correspondidas:

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 colocará as mensagens que vêm de kenny@northpark.example.com e contêm mmph mmph na linha de assunto na pasta Kenny.

Not

Por fim, às vezes você precisa aplicar um comando se algo não corresponder. Adicionar not na frente da instrução garantirá que isso aconteça:

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";
}

O que é igual 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";
}

Isso coloca todos os e-mails que não contêm real guitar na linha de assunto na pasta Young people.

É claro que é possível combinar todos esses testes. Por exemplo, você pode querer marcar com estrela um e-mail se ele não for de Kenny e não contiver mmph mmph no assunto:

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

Realizando testes em cabeçalhos

Usando o comando address, você pode realizar testes em cabeçalhos de endereço, como os cabeçalhos from, to e sender. Você pode extrair diferentes partes do endereço de e-mail usando uma das seguintes flags:

  • :localpart — a parte antes do símbolo de arroba (@)
  • :domain — a parte depois do símbolo de arroba (@)
  • :all — o endereço completo

O trecho a seguir explica o uso deste 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";
}

Em resumo, este script colocará tudo o que for enviado do domínio northpark.example.com em PaperPeople e do springfield.example.com em YellowPeople.

Além disso, não importa de qual domínio um e-mail é enviado, se a parte antes do @ for igual a chef (por exemplo, chef@example.com), a mensagem será sinalizada. Outro uso interessante é armazenar automaticamente tudo o que for enviado para um endereço em uma pasta:

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

Avançado

O comando envelope permite realizar mais testes. Em geral, o teste address apenas recupera o valor do cabeçalho. No entanto, na sessão SMTP, é possível especificar um endereço from diferente daquele no cabeçalho.

Na interface de cabeçalho do Proton Mail, o envelope-from é igual ao cabeçalho return-path e o envelope-to é igual ao cabeçalho x-original-to.

Usando o comando envelope, você pode recuperar os endereços to: e from: reais do envelope. Observe que não existem outros campos além desses dois, portanto, sender não existe neste comando. Observe também que o envelope está em uma extensão e, portanto, exige que você use o require nessa extensão primeiro.

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";
}

Usando comparadores para avaliar dois valores

Quando um teste avalia dois valores, é possível especificar como essa comparação é feita usando diferentes flags chamadas comparators. Anteriormente, já usamos dois comparadores: :is e :contains, que verificam se a string fornecida é exatamente igual ao valor específico, e se o valor específico contém a string fornecida, como no teste a seguir.

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";
}

O comparador :matches também pode ser usado para definir um formato mais específico. Ele comparará ambos os valores do início ao fim, assim como o comparador :is. No entanto, no caso de :matches, o valor que você definiu pode conter os valores ? e *. O ponto de interrogação corresponderá a um caractere, e a estrela (chamada de curinga) corresponderá a zero ou mais caracteres.

Com este formato, você pode criar este teste:

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

Neste exemplo, o teste será bem-sucedido se o assunto da mensagem começar com mmph e contiver qualquer caractere ou caracteres depois dele. Em outras palavras, o e-mail será sinalizado quando o assunto começar com ‘mmph’. ‘mmph mmph’ e ‘mmph mmph Hello’ corresponderão; ‘Hello mmph’ e ‘Springfield sales’ não.

A estrela também pode ser usada no meio do valor e várias vezes, da seguinte forma:

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

Este teste corresponderá se o assunto começar com ‘mmph ’ (com um espaço), contiver outro ‘mmph ’ (com um espaço) e terminar com ‘mmph’ (sem um espaço). Os assuntos correspondentes são ‘mmph mmph mmph’, ‘mmph mmph mmphmmph’ ou ‘mmph is mmph and mmph’.

Este comparador :matches pode ser muito útil na comparação de endereços. Como você deve saber, o Proton Mail possui vários domínios: protonmail.com and proton.me. Se você quiser verificar se uma mensagem vem de um usuário do Proton Mail, você pode usar este script:

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

Se por algum motivo você precisar corresponder exatamente ao caractere * ou ?, você pode escapá-los adicionando \\ antes: \\* corresponderá a uma estrela e \\? corresponderá a um ponto de interrogação.

Observe que também oferecemos suporte à extensão regex, que também define o comparador :regex. Esse comparador é uma versão mais precisa do :matches, mas é muito complexo. Para mais informações, leia a documentação oficial(nova janela).

Em alguns casos (como você verá na sequência deste artigo), você pode querer comparar valores numéricos. O pacote relational foi feito para esse uso. Esse pacote define o comparador :value, que é seguido pelo tipo de comparação.

Ele permite que você verifique se um valor é maior que (sendo o tipo de comparação “gt”), maior ou igual a (“ge”), igual a (“eq”), menor ou igual a (“le”) ou menor que (“lt”) o valor fornecido.

Ao comparar valores numéricos, o pacote comparator-i;ascii-numeric também é muito útil. Ele informa ao interpretador do script que o conteúdo da string é um número, e não uma string comum. Ele pode ser usado adicionando ao teste :comparator “i;ascii-numeric”.

Com todas essas informações, podemos criar o seguinte script:

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

Este teste moverá a mensagem para a pasta Dummy example se o assunto for maior ou igual a 2. Se o assunto não for um número, mas sim um texto, o teste falhará. Dessa forma, este exemplo parece bem bobo, mas ele foi pensado para ser usado em combinação com outras extensões, como date, que definiremos mais adiante neste artigo.

Comparação usando contexto no Sieve

Você também pode acessar informações relacionadas à sua conta e ao contexto do Proton Mail em geral usando extensões. Por exemplo, você pode verificar se o endereço do remetente está na sua lista de contatos.

Acessando sua lista de contatos

Você pode acessar sua lista de contatos usando a extensão extlists. Combinada com os testes de cabeçalho, você pode verificar se um contato está na sua lista de contatos.

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

Este teste sinalizará uma mensagem com o marcador Known se o remetente estiver contido na lista :addrbook:personal?label=Family. A lista pode ser dividida em duas partes. Primeiro, :addrbook:personal significa que o endereço está no seu catálogo de endereços pessoal. Segundo, label=Family restringe ainda mais a lista, especificando que, além de estar no seu catálogo de endereços, o contato também deve pertencer ao grupo de contatos Family. Se precisar, você pode alterar esse marcador para outro grupo de contatos. Você pode usar :addrbook:personal?label=Work se quiser, caso em que o teste seria bem-sucedido apenas se o remetente estivesse no seu catálogo de endereços e no grupo de contatos Work.

De forma mais geral, uma lista respeita o Tag URI Scheme(nova janela), e você pode adicionar parâmetros extras para restringir seus filtros. Então, você pode usar esta lista da seguinte forma:

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

Fornecemos quatro listas diferentes:

  • :addrbook:personal¹ verifica se um endereço está na sua lista de contatos. A lista aceita o parâmetro label que corresponde a um grupo de contatos específico. Este parâmetro pode ser declinado em quatro subversões:
    • :addrbook:personal?label=something corresponderá a um contato que está no grupo de contatos “something”;
    • :addrbook:personal?label.starts-with=something corresponderá a um contato que pertence a pelo menos um grupo que começa com “something”;
    • :addrbook:personal?label.ends-with=something corresponderá a um contato que pertence a pelo menos um grupo que termina com “something”;
    • :addrbook:personal?label.contains=something corresponderá a um contato que pertence a pelo menos um grupo que contém “something”.

Você também pode acessar informações criptográficas sobre o e-mail correspondente:

  • :addrbook:personal?keypinning=true corresponderá a um contato que possui uma chave de confiança. Alterar de true para false corresponderá a um contato que não possui uma chave de confiança;
  • :addrbook:personal?encryption=true corresponderá a um contato para o qual a criptografia está ativada. Alterar de true para false corresponderá a um contato para o qual a criptografia não está configurada ou está desativada;
  • :addrbook:personal?signing=true corresponderá a um contato para o qual a assinatura está ativada. Alterar true para false corresponderá a um contato para o qual a assinatura está desativada.
  • :addrbook:myself¹ corresponde a cada endereço que pertence a você mesmo;
  • :addrbook:organization corresponde a cada endereço que pertence a alguém na organização da qual você é membro;
  • :incomingdefaults:inbox verifica se o endereço está na sua lista de permitidos;
  • :incomingdefaults:spam verifica se o endereço está na sua Lista de bloqueio.

Combinadas com a extensão de variável (descrita no próximo parágrafo), as variáveis correspondentes serão alteradas. A variável correspondente ${0} sempre conterá o último endereço de e-mail contido na lista especificada. Se a lista foi marcada com a nota 1, a variável correspondente ${1} conterá o nome de exibição.

Por exemplo, com as listas abaixo, você pode criar um filtro que excluirá todos os e-mails recebidos de qualquer pessoa que não seja da sua família ou alguém na sua lista de permissões:

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
}

Se essa condição for atendida, a ação discard será executada. Essa ação exclui o e-mail imediatamente e permanentemente . Você também pode simplesmente movê-lo para a pasta lixeira usando uma ação fileinto em vez de discard: fileinto “trash”;.

Criando variáveis

Outra ferramenta útil ao gerenciar o contexto é a definição de variável. Uma variável é um local temporário de armazenamento no qual você pode colocar texto e identificá-lo com um nome. Mais tarde, você poderá reutilizar esse conteúdo chamando-o pelo nome. Por exemplo, você poderia ter o seguinte 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}";

O objetivo deste script é rejeitar um e-mail com uma mensagem personalizada. Se o e-mail original for de kenny e o assunto for ‘mmph mmph’, a variável ‘message’ é criada, contendo mmph mmph. Caso contrário, a mensagem será preenchida com ‘Sorry, I don’t want emails today!’. Então, na última etapa, reutilizamos essa variável no comando reject.

O Sieve não define variáveis nativamente, por isso elas são definidas na extensão variables, que deve ser solicitada no início do seu script. Existem duas maneiras de definir uma variável.

  • Criação explícita de uma variável:

A ação set é fornecida para criar uma variável.

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

A primeira string é o nome da sua variável e a segunda é o valor dela. Sendo assim, o exemplo anterior cria uma variável chamada labelname e contendo Work.

Uma vez que uma variável é definida, você pode chamá-la adicionando o seguinte formato em uma string: ${name}, onde name é o nome da sua variável. Quando executada, ela será substituída pelo valor da variável. (Se você não tiver definido a variável, ela será substituída por uma string vazia.) Assim, no seguinte 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}";

Seu e-mail será marcado com o marcador /Work. Como já definimos a variável labelname, ela é substituída por Work. No entanto, foldername não está definida, por isso é simplesmente removida.

  • Atribuição implícita de uma variável:

O caso de uso mais interessante de variáveis é ao usar um teste :matches. Vamos dar o seguinte exemplo, onde o remetente do e-mail é 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}";
}

Quando usado com a extensão de variáveis, o resultado de uma operação match será armazenado nas variáveis. Várias variáveis serão definidas com um nome numérico. Primeiro, a variável 0 conterá a correspondência completa (no nosso exemplo, será o endereço completo: test@proton.me). Depois, o primeiro grupo correspondente será atribuído à variável 1 (no nosso exemplo, será test), o segundo grupo correspondente será atribuído à segunda variável (proton.me) e assim por diante até o último grupo correspondente.

No nosso exemplo, o comando fileinto é executado. A localização é definida para ${1} que é reconhecida como uma variável e, portanto, substituída pelo seu valor, conforme calculado acima: test.

Observe que também é possível atribuir variáveis em um teste :regex, usando grupos de correspondência de expressão regular.

Transformando variáveis

Uma excelente possibilidade é a transformação de variáveis. Para isso, a palavra-chave set pode ser usada com uma combinação de sinalizadores que podem ser usados para alterar o valor antes de atribuí-lo à variável.

  • :lower mudará o valor de uma variável para minúsculas;
  • :upper mudará o valor de uma variável para maiúsculas;
  • :lowerfirst mudará a primeira letra do valor da variável para minúscula;
  • :upperfirst mudará a primeira letra do valor da variável para maiúscula;
  • :quotewildcard colocará entre aspas qualquer caractere curinga contido na string, para que ele possa ser usado literalmente em uma instrução de correspondência;
  • :length retornará o comprimento do valor.

Observe que você também pode reutilizar uma variável definida em outra ação set. Vamos melhorar nossos exemplos 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}";

Passo a passo, o filtro criará três variáveis. O primeiro comando set criará a variável labelname. O conteúdo da variável é Work. De fato, o valor original WORK é transformado usando os sinalizadores :lower e :upperfirst, mudando para work e depois para Work.

O segundo comando set criará uma segunda variável chamada foldername, contendo a string Geneva. De fato, foram usados os sinalizadores :lower e :upperfirst.

Finalmente, a variável location é criada. O valor “${foldername}/${labelname}” contém duas variáveis: foldername e labelname. Portanto, o interpretador do Sieve substituirá essas variáveis por seus valores: Work and Geneva.

Finalmente, a variável location é usada como argumento para o comando fileinto. Assim, o e-mail será movido para a pasta cujo nome é o valor da variável location: Work/Geneva.

Os comparadores também podem ser aplicados às variáveis correspondentes:

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

Aqui, se o remetente do e-mail for test@proton.me, ele será marcado com o marcador Test.

Outra maneira de alterar o valor de uma variável é usar a extensão vnd.proton.eval. Essa extensão define o novo sinalizador :eval, que permitirá que você faça alguns cálculos simples:

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}";
}

Neste exemplo, e considerando ainda que o e-mail está chegando de test@proton.me, o e-mail será marcado com o valor 478. De fato, o comprimento da primeira variável correspondente é 19, e o resultado de 19 * 25 – 1 / 8 + 3 é arredondado para 478.

Isso pode parecer inútil a princípio, mas esta extensão faz mais sentido quando combinada com outras operações.

Comparação com outros campos no Sieve

A correspondência em cabeçalhos específicos também é possível. Por exemplo, para colocar todas as mensagens enviadas para listas (geralmente são mensagens de marketing ou boletins informativos), você pode fazer:

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

Para organizar e-mails de redes sociais em sua própria pasta, você poderia escrever:

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";
}

Observe que usamos:

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

em vez de:

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

Pois este último verifica se tanto o x-facebook quanto o x-linkedin-id foram definidos.

Para realmente verificar qual valor um cabeçalho contém, você pode usar o teste 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";
}

Além da operação :is, que faz uma correspondência exata, o comando header também suporta :matches, que faz a correspondência usando caracteres curinga (por exemplo, “*@*.com” corresponderá a qualquer endereço de e-mail que termine em ponto com), e o comando :contains, que verifica se o cabeçalho contém uma determinada string.

Para criar filtros do Sieve, pode ser útil recuperar os cabeçalhos de um e-mail. Para fazer isso na interface web do Proton Mail, acesse Mais () → Visualizar cabeçalhos. Uma nova janela se abrirá contendo todos os cabeçalhos do e-mail.

Filtrar usando o tamanho da mensagem no Sieve

É possível tratar e-mails grandes de forma diferente de e-mails pequenos. Por exemplo, você pode querer sinalizar e-mails grandes para poder excluí-los e economizar espaço na caixa de correio. Isso pode ser feito da seguinte maneira:

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 você pode ver, as unidades estão disponíveis se quiser especificar tamanhos grandes, adicionando a letra correspondente à unidade esperada logo após o número. Três unidades estão disponíveis: K para um kibiocteto (ou 1024 bytes), M para um mebiocteto (ou 1 048 576 bytes) e G para um gibiocteto (ou 1 073 741 824 bytes).

Observe que “over” neste caso significa maior que, e “under” significa menor que. Isso significa que, se uma mensagem tiver um tamanho de exatamente 1000 bytes, então nem

size :under 1000

nem

size :over 1000

corresponderá.

Observe que os filtros do Sieve não têm acesso ao conteúdo real e mostram apenas o tamanho criptografado.

Executando ações avançadas em mensagens

Você pode executar diferentes reações a uma mensagem no Sieve. Já apresentamos as ações fileinto, addflag, discard e reject nas seções anteriores. Aqui, apresentaremos ações mais avançadas.

Mensagens de férias e testes de data

Você pode replicar o recurso de resposta automática no Sieve usando o comando vacation. Na verdade, o recurso de resposta automática nas suas Configurações depende do Sieve para funcionar. Mas, ao usar as opções de vacation dentro de um script, você tem muito mais possibilidades de personalizar suas respostas automáticas. Por exemplo, você pode criar mensagens específicas dependendo das condições. Observação: assim como o recurso de resposta automática nas Configurações, a ação vacation está disponível apenas em planos pagos.

O comando vacation envia uma resposta de férias para qualquer pessoa que tentar entrar em contato com você. Ele geralmente é associado aos testes currentdate ou date para enviar respostas em um intervalo de tempo específico.

Suponha que eu vá sair de férias de 14 de julho de 2017 a 14 de agosto de 2017, no fuso horário do Colorado. Posso usar o seguinte código Sieve para configurar uma resposta 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.";
}

Alguns dos argumentos opcionais para o comando vacation são os argumentos :handle e :days. Por padrão, o Sieve não responderá várias vezes ao mesmo remetente dentro de um número específico de dias, chamado de timeout. Isso evita que você envie acidentalmente inúmeros e-mails automatizados.

Para controlar o timeout, você pode usar o parâmetro :days. O argumento :days é usado para especificar o período em que os endereços são mantidos e não recebem resposta, sendo sempre especificado em dias. Às vezes, você tem vários comandos vacation no seu script Sieve e precisa garantir que cada um deles envie uma resposta pelo menos uma vez (se a regra for correspondida). Nesse caso, a opção :handle pode ser usada. O argumento de :handle é uma string que identifica o tipo de resposta que está sendo enviada.

Para ver como isso funciona, suponha que você seja um professor. Os professores costumam receber tarefas de casa por e-mail. É útil organizá-las em uma pasta própria. Além disso, você pode rejeitar qualquer entrega feita após o prazo.

Em um caso como esse, você pode querer usar o handle para garantir que as respostas sejam enviadas quando necessário:

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.";
    }
}

Aqui estão todos os argumentos permitidos para a resposta de férias, listados na ordem em que os argumentos devem ser passados:

  • :days é o número de dias que o autoresponder deve evitar enviar uma resposta ao mesmo remetente após enviar uma mensagem de férias
  • :subject é um prefixo (por padrão, auto) que o autoresponder deve usar para responder ao remetente. Por exemplo, “Homework Assignment 2” receberá uma resposta com “late: Homework Assignment 2” se :subject “late” for passado.
  • :mime indica que a primeira linha de resposta usa um formato específico. Isso permite que o remetente responda com mensagens HTML. Por exemplo, para escrever uma resposta em HTML, passe o argumento :mime e escreva na primeira linha da resposta Content-Type : text/html.
  • :handle é uma string que identifica o tipo de resposta que está sendo enviada.

Observe que o parâmetro :zone em currentdate é opcional e usará a hora local do servidor (Genebra, Suíça, no caso do Proton Mail) se não for definido.

O parâmetro de zona aceita deslocamentos de fuso horário, que são strings no formato “+0100” (que significa UTC+1), e fusos horários reais no banco de dados ICANN (veja https://en.wikipedia.org/wiki/List_of_tz_database_time_zones(nova janela)). A última opção geralmente é mais útil (embora não seja o padrão do Sieve), pois ela também codifica o horário de verão de cada fuso horário.

Você pode comparar datas usando o parâmetro normal :is/ :contains/ :matches. Por exemplo, o seguinte comando Sieve corresponde a qualquer data em julho de 2017:

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

Mas na maioria dos casos o parâmetro :value é muito mais útil.

O último parâmetro que você precisa passar é o formato. O formato também codifica qual parte da data você deseja comparar. No exemplo fornecido, usamos o formato de data. Todos os formatos suportados são:

  • year, o ano codificado no formato de “0000” a “9999”
  • month, o mês codificado como “01” a “12”
  • day, o dia codificado como “01” a “31”
  • date, codificado como aaaa-mm-dd
  • hour, a hora codificada como “00” a “23”
  • minute, o minuto codificado como “00” a “59”
  • second, o segundo codificado como “00” a “60” (60 é um segundo bissexto(nova janela), ocorrendo apenas às 23:59:60 quando os cientistas julgarem necessário)
  • time, o horário como hh:mm:ss
  • iso8601, a data e o horário de acordo com o padrão ISO8601, por exemplo: 2005-08-15T15:52:01+00:00
  • std11, a data e o horário de acordo com o padrão RFC2822, por exemplo: Mon, 15 Aug 2005 15:52:01 +0000
  • zone, o deslocamento de fuso horário no formato +/-zzzz, por exemplo, +0000 ou -1200
  • julian, o número de dias desde 17 de novembro de 1858 UTC
  • weekday, o dia da semana começando de domingo como 0 até sábado como 6

Por fim, também é possível recuperar a data de um cabeçalho em vez de usar o currentdate. Esse comando de data funciona da mesma forma que o currentdate, exceto que requer uma string extra antes da string de formato: o nome do cabeçalho. Por exemplo:

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

Observe que os cabeçalhos não são necessariamente precisos: um remetente pode alterá-los à vontade e, portanto, eles não são confiáveis.

Considerações:

  1. A resposta automática não responde a mensagens geradas automaticamente, como listas de e-mails, e-mails enviados por outra resposta automática ou mensagens enviadas por um endereço noreply.
  2. A resposta automática não enviará mensagens várias vezes para o mesmo endereço de e-mail, exceto quando o comando vacation tiver um :handle diferente.

Gerenciando a expiração

Um recurso exclusivo do Proton Mail é a capacidade de definir um tempo de expiração nas mensagens enviadas. Nesse momento, a mensagem será excluída da caixa de correio do destinatário.

Você também pode usar esse recurso para gerenciar suas mensagens recebidas adicionando um tempo de expiração:

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

O script acima excluirá qualquer e-mail recebido após 10 dias. Esse é um pouco extremo, pois se aplica a todos os e-mails. Em vez disso, você provavelmente deve usar uma condição para aplicar o script apenas a um conjunto específico de e-mails. Por exemplo, você pode expirar qualquer mensagem de alguém que não está nos seus contatos:

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";
}

Observação: se o tempo de expiração especificado exceder 730 dias, ele será automaticamente limitado a 730 dias.

Limitações do Sieve

Há várias limitações do Sieve que você deve observar.

  • As mensagens enviadas não podem ser movidas manualmente ou por filtro para a Caixa de entrada/Rascunho. Elas sempre permanecerão na pasta Enviados e com as pastas/marcadores aplicados pelo usuário ou filtro.
  • As mensagens recebidas não podem ser movidas manualmente ou por filtro para Rascunho/Enviados.
  • Os rascunhos não podem ser movidos manualmente ou por filtro para a Caixa de entrada/Enviados.
  • Para mensagens no Spam — ou mensagens arquivadas no spam durante o processamento — não enviamos mensagens de resposta automática/férias. Se você precisar de um recurso como esse, considere adicionar uma pasta personalizada — mySpam, por exemplo — e desativar as notificações para ela.
  • Limitações de respostas automáticas/mensagens de férias

Nota sobre o suporte a expressões regulares

A implementação do Sieve pelo Proton segue o padrão de filtragem de e-mail do Sieve, que inclui apenas um suporte mínimo a expressões regulares. Algumas sintaxes abreviadas comuns de expressão regular, como \b (limite de palavra), \w (caractere de palavra), \W (caractere não de palavra) e \d (dígito), não são suportadas no Sieve. Como resultado, o uso desses caracteres abreviados em filtros pode fazer com que eles falhem silenciosamente. Essa limitação se deve ao próprio padrão Sieve, que prioriza a simplicidade e a compatibilidade entre plataformas. Para mais detalhes, consulte o rascunho da RFC de Expressões Regulares do Sieve.

Lista de ações e testes suportados

Pacotes

O Sieve suporta as seguintes extensões. Você pode consultar a documentação oficial para mais informações.

Data

  • Uso: date
  • Descrição: (nova janela)Fornece uma maneira de verificar informações de data.
  • Documentação: https://tools.ietf.org/html/rfc5260(nova janela)
  • Implementação: O comparador padrão é i;ascii-numeric e não i;ascii-casemap. De fato, date não é útil com o comparador casemap.
  • Veja: Mensagens de férias e testes de data

Envelope

FileInto

  • Uso: fileinto
  • Descrição: Aplica um marcador a uma mensagem ou a move para uma pasta.
  • Documentação: https://tools.ietf.org/html/rfc5228#section-4.1(nova janela)
  • Implementação: As barras indicam o caminho completo das pastas e devem ser escapadas se o nome de um marcador contiver uma barra. As seguintes opções são suportadas:
    • Work“: este é o marcador ou pasta chamado ‘Work’
    • Work/Project1“: esta é a subpasta ‘Project1’ que está na pasta ‘Work’
    • Work/Project1/Docs“: esta é a subpasta ‘Docs’ que está na subpasta ‘Project1’ que está na pasta ‘Work’
    • Work/Misc\\/Others“: esta é a subpasta ‘Misc/Others’ que está na pasta ‘Work’
  • Veja: Primeiros passos

Imap4flags

Reject

Vacation

Variables

Relacional

  • Uso: relacional
  • Descrição: Fornece operadores de correspondência relacional.
  • Documentação: https://tools.ietf.org/html/rfc5231

Regex

  • Uso: regex
  • Descrição: Fornece os operadores de correspondência regex.
  • Documentação: https://tools.ietf.org/id/draft-ietf-sieve-regex-01.html

Comparador numérico ASCII

Listas armazenadas externamente

  • Uso: extlists
  • Descrição: Fornece acesso a listas de contatos.
  • Documentação: https://tools.ietf.org/html/rfc6134(nova janela)
  • Implementação: As seguintes listas são suportadas
    • addrbook:personal : Lista de contatos pessoais. As seguintes consultas são suportadas:
      • label[.starts-with / .ends-with / .contains]=<group: string>: operação em um grupo de contatos;
      • keypinning=<valor: true / false> definição de chave pública do contato;
      • encryption=<valor: true / false> criptografia padrão do contato;
      • signing=<valor: true / false>  assinatura padrão do contato.
    • :addrbook:myself Endereços pertencentes ao usuário atual;
    • :addrbook:organization Endereços pertencentes aos membros da organização atual;
    • :incomingdefaults:inbox Lista de permitidos
    • :incomingdefaults:spam Lista de bloqueio
  • Veja: Acessar sua lista de contatos

Eval

  • Uso: vnd.proton.eval
  • Descrição: Avalia uma função aritmética simples fornecida em uma string.
  • Documentação: Transformar variáveis

Include

Expiração

  • Uso: vnd.proton.expire
  • Descrição: Gerencia a expiração de mensagens.
  • Documentação: Gerenciar expiração

Testes

Currentdate

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

Data

  • 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>
  • Descrição: Testa se uma determinada mensagem tem um determinado sinalizador.
  • Pacote: imap4flags
  • Veja também: Primeiros passos

Envelope

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

Endereço·

  • Uso:
address [COMPARATOR] [ADDRESS-PART] [MATCH-TYPE] <header-list: string-list> <key-list: string-list>
  • Descrição: Testa se o(s) cabeçalho(s) especificado(s) analisado(s) como endereço corresponde(m) à(s) chave(s) especificada(s).
  • Pacote: <padrão>
  • Veja também: Comparação com endereços no Sieve

Cabeçalho

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

HasExpiration

  • Uso:
hasexpiration
  • Descrição: Testa se uma mensagem tem um tempo de expiração definido.
  • Pacote: vnd.proton.expire

Exists

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

Expiração

  • Uso:
expiration :comparator "i;ascii-numeric" [MATCH-TYPE] <unit: "day" / "minute" / "second"> <key-list: string-list>
  • Descrição: Compara o tempo de expiração da mensagem com a(s) chave(s) fornecida(s). O teste falhará se for executado em uma mensagem sem expiração.
  • Pacote: vnd.proton.expire

Size

  • Uso:
size <":over" / ":under"> <limit: number>

String

  • Uso:
string [MATCH-TYPE] [COMPARATOR] <source: string-list> <key-list: string-list>
  • Descrição: Avalia se alguma das strings de origem corresponde a alguma chave.
  • Pacote: variables

Anyof

  • Uso:
anyof <tests: test-list>
  • Descrição: Realiza um OU lógico nos testes fornecidos.
  • Pacote: <padrão>
  • Veja: Primeiros passos

Allof

  • Uso:
allof <tests: test-list>
  • Descrição: Realiza um E lógico nos testes fornecidos.
  • Pacote: <padrão>
  • Veja também: Primeiros passos

Not

  • Uso:
not <test: test>
  • Descrição: Inverte o resultado do teste fornecido.
  • Pacote: <padrão>
  • Veja também: Primeiros passos

True

  • Uso:
true
  • Descrição: Sempre corresponde.
  • Pacote: <padrão>

False

  • Uso:
false
  • Descrição: Nunca corresponde.
  • Pacote: <padrão>

Ações

Require

  • Uso:
require <packages: string-list>
  • Descrição: Carrega uma extensão especificada para que seus métodos ou modificações possam ser usados.
  • Pacote: <padrão>
  • Veja: Primeiros passos

FileInto

  • Uso:
fileinto <folder: string>
  • Descrição: Move a mensagem que está sendo processada para uma determinada pasta.
  • Pacote: fileinto
  • Veja também: Primeiros passos

Addflag

  • Uso:
addflag <list-of-flags: string-list>
  • Descrição: Adiciona o sinalizador especificado à mensagem que está sendo processada.
  • Pacote: imap4flags
  • Veja também: Primeiros passos

Removeflag

  • Uso:
removeflag <list-of-flags: string-list>
  • Descrição: Remove os sinalizadores especificados da mensagem que está sendo processada.
  • Pacote: imap4flags

Setflag

  • Uso:
setflag <list-of-flags: string-list>
  • Descrição: Remove todos os sinalizadores e define os sinalizadores especificados na mensagem que está sendo processada.
  • Pacote: imap4flags

Stop

  • Uso:
stop
  • Descrição: Interrompe o processamento de todos os filtros Sieve. Os filtros Sieve subsequentes não serão executados.
  • Pacote: <padrão>

Return

  • Uso:
return
  • Descrição: Interrompe o processamento do filtro Sieve atual. Os filtros Sieve subsequentes ainda serão executados.
  • Pacote: include

Set

  • Uso:
set [MODIFIER] <name: string> <value: string>
  • Descrição: Cria novas variáveis associando o nome fornecido e o valor fornecido.
  • Pacote: variables
  • Veja: Criação de variáveis

Discard

  • Uso:
discard
  • Descrição: Descarta a mensagem ao final deste filtro Sieve. Após o descarte, nenhum outro filtro Sieve será executado.
  • Pacote: <padrão>

Keep

  • Uso:
keep
  • Descrição: Reverte o último comando discard. Só terá efeito se estiver no mesmo filtro Sieve. Se nenhum descarte tiver sido executado, isso não fará nada.
  • Pacote: <padrão>

Reject

  • Uso:
reject <reason: string>

Expire

  • Uso:
expire <unit: "day" / "minute" / "second"> <value: string>

Unexpire

  • Uso:
unexpire
  • Descrição: Remove o tempo de expiração de uma mensagem.
  • Pacote: vnd.proton.expire

Vacation

  • Uso:
vacation [":days" number] [":subject" string] [":mime"] [":handle" string] <reason: string>
  • Descrição: Envia uma resposta automática para o endereço SMTP do remetente com o motivo especificado como corpo.
  • Pacote: vacation (requer uma conta paga)
  • Veja também: Mensagens de férias e testes de data

Valid External List

  • Uso:
valid_ext_list <ext-list-names: string-list>
  • Descrição: Testa se todas as listas externas fornecidas são suportadas e válidas.
  • Pacote: extlists