Фильтр Sieve (продвинутые пользовательские фильтры)
- Чтение
- 11 мин.
- Категория
- Получать и читать электронные письма
Proton Mail предлагает пользователям различные способы автоматической фильтрации писем путем присвоения ярлыков или сортировки их по папкам. В целом существует три метода:
- Добавление отправителей в черный и белый списки , чтобы их письма всегда или никогда не попадали в папку со спамом;
- Создание пользовательского фильтра с помощью интерактивного интерфейса Proton Mail;
- [Самый продвинутый] Создание пользовательского фильтра в Sieve.
Из этих методов создание пользовательского фильтра в Sieve предлагает наибольшую гибкость, но этот способ и более сложен в использовании. По этой причине мы считаем Sieve функцией для опытных пользователей, обладающих некоторым техническим опытом. Большинству пользователей подойдет интерактивный интерфейс для создания необходимых вам пользовательских фильтров.
Содержание
Что такое Sieve?
Sieve — это язык программирования, используемый для фильтрации писем. Вы можете создавать фильтры в Sieve, записывая простые правила. Например: «Присвоить всем сообщениям от Кайла зеленый ярлык». Сочетание этих правил позволяет создать сложную систему фильтрации.
Вы можете писать правила Sieve с нуля, заимствовать их из примеров (подобных приведенным в этой статье) или использовать программное обеспечение, которое облегчает этот процесс.
На самом деле мы уже предлагаем вам способ создания фильтров Sieve с помощью интерактивного интерфейса, который на основе ваших вводных данных автоматически генерирует нужный код. Еще один хороший способ изучить Sieve — создавать фильтры в интерактивном интерфейсе, а затем редактировать их в режиме Sieve, поскольку сам интерфейс использует подмножество этого языка.
Например, сравните следующий фильтр, созданный с помощью интерактивного интерфейса…
… с кодом того же фильтра в редакторе Sieve:
Эта статья познакомит вас с Sieve и объяснит, как писать собственные фильтры. Если вам нужна дополнительная информация об использовании Sieve, в Интернете можно найти множество других руководств. Если у вас возникли вопросы о Sieve в Proton Mail, на которые нет ответов на этой странице, вы всегда можете обратиться в службу поддержки здесь.
Начало работы
Чтобы начать создавать фильтры Sieve, войдите в аккаунт на mail.proton.me(новое окно) и перейдите в раздел Настройки → Все настройки → Proton Mail → Фильтры → Добавить фильтр Sieve.
Скрипт Sieve состоит из списка команд. Большинство скриптов начинаются с команды require. Команда require загружает расширение, обеспечивающее определенный функционал. Например, чтобы присвоить ярлык или поместить сообщение в папку, нам нужна команда fileinto.
Чтобы загрузить эту команду, мы просто пишем:
require "fileinto";
Чтобы загрузить несколько расширений, вы можете использовать список:
require ["fileinto", "imap4flags"];
В данном случае imap4flags загружает расширение, которое позволяет помечать почту как прочитанную. После команды require вы обычно выполняете некоторые проверки входящего сообщения. Это делается путем объединения if и другой команды, такой как address или header.
Наконец, если проверки пройдены успешно, вы можете применить действие к сообщению. Например, предположим, что мы хотим поместить все письма от определенного отправителя в одну папку и пометить входящую почту как прочитанную. Это можно записать так:
require ["fileinto", "imap4flags"];
# I don't really like Spott
if address :is "from" "Spott.Tenerman@northpark.example.com"
{
addflag "\\Seen";
fileinto "enemies";
}Обратите внимание, что знак # указывает на комментарий и не интерпретируется как часть скрипта Sieve. Кроме того, папка или ярлык, которые вы задаете (в данном случае — enemies), должны существовать в вашей учетной записи: вы можете узнать, как создавать папки и ярлыки, здесь. После ввода этого фильтра нажмите кнопку «СОХРАНИТЬ». Теперь ваш фильтр будет срабатывать для каждого входящего письма.
Конечно, вы можете захотеть поместить письма от нескольких отправителей в одну и ту же папку. В этом случае вы можете передать список строк команде address (строка(новое окно) — это последовательность символов, в данном случае адрес электронной почты):
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";
}Обратите внимание: везде, где вы можете передать строку для условия проверки, обычно также можно передать и список. В таком случае система попытается найти совпадение по любой из строк в списке. Это не относится к таким командам, как fileinto, addflag и т. д.
Но возможности Sieve шире, чем просто наведение порядка в вашем почтовом ящике. Он также позволяет отклонять письма с отправкой ответного сообщения:
require "reject";
# Reject mails that spell my name wrong
if header :contains "subject" "Kyhel"
{
reject "My name is not Kyhel";
}Использование проверок
Объединение проверок в Sieve
Как мы показали вам в разделе «Начало работы», вы можете выполнять проверки входящих сообщений с помощью команды if, чтобы определить, должно ли письмо подпадать под действие команды require.
Помимо команды if, существуют и другие проверочные команды, которые позволяют легко структурировать ваш скрипт.
Else
Команда else позволяет выполнить определенное действие, если команда if не выполнила свои действия. Пример этого:
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";
}В данном случае письмо будет перемещено в папку Kenny, если тема в точности соответствует mmph mmph. В противном случае (то есть если тема не совпадает точно с mmph mmph) письмо будет перемещено в папку Understandable.
Elsif
Команда elsif представляет собой сокращение от else if. Как и команда else, она будет выполнена, если условие if не соблюдено, но только в том случае, если условие elsif верно. Если же условие elsif неверно, то будет выполнен следующий блок elsif или 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";
}Обратите внимание, что за один проход будет выполнен только один из блоков if, elsif или else.
Anyof
Иногда вам нужно выполнить команду, когда успешно пройден один из нескольких тестов. Для этого вы можете использовать команду anyof. Чтобы сделать это, напишите anyof, затем открывающую круглую скобку «(», проверяемые инструкции через запятую и закрывающую круглую скобку «)».
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";
}Этот скрипт будет помещать сообщения, которые приходят от kenny@northpark.example.com или содержат mmph mmph в теме, в папку Kenny.
Allof
Существует также аналог команды anyof — allof. Он позволяет выполнять команду только тогда, когда выполняются все заданные условия:
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";
}
Этот скрипт будет помещать сообщения, которые приходят от kenny@northpark.example.com и содержат mmph mmph в теме, в папку Kenny.
Not
Наконец, иногда требуется применить команду, если что-то не совпадает. Добавление not перед инструкцией обеспечит это действие:
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";
}Что равносильно:
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";
}Это помещает все электронные письма, тема которых не содержит «real guitar», в папку Young people.
Разумеется, вы можете комбинировать все эти проверки. Например, вы можете пометить электронное письмо звездочкой, если оно отправлено не от Kenny и не содержит mmph mmph в теме:
require ["fileinto", "imap4flags"];
if not anyof ( header :contains "subject" "mmph mmph",
address :is "from" "Kyhel.Broski@northpark.example.com" ) {
addflag "\\Flagged";
}Проверка заголовков
С помощью команды address вы можете проверять заголовки адресов, такие как from, to и sender. Вы можете извлекать различные части адреса электронной почты, используя один из следующих флагов:
- :localpart — часть перед символом @ (at)
- :domain — часть после символа @ (at)
- :all — адрес целиком
Следующий фрагмент кода поясняет использование этой команды:
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";
}Таким образом, этот скрипт будет помещать все сообщения, отправленные с домена northpark.example.com, в папку PaperPeople, а с домена springfield.example.com — в YellowPeople.
Более того, независимо от того, с какого домена отправлено электронное письмо, если часть перед @ равна chef (например, chef@example.com), то сообщение будет помечено флагом. Еще один интересный способ использования — автоматически сохранять все письма, отправленные на определенный адрес, в папку:
require ["fileinto", "imap4flags"];
# Put support mail in a separate organized folder
if address :localpart "to" "support"
{
fileinto "Support";
}Дополнительно
Команда envelope позволяет выполнять больше проверок. Как правило, тест address только извлекает значение из заголовка. Однако в сеансе SMTP можно указать адрес отправителя (from), отличный от указанного в заголовке.
В интерфейсе заголовков Proton Mail значение envelope-from соответствует заголовку return-path, а envelope-to — заголовку x-original-to.
Используя команду envelope, вы можете получить фактические адреса to: и from: из конверта (envelope). Обратите внимание, что других полей, кроме этих двух, не существует, поэтому sender в этой команде не поддерживается. Обратите внимание, что envelope находится в расширении, поэтому вам нужно сначала подключить это расширение с помощью команды require.
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";
}Использование компараторов для сравнения двух значений
Когда тест оценивает два значения, можно указать способ сравнения с помощью специальных флагов, называемых компараторами. Ранее мы уже использовали два компаратора: :is и :contains, которые проверяют, совпадает ли заданная строка в точности с указанным значением и содержит ли указанное значение заданную строку, как в следующем тесте.
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";
}Компаратор :matches также может использоваться для определения более точного формата. Он сравнивает оба значения от начала до конца, точно так же, как компаратор :is. Однако в случае с :matches заданное вами значение может содержать символы ? и *. Вопросительный знак соответствует одному любому символу, а звездочка (называемая подстановочным знаком) — нулю или более символам.
Используя этот формат, вы можете создать следующий тест:
require ["fileinto", "imap4flags"];
if header :matches "subject" "mmph*" {
addflag "\\Flagged";
}В этом примере тест будет успешно пройден, если тема сообщения начинается с mmph и за ней следует любой символ или символы. Иными словами, электронное письмо будет помечено, если тема начинается с «mmph». Значения «mmph mmph» и «mmph mmph Hello» совпадут; «Hello mmph» и «Springfield sales» — нет.
Звездочку также можно использовать в середине значения и несколько раз, например:
require ["fileinto", "imap4flags"];
if header :matches "subject" "mmph *mmph *mmph" {
addflag "\\Flagged";
}Этот тест вернет совпадение, если тема начинается с «mmph » (с пробелом), содержит еще одно «mmph » (с пробелом) и заканчивается на «mmph» (без пробела). Совпадающие темы: «mmph mmph mmph», «mmph mmph mmphmmph» или «mmph is mmph and mmph».
Компаратор :matches может быть очень полезен при сравнении адресов. Как вы, возможно, знаете, у Proton Mail есть несколько доменов: protonmail.com и proton.me. Если вы хотите проверить, что сообщение получено от пользователя Proton Mail, вы можете использовать следующий скрипт:
require ["fileinto", "imap4flags"];
# Put support mail in a separate organized folder
if address :domain :matches "from" "protonmail.*"
{
fileinto "Internal";
}Если по какой-то причине вам нужно найти точное совпадение с символом * или ?, вы можете экранировать их, добавив \\ перед ними: \\* будет соответствовать звездочке, а \\? — вопросительному знаку.
Обратите внимание, что мы также поддерживаем расширение regex, которое определяет компаратор :regex. Этот компаратор является более точной версией :matches, но он очень сложен. Для получения дополнительной информации ознакомьтесь с официальной документацией(новое окно).
В некоторых случаях (как вы увидите далее в этой статье) вам может потребоваться сравнить числовые значения. Для этого предназначен пакет relational. Этот пакет определяет компаратор :value, за которым следует тип сравнения.
Он позволяет проверить, является ли значение больше (тип сравнения «gt»), больше или равно («ge»), равно («eq»), меньше или равно («le») либо меньше («lt») заданного значения.
При сравнении числовых значений также очень полезен пакет comparator-i;ascii-numeric. Он сообщает интерпретатору скрипта, что содержимое строки является числом, а не обычной строкой. Его можно использовать, добавив к тесту :comparator “i;ascii-numeric”.
Используя всю эту информацию, мы можем составить следующий скрипт:
require ["fileinto", "relational", "comparator-i;ascii-numeric"];
if header :value "ge" :comparator "i;ascii-numeric" "subject" "2"
{
fileinto "Dummy example";
}Этот тест переместит сообщение в папку Dummy example, если тема больше или равна 2. Если тема является не числом, а текстом, то тест не будет пройден. Сам по себе этот пример выглядит нелепо, но он предназначен для использования в сочетании с другими расширениями, такими как date, о котором мы расскажем позже в этой статье.
Сравнение с использованием контекста в Sieve
Вы также можете получить доступ к информации, связанной с вашей учетной записью и контекстом Proton Mail в целом, используя расширения. Например, вы можете проверить, находится ли адрес отправителя в вашем списке контактов.
Доступ к списку контактов
Вы можете получить доступ к своему списку контактов с помощью расширения extlists. В сочетании с проверкой заголовков это позволяет узнать, есть ли отправитель в вашем списке контактов.
require ["fileinto", "extlists"];
# Checks that the sender is in your personal address book
if header :list "from" ":addrbook:personal?label=Family"
{
fileinto "Known";
}Этот тест пометит сообщение ярлыком Known, если отправитель содержится в списке :addrbook:personal?label=Family. Список можно разделить на две части. Во-первых, :addrbook:personal означает, что адрес находится в вашей личной адресной книге. Во-вторых, label=Family дополнительно сужает список, указывая на то, что помимо нахождения в адресной книге контакт должен принадлежать к группе контактов Family. При необходимости вы можете изменить этот ярлык на другую группу контактов. Например, вы можете использовать :addrbook:personal?label=Work, и тогда тест будет успешно пройден только в том случае, если отправитель есть в вашей адресной книге и входит в группу контактов Work.
В более общем смысле список соответствует спецификации Tag URI Scheme(новое окно), и вы можете добавлять дополнительные параметры для сужения фильтров. Затем этот список можно использовать следующим образом:
require ["fileinto", "extlists"];
# replace :your:list:here by the list you want to use
if header :list "from" ":your:list:here"
{
# some actions...
}Мы предлагаем четыре различных списка:
- :addrbook:personal¹ проверяет, есть ли адрес в вашем списке контактов. Список принимает параметр label, соответствующий определенной группе контактов. Этот параметр имеет четыре разновидности:
- :addrbook:personal?label=something вернет совпадение для контакта, который находится в группе контактов «something»;
- :addrbook:personal?label.starts-with=something вернет совпадение для контакта, принадлежащего как минимум к одной группе, название которой начинается с «something»;
- :addrbook:personal?label.ends-with=something вернет совпадение для контакта, принадлежащего как минимум к одной группе, название которой заканчивается на «something»;
- :addrbook:personal?label.contains=something вернет совпадение для контакта, принадлежащего как минимум к одной группе, содержащей в названии «something».
Вы также можете получить доступ к криптографической информации о подходящем электронном письме:
- :addrbook:personal?keypinning=true вернет совпадение для контакта, у которого есть доверенный ключ. Изменение значения true на false позволит находить контакты без доверенного ключа;
- :addrbook:personal?encryption=true вернет совпадение для контакта, для которого включено шифрование. Изменение значения true на false позволит находить контакты, для которых шифрование не настроено или отключено;
- :addrbook:personal?signing=true соответствует контакту, для которого включено подписание. Изменение true на false выберет контакт, для которого подписание отключено.
- :addrbook:myself¹ соответствует любому адресу, который принадлежит вам;
- :addrbook:organization соответствует любому адресу, принадлежащему участнику организации, в которой вы состоите;
- :incomingdefaults:inbox проверяет, находится ли адрес в вашем белом списке;
- :incomingdefaults:spam проверяет, находится ли адрес в вашем чёрном списке.
В сочетании с расширением переменных (описанным в следующем абзаце) переменные соответствия изменятся. Переменная соответствия ${0} всегда будет содержать последний адрес электронной почты в указанном списке. Если список был помечен сноской 1, переменная соответствия ${1} будет содержать отображаемое имя.
Например, используя списки ниже, вы можете создать фильтр, который будет удалять любые электронные письма, полученные от кого-либо, кроме вашей семьи или людей из вашего белого списка:
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
}Если это условие выполнено, будет выполнено действие discard. Это действие удаляет электронное письмо немедленно и окончательно . Вы также можете просто переместить его в папку «Корзина» с помощью действия fileinto вместо discard: fileinto “trash”;.
Создание переменных
Ещё одним полезным инструментом при управлении контекстом является определение переменной. Переменная — это место временного хранения, в которое вы можете поместить текст и связать его с именем. Позже вы сможете повторно использовать это содержимое, вызывая его по имени. Например, у вас может быть следующий скрипт:
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}";Цель этого скрипта — отклонить электронное письмо с пользовательским сообщением. Если исходное письмо пришло от kenny, а его тема — «mmph mmph», создаётся переменная «message», содержащая mmph mmph. В противном случае сообщение будет заполнено текстом «Sorry, I don’t want emails today!». Затем на последнем шаге мы повторно используем эту переменную в команде reject.
Sieve изначально не определяет переменные, поэтому они определены в расширении variables, которое необходимо подключить в начале вашего скрипта. Существует два способа определить переменную.
- Явное создание переменной:
Для создания переменной предусмотрено действие set.
require "variables"; # Create a variable called "labelname" and containing the string "Work". set "labelname" "Work";
Первая строка — это имя вашей переменной, а вторая — её значение. Таким образом, предыдущий пример создаёт переменную с именем labelname, содержащую Work.
После того как переменная определена, вы можете вызвать её, добавив в строку следующий формат: ${name}, где name — имя вашей переменной. При выполнении оно будет заменено значением переменной. (Если переменная не была определена, она будет заменена пустой строкой.) Таким образом, в следующем скрипте:
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}";Ваше электронное письмо будет помечено ярлыком /Work. Поскольку мы уже определили переменную labelname, она заменяется на Work. Однако переменная foldername не определена, поэтому она просто удаляется.
- Неявное присваивание переменной:
Наиболее интересный сценарий использования переменных — использование теста :matches. Рассмотрим следующий пример, где отправителем электронного письма является 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}";
}При использовании с расширением переменных результат операции match будет сохранён в переменных. Будет задано несколько переменных с числовыми именами. Во-первых, переменная 0 будет содержать полное совпадение (в нашем примере это будет полный адрес: test@proton.me). Затем первая группа совпадений будет присвоена переменной 1 (в нашем примере это будет test), вторая группа совпадений будет присвоена второй переменной (proton.me) и так далее до последней группы совпадений.
В нашем примере выполняется команда fileinto. Местоположение определено как ${1}, что распознаётся как переменная и, следовательно, заменяется её значением, вычисленным выше: test.
Обратите внимание, что переменные также можно присваивать в тесте :regex, используя группы совпадений регулярных выражений.
Преобразование переменных
Одной из отличных возможностей является преобразование переменных. Для этого ключевое слово set можно использовать в сочетании с флагами, которые позволяют изменить значение перед его присвоением переменной.
- :lower преобразует значение переменной в нижний регистр;
- :upper преобразует значение переменной в верхний регистр;
- :lowerfirst преобразует первую букву значения переменной в нижний регистр;
- :upperfirst преобразует первую букву значения переменной в верхний регистр;
- :quotewildcard экранирует любые подстановочные знаки в строке, чтобы их можно было использовать буквально в операторе сравнения;
- :length возвращает длину значения.
Обратите внимание, что вы также можете повторно использовать определённую переменную в другом действии set. Давайте улучшим наши предыдущие примеры:
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}";Шаг за шагом фильтр создаст три переменные. Первая команда set создаст переменную labelname. Содержимым переменной является Work. Действительно, исходное значение WORK преобразуется с помощью флагов :lower и :upperfirst, изменяя регистр на work, а затем на Work.
Вторая команда set создаст вторую переменную с именем foldername, содержащую строку Geneva. Для этого использовались флаги :lower и :upperfirst.
Наконец, создаётся переменная location. Значение «${foldername}/${labelname}» содержит две переменные: foldername и labelname. Таким образом, интерпретатор Sieve заменит эти переменные их значениями: Work и Geneva.
Наконец, переменная location используется в качестве аргумента для команды fileinto. Таким образом, электронное письмо будет перемещено в папку, имя которой является значением переменной location: Work/Geneva.
Компараторы также можно применять к переменным соответствия:
require "variables";
require "fileinto";
if address :all :matches "from" "*@*" {
set :lower :upperfirst "fileintovar" "${1}";
fileinto "${fileintovar}";
}В данном случае, если отправителем электронного письма является test@proton.me, оно будет помечено ярлыком Test.
Ещё один способ изменить значение переменной — использовать расширение vnd.proton.eval. Это расширение определяет новый флаг :eval, который позволит вам выполнять простые вычисления:
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}";
}В этом примере, по-прежнему предполагая, что электронное письмо поступает от test@proton.me, оно будет помечено значением 478. Действительно, длина первой переменной соответствия равна 19, а результат вычисления 19 * 25 – 1 / 8 + 3 округляется в большую сторону до 478.
На первый взгляд это может показаться бесполезным, но это расширение приобретает больше смысла в сочетании с другими операциями.
Сравнение с другими полями в Sieve
Также возможно сопоставление по определённым заголовкам. Например, чтобы упорядочить все сообщения, отправленные в списки рассылки (часто это маркетинговые сообщения или новостные рассылки), вы можете сделать следующее:
require "fileinto";
# Filter all lists into the same folder
if exists "list-unsubscribe"
{
fileinto "advertisements";
}Чтобы сортировать электронные письма из социальных сетей в отдельную папку, вы можете написать следующее:
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";
}Обратите внимание, что мы используем:
anyof(exists "x-facebook", exists "x-linkedin-id")
вместо:
exists ["x-facebook", "x-linkedin-id"]
Так как последний вариант проверяет, установлены ли оба заголовка — x-facebook и x-linkedin-id.
Чтобы посмотреть, какое именно значение содержит заголовок, вы можете использовать тест 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";
}Помимо операции :is, которая выполняет точное сопоставление, команда header также поддерживает :matches, которая сопоставляет с использованием подстановочных знаков (например, «*@*.com» будет соответствовать любому адресу электронной почты, заканчивающемуся на .com), и команду :contains, которая проверяет, содержит ли заголовок заданную строку.
Для настройки фильтров Sieve может быть полезно получить заголовки электронного письма. Для этого в веб-интерфейсе Proton Mail перейдите в раздел Ещё (∨) → Посмотреть заголовки. Откроется новое окно, содержащее все заголовки электронного письма.
Фильтрация по размеру сообщения в Sieve
Большие электронные письма можно обрабатывать иначе, чем маленькие. Например, вы можете помечать большие письма, чтобы затем удалить их и освободить место в почтовом ящике. Это можно сделать следующим образом:
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";
}Как видите, для указания больших размеров можно использовать единицы измерения, добавляя букву, соответствующую нужной единице, сразу после числа. Доступны три единицы измерения: K для кибиоктета (или 1024 байт), M для мебиоктета (или 1 048 576 байт) и G для гибиоктета (или 1 073 741 824 байт).
Обратите внимание, что «over» в данном случае означает «больше», а «under» — «меньше». Это означает, что если размер сообщения составляет ровно 1000 байт, то ни
size :under 1000
ни
size :over 1000
не совпадут.
Обратите внимание, что фильтры Sieve не имеют доступа к фактическому содержимому и видят только зашифрованный размер.
Выполнение сложных действий с сообщениями
В Sieve вы можете настраивать различные реакции на сообщения. В предыдущих разделах мы уже рассмотрели действия fileinto, addflag, discard и reject. Здесь мы расскажем о более сложных действиях.
Сообщения автоответчика и проверки дат
Вы можете воссоздать функцию автоответчика в Sieve с помощью команды vacation. Фактически работа функции автоответчика в ваших настройках основана именно на Sieve. Однако, используя параметры vacation в скрипте, вы получаете гораздо больше возможностей для настройки автоответов. Например, вы можете адаптировать определенные сообщения в зависимости от условий. Примечание. Как и функция автоответчика в настройках, действие vacation доступно только на платных тарифах.
Команда vacation отправляет автоответ каждому, кто пытается с вами связаться. Ее часто сочетают с проверками currentdate или date для отправки ответов в определенный промежуток времени.
Предположим, я ухожу в отпуск с 14 июля 2017 года по 14 августа 2017 года по времени Колорадо. Я могу использовать следующий код Sieve для настройки автоответчика:
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.";
}Одними из необязательных аргументов для команды vacation являются :handle и :days. По умолчанию Sieve не отвечает одному и тому же отправителю несколько раз в течение определенного количества дней (тайм-аута). Это предотвращает случайную отправку множества автоматических писем.
Для управления тайм-аутом можно использовать параметр :days. Аргумент :days указывает период времени (всегда в днях), в течение которого адреса сохраняются и повторные ответы на них не отправляются. Иногда в скрипте Sieve используется несколько команд vacation, и вам нужно сделать так, чтобы по каждой из них отправлялся ответ хотя бы один раз (если правило совпадает). В этом случае можно использовать параметр :handle. Аргумент для :handle — это строка, идентифицирующая тип отправляемого ответа.
Чтобы понять, как это работает, представим, что вы учитель. Учителя часто получают домашние задания по электронной почте. Полезно сортировать их по отдельным папкам. Кроме того, вы можете отклонять любые работы, сданные после дедлайна.
В таком случае вы можете использовать параметр handle, чтобы ответы гарантированно отправлялись тогда, когда это необходимо:
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.";
}
}Ниже перечислены все аргументы, допустимые для ответа vacation, в том порядке, в котором их следует передавать:
- :days — количество дней, в течение которых автоответчик должен воздерживаться от отправки ответа тому же отправителю после отправки сообщения об отсутствии
- :subject — префикс (по умолчанию auto), который автоответчик должен использовать при ответе отправителю. Например, для темы «Homework Assignment 2» будет отправлен ответ с темой «late: Homework Assignment 2», если передан аргумент :subject “late”.
- :mime указывает на то, что в первой строке ответа используется определенный формат. Это позволяет отправлять ответы в формате HTML. Например, чтобы составить HTML-ответ, передайте аргумент :mime и в первой строке ответа укажите Content-Type : text/html.
- :handle — это строка, которая идентифицирует тип отправляемого ответа.
Обратите внимание, что параметр :zone в currentdate является необязательным и, если он не задан, будет использоваться местное время сервера (в случае Proton Mail — Женева, Швейцария).
Параметр zone принимает смещения часовых поясов (строки вида «+0100», что означает UTC+1) и актуальные часовые пояса из базы данных ICANN (см. https://en.wikipedia.org/wiki/List_of_tz_database_time_zones(новое окно)). Последний вариант часто оказывается более полезным (хоть и не является стандартным для Sieve), так как он также учитывает переход на летнее время для каждого часового пояса.
Вы можете сравнивать даты с помощью обычных параметров :is/ :contains/ :matches. Так, например, следующая команда Sieve будет соответствовать любой дате в июле 2017 года:
currentdate :zone "US/Mountain" :matches "date" "2017-07-??"
Но в большинстве случаев гораздо полезнее использовать параметр :value.
Последний параметр, который необходимо передать, — это формат. Формат также определяет, какую часть даты вы хотите сравнить. В приведенном примере мы использовали формат даты. Все поддерживаемые форматы:
- year — год, представленный в формате от «0000» до «9999»
- month — месяц, представленный как «01»–«12»
- day — день, представленный как «01»–«31»
- date — дата, представленная как yyyy-mm-dd
- hour — час, представленный как «00»–«23»
- minute — минута, представленная как «00»–«59»
- second — секунда, представленная как «00»–«60» (60 — это високосная секунда(новое окно), которая случается только в 23:59:60, когда ученые сочтут это необходимым)
- time — время в формате hh:mm:ss
- iso8601 — дата и время в соответствии со стандартом ISO8601, например: 2005-08-15T15:52:01+00:00
- std11 — дата и время в соответствии со стандартом RFC2822, например: Mon, 15 Aug 2005 15:52:01 +0000
- zone — смещение часового пояса в формате +/-zzzz, например +0000 или -1200
- julian — количество дней, прошедших с 17 ноября 1858 года (UTC)
- weekday — день недели, начиная с воскресенья как 0 и заканчивая субботой как 6
Наконец, дату можно также извлечь из заголовка вместо использования currentdate. Эта команда даты работает так же, как и currentdate, за исключением того, что перед строкой формата требуется указать дополнительную строку — имя заголовка. Например:
date :zone "US/Mountain" :matches "received" "date" "2017-07-??"
Обратите внимание, что заголовки не обязательно точны: отправитель может изменять их по своему усмотрению, поэтому они ненадежны.
Что следует учитывать:
- Автоответчик не отвечает на автоматически сгенерированные сообщения, такие как списки рассылки, письма, отправленные другими автоответчиками, или сообщения, отправленные с адресов noreply.
- Автоответчик не будет отправлять сообщения несколько раз на один и тот же адрес электронной почты, за исключением случаев, когда команда vacation содержит другой параметр :handle.
Управление сроком действия
Уникальной функцией Proton Mail является возможность устанавливать срок действия для отправленных сообщений, по истечении которого сообщение удаляется из почтового ящика получателя.
Вы также можете использовать эту функцию для управления входящими сообщениями, задавая срок их действия:
require "vnd.proton.expire"; # permanently delete all incoming and outgoing emails after 10 days expire "day" "10";
Приведенный выше скрипт удалит любое полученное письмо через 10 дней. Это довольно радикально, поскольку правило применяется ко всем письмам. Вместо этого лучше использовать условие, чтобы скрипт применялся только к определенной группе писем. Например, вы можете настроить истечение срока действия сообщений от отправителей, которых нет в ваших контактах:
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";
}Примечание. Если указанный срок действия превышает 730 дней, он будет автоматически ограничен 730 днями.
Ограничения Sieve
Обратите внимание на несколько ограничений Sieve.
- Отправленные сообщения нельзя переместить вручную или с помощью фильтра во «Входящие» или «Черновики». Они всегда остаются в папке «Отправленные» и в папках/ярлыках, примененных пользователем или фильтром.
- Полученные сообщения нельзя переместить вручную или с помощью фильтра в «Черновики» или «Отправленные».
- Черновики нельзя переместить вручную или с помощью фильтра во «Входящие» или «Отправленные».
- Для сообщений в спаме — или сообщений, попавших в спам в процессе обработки, — мы не отправляем автоответы и сообщения о режиме отсутствия. Если вам нужна такая функция, вы можете создать собственную папку (например, mySpam) и отключить для нее уведомления.
- Ограничения для автоответчика и сообщений о режиме отсутствия
Примечание о поддержке регулярных выражений
Реализация Sieve от Proton соответствует стандарту фильтрации электронной почты Sieve, который предусматривает лишь минимальную поддержку регулярных выражений. Некоторые распространенные сокращения синтаксиса регулярных выражений, такие как \b (граница слова), \w (буквенно-цифровой символ), \W (небуквенно-цифровой символ) и \d (цифра), не поддерживаются в Sieve. В результате использование этих сокращений в фильтрах может приводить к сбоям без вывода ошибок. Это ограничение связано с самим стандартом Sieve, где приоритет отдается простоте и совместимости между платформами. Подробности см. в проекте RFC по регулярным выражениям Sieve.
Список поддерживаемых действий и проверок
Пакеты
Sieve поддерживает следующие расширения. Вы можете обратиться к официальной документации для получения дополнительной информации.
Date
- Использование: date
- Описание: (новое окно)предоставляет возможность проверки информации о дате.
- Документация: https://tools.ietf.org/html/rfc5260(новое окно)
- Реализация: компаратором по умолчанию является i;ascii-numeric, а не i;ascii-casemap. Действительно, функция date бесполезна с компаратором casemap.
- См.: Сообщения автоответчика и проверки дат
Envelope
- Использование: envelope
- Описание: (новое окно)определяет проверки, связанные с конвертом SMTP сообщения.
- Документация: https://tools.ietf.org/html/rfc5228#section-5.4(новое окно)
- См. также: Сравнение с адресами в Sieve
FileInto
- Использование: fileinto
- Описание: применяет ярлык к сообщению или перемещает его в папку.
- Документация: https://tools.ietf.org/html/rfc5228#section-4.1(новое окно)
- Реализация: косые черты указывают на полный путь к папке и должны быть экранированы, если имя ярлыка содержит косую черту. Поддерживаются следующие параметры:
- «Work»: это ярлык или папка с названием «Work»
- «Work/Project1»: это вложенная папка «Project1», которая находится в папке «Work»
- «Work/Project1/Docs»: это вложенная папка «Docs», которая находится во вложенной папке «Project1», которая, в свою очередь, находится в папке «Work»
- «Work/Misc\\/Others»: это вложенная папка «Misc/Others», которая находится в папке «Work»
- См.: С чего начать
Imap4flags
- Использование: imap4flags
- Описание: применяет флаг к сообщению.
- Документация: https://tools.ietf.org/html/rfc5232(новое окно)
- Реализация: параметры в виде списков переменных не поддерживаются. Вместо этого используйте расширение variables.
- См.: С чего начать
Reject
- Использование: reject
- Описание: отклоняет входящее сообщение с отправкой указанного сообщения.
- Документация: https://tools.ietf.org/html/rfc5429(новое окно)
- См.: С чего начать
Vacation
- Использование: vacation
- Описание: отправляет сообщение автоответчика.
- Документация: https://tools.ietf.org/html/rfc5230(новое окно)
- См.: Сообщения автоответчика и проверки дат
Variables
- Использование: variables
- Описание: создает и использует переменные.
- Документация: https://tools.ietf.org/html/rfc5229(новое окно)
- См.: Создание переменных
Реляционный
- Использование: relational
- Описание: предоставляет реляционные операторы сравнения.
- Документация: https://tools.ietf.org/html/rfc5231
Регулярные выражения
- Использование: regex
- Описание: предоставляет операторы сравнения на основе регулярных выражений.
- Документация: https://tools.ietf.org/id/draft-ietf-sieve-regex-01.html
Числовой компаратор ASCII
- Использование: comparator-i;ascii-numeric
- Описание: предоставляет возможность сравнения чисел.
- Документация: https://tools.ietf.org/html/rfc5231(новое окно)
Внешне хранящиеся списки
- Использование: extlists
- Описание: предоставляет доступ к спискам контактов.
- Документация: https://tools.ietf.org/html/rfc6134(новое окно)
- Реализация: поддерживаются следующие списки
- addrbook:personal : личный список контактов. Поддерживаются следующие запросы:
- label[.starts-with / .ends-with / .contains]=<group: string>: операция в отношении группы контактов;
- keypinning=<value: true / false> определение открытого ключа контакта;
- encryption=<value: true / false> шифрование контакта по умолчанию;
- signing=<value: true / false> подпись контакта по умолчанию.
- :addrbook:myself адреса, принадлежащие текущему пользователю;
- :addrbook:organization адреса, принадлежащие участникам текущей организации;
- :incomingdefaults:inbox белый список
- :incomingdefaults:spam черный список
- addrbook:personal : личный список контактов. Поддерживаются следующие запросы:
- См.: Доступ к списку контактов
Вычисление
- Использование: vnd.proton.eval
- Описание: вычисляет простое арифметическое выражение, заданное в виде строки.
- Документация: Преобразование переменных
Включение
- Использование: include
- Описание: управляет рабочим процессом Sieve.
- Документация: https://tools.ietf.org/html/rfc6609(новое окно)
- Реализация: поддерживается только узел return.
Срок действия
- Использование: vnd.proton.expire
- Описание: управляет сроком действия сообщений.
- Документация: Управление сроком действия
Тесты
Текущая дата
- Использование:
currentdate [":zone" <time-zone: string>] [COMPARATOR] [MATCH-TYPE] <date-part: string> <key-list: string-list>
- Описание: выполняет проверку с использованием текущей даты на почтовом сервере Proton Mail
- Пакет: date
- См.: Список поддерживаемых действий и проверок
Date
- Использование:
date [":zone" <time-zone: string> / ":originalzone"] [MATCH-TYPE] <header-name: string> <date-part: string> <key-list: string-list
- Описание: выполняет проверку с использованием даты, указанной в заголовке.
- Пакет: date
- См.: Список поддерживаемых действий и проверок
Наличие флага
- Использование:
hasflag [MATCH-TYPE] [COMPARATOR] <list-of-flags: string-list>
- Описание: Проверяет, имеет ли определенное сообщение определенный флаг.
- Пакет: imap4flags
- См.: Начало работы
Envelope
- Использование:
envelope [COMPARATOR] [ADDRESS-PART] [MATCH-TYPE] <envelope-part: string-list> <key-list: string-list>
- Описание: Проверяет, соответствует ли указанная часть конверта SMTP указанному ключу.
- Пакет: envelope
- См.: Сравнение с адресами в Sieve — продвинутый уровень
Address·
- Использование:
address [COMPARATOR] [ADDRESS-PART] [MATCH-TYPE] <header-list: string-list> <key-list: string-list>
- Описание: Проверяет, соответствуют ли указанные заголовки, разобранные как адрес, указанным ключам.
- Пакет: <default>
- См.: Сравнение с адресами в Sieve
Header
- Использование:
header [COMPARATOR] [MATCH-TYPE] <header-names: string-list> <key-list: string-list>
- Описание: Проверяет, соответствуют ли указанные заголовки указанным ключам.
- Пакет: <default>
- См.: Сравнение с другими полями в Sieve
HasExpiration
- Использование:
hasexpiration
- Описание: Проверяет, установлен ли для сообщения срок действия.
- Пакет: vnd.proton.expire
Exists
- Использование:
exists <header-names: string-list>
- Описание: Проверяет, существуют ли (все) указанные заголовки.
- Пакет: <default>
- См.: Сравнение с другими полями в Sieve
Срок действия
- Использование:
expiration :comparator "i;ascii-numeric" [MATCH-TYPE] <unit: "day" / "minute" / "second"> <key-list: string-list>
- Описание: Сравнивает время истечения срока действия сообщения с указанными ключами. Проверка завершится ошибкой, если она выполняется для сообщения без срока действия.
- Пакет: vnd.proton.expire
Size
- Использование:
size <":over" / ":under"> <limit: number>
- Описание: Проверяет, больше или меньше определенного лимита общий размер сообщения (включая вложения).
- Пакет: <default>
- См.: Фильтрация по размеру сообщения в Sieve
String
- Использование:
string [MATCH-TYPE] [COMPARATOR] <source: string-list> <key-list: string-list>
- Описание: Проверяет, соответствует ли какая-либо из исходных строк какому-либо ключу.
- Пакет: variables
Anyof
- Использование:
anyof <tests: test-list>
- Описание: Выполняет логическое ИЛИ для переданных проверок.
- Пакет: <default>
- См.: С чего начать
Allof
- Использование:
allof <tests: test-list>
- Описание: Выполняет логическое И для переданных проверок.
- Пакет: <default>
- См.: Начало работы
Not
- Использование:
not <test: test>
- Описание: Инвертирует результат указанной проверки.
- Пакет: <default>
- См.: Начало работы
True
- Использование:
true
- Описание: Всегда соответствует.
- Пакет: <default>
False
- Использование:
false
- Описание: Никогда не соответствует.
- Пакет: <default>
Действия
Require
- Использование:
require <packages: string-list>
- Описание: Загружает указанное расширение, позволяя использовать его методы или модификации.
- Пакет: <default>
- См.: С чего начать
FileInto
- Использование:
fileinto <folder: string>
- Описание: Перемещает обрабатываемое сообщение в определенную папку.
- Пакет: fileinto
- См.: Начало работы
Addflag
- Использование:
addflag <list-of-flags: string-list>
- Описание: Добавляет указанный флаг к обрабатываемому сообщению.
- Пакет: imap4flags
- См.: Начало работы
Removeflag
- Использование:
removeflag <list-of-flags: string-list>
- Описание: Удаляет указанные флаги из обрабатываемого сообщения.
- Пакет: imap4flags
Setflag
- Использование:
setflag <list-of-flags: string-list>
- Описание: удаляет все флаги и устанавливает указанные флаги для обрабатываемого сообщения.
- Пакет: imap4flags
Stop
- Использование:
stop
- Описание: прекращает обработку всех фильтров Sieve. Последующие фильтры Sieve не будут запущены.
- Пакет: <default>
Return
- Использование:
return
- Описание: прекращает обработку текущего фильтра Sieve. Последующие фильтры Sieve все равно будут запущены.
- Пакет: include
Set
- Использование:
set [MODIFIER] <name: string> <value: string>
- Описание: создает новые переменные, связывая указанное имя с указанным значением.
- Пакет: variables
- См.: Создание переменных
Discard
- Использование:
discard
- Описание: сбрасывает сообщение в конце этого фильтра Sieve. После сброса другие фильтры Sieve выполняться не будут.
- Пакет: <default>
Keep
- Использование:
keep
- Описание: отменяет последнюю команду discard. Это подействует только в том случае, если команда находится в том же фильтре Sieve. Если команда discard не выполнялась, ничего не произойдет.
- Пакет: <default>
Reject
- Использование:
reject <reason: string>
- Описание: мгновенно отправляет электронное письмо на SMTP-адрес отправителя с указанием причины и сбрасывает это сообщение. Команда keep не отменит это действие.
- Пакет: <по умолчанию>
- См.: Начало работы, Сообщения автоответа и проверки дат
Expire
- Использование:
expire <unit: "day" / "minute" / "second"> <value: string>
- Описание: устанавливает срок действия сообщения по прошествии указанного времени.
- Пакет: vnd.proton.expire
- См.: Управление сроком действия
Unexpire
- Использование:
unexpire
- Описание: удаляет срок действия сообщения.
- Пакет: vnd.proton.expire
Vacation
- Использование:
vacation [":days" number] [":subject" string] [":mime"] [":handle" string] <reason: string>
- Описание: отправляет автоответ на SMTP-адрес отправителя с указанным текстом в качестве тела письма.
- Пакет: vacation (требуется платный аккаунт)
- См.: Сообщения автоответа и проверки дат
Valid External List
- Использование:
valid_ext_list <ext-list-names: string-list>
- Описание: проверяет, поддерживаются ли все указанные внешние списки и являются ли они допустимыми.
- Пакет: extlists



