Protonホームページ

Sieveフィルター(詳細カスタムフィルター)

閲覧中
11 分
カテゴリー
メールを受信して読む

Proton Mailでは、タグを割り当てたり、フォルダーに分類したりすることで、メールを自動的にフィルタリングするさまざまな方法をユーザーに提供しています。通常、これには次の3つの方法があります:

  1. 差出人をブロックリストと許可リスト に追加し、迷惑メールフォルダーに常に振り分ける、あるいは絶対に振り分けないようにする。
  2. Proton Mailの対話型インターフェイスを使用して、カスタムフィルターを作成する。
  3. [最も高度]Sieveでカスタムフィルターを作成する。

これらの方法の中で、Sieveでカスタムフィルターを作成する方法が最も高い汎用性を提供しますが、使い方はより複雑になります。このため、Sieveはある程度の技術的経験を持つユーザー向けの高度な機能であると考えています。ほとんどのお客様にとっては、対話型インターフェイスが、必要とするカスタムフィルターを作成するのに適しています。

目次

Sieveとは?

Sieveは、メールをフィルタリングするために使用されるプログラミング言語です。お客様は、シンプルなルールを記述することで、Sieveでフィルターを作成できます。たとえば、「Kyleからのすべてのメッセージに緑色のラベルを付ける」などです。これらのルールを組み合わせることで、高度なフィルタリングシステムを作成できます。

お客様は、Sieveルールをゼロから作成することも、この記事にあるような例を参考にする事も、作業を容易にするソフトウェアを使用することもできます。

実際、Protonはすでにお客様の入力を基にSieveフィルターを生成する対話型インターフェイスを使用して、Sieveフィルターを作成する方法をお客様に提供しています。対話型インターフェイス自体がSieveのサブセットを使用しているため、対話型インターフェイスでフィルターを作成し、それをSieveで編集することも、Sieveを学ぶためのもう一つの良い方法です。

たとえば、対話型インターフェイスを使用して作成された次のフィルターを比較してみましょう…


…同じフィルターのコードをSieveエディターで表示した場合と比較してください:

この記事では、Sieveについて紹介し、お客様独自のSieveフィルターを作成する方法を説明します。Sieveの使用方法について詳しく知りたい場合は、オンラインにある多数のチュートリアルを参考にしてください。このページで解決しないProton MailのSieveに関する質問がある場合は、いつでもこちらからサポートチームにお問い合わせいただけます。

はじめに

Sieveフィルターの作成を開始するには、mail.proton.me(新しいウィンドウ)にログインし、設定 → すべての設定 → Proton Mail → フィルター → Sieveフィルターを追加の順に進みます。

Sieveスクリプトは、コマンドのリストで構成されています。ほとんどのスクリプトは、requireコマンドで始まります。requireコマンドは、特定の機能を提供する拡張機能を読み込みます。たとえば、ラベルを割り当てたり、メッセージをフォルダーに移動したりするには、fileintoコマンドが必要です。

このコマンドを読み込むには、次のように記述するだけです:

require "fileinto";

複数の拡張機能を読み込むには、リストを使用できます:

require ["fileinto", "imap4flags"];

この場合、imap4flagsはお客様がメールに既読フラグを立てることを可能にする拡張機能を読み込みます。requireコマンドの後、通常は受信メッセージに対していくつかのテストを実行します。これは、ifと、addressheaderなどの別のコマンドを組み合わせることで行われます。

最後に、テストが成功した場合、メッセージにアクションを適用できます。たとえば、特定の差出人からのすべてのメールを同じフォルダーに入れ、受信メールに既読フラグを立てる場合、以下のように記述できます:

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コマンドに文字列のリストを渡すことができます(文字列(新しいウィンドウ)とは一連 of 文字のことで、この場合はメールアドレスを指します):

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

ここでは、件名が正確にmmph mmphである場合、メールはフォルダーKennyに移動されます。それ以外の場合(つまり件名が正確に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";
}

1回の実行につき、ifelsifelseブロックのいずれか1つのみが実行されることに注意してください。

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コマンドを使用すると、fromtosenderヘッダーなどのアドレスヘッダーに対してテストを実行できます。次のいずれかのフラグを使用することで、メールアドレスの異なる部分を抽出できます:

  • :localpart — アットマーク(@)の前の部分
  • :domain — アットマーク(@)の後の部分
  • :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 isはx-original-toヘッダーと同等です。

envelopeコマンドを使用すると、エンベロープから実際のto:およびfrom:アドレスを取得できます。この2つ以外のフィールドは存在しないため、このコマンドに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";
}

比較器を使用した2つの値の評価

テストで2つの値を評価する場合、comparators(比較器)と呼ばれる異なるフラグを使用して、この比較がどのように行われるかを指定できます。これまでに、指定された文字列が特定の値と完全に一致することを確認する:isと、特定の値に指定された文字列が含まれていることを確認する:containsの2つの比較器をすでに使用しました(次のテストを参照)。

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の場合、お客様が定義した値に?および*を含めることができます。疑問符は任意の1文字に一致し、アスタリスク(ワイルドカードと呼ばれます)は0文字以上の任意の文字に一致します。

この形式を使用すると、次のテストを作成できます:

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

何らかの理由で文字*または?を正確に一致させる必要がある場合は、前に\\を追加することでそれらをエスケープ(quote)できます。\\* はスターに一致し、\\? は疑問符に一致します。

なお、比較器: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";
}

このテストは、件名が2以上の場合にメッセージをDummy exampleフォルダーに移動します。件名が数値ではなくテキストの場合、テストは失敗します。そのため、この例は一見不合理に見えますが、この記事の後半で説明する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"; 
}

このテストは、差出人がリスト:addrbook:personal?label=Familyに含まれている場合、メッセージにKnown というラベルでフラグを立てます。このリストは2つの部分に分けることができます。まず、:addrbook:personalは、アドレスがお客様の個人のアドレス帳にあることを意味します。次に、label=Familyはリストをさらに絞り込み、アドレス帳にあることに加えて、連絡先が連絡先グループFamilyにも属している必要があることを指定します。必要に応じて、このラベルを別の連絡先グループに変更できます。必要であれば:addrbook:personal?label=Workを使用することもでき、その場合、差出人がお客様のアドレス帳にあり、かつ連絡先グループWorkに含まれている場合にのみテストが成功します。

より一般的には、リストはTag URIスキーム(新しいウィンドウ)に準拠しており、追加のパラメーターを追加してフィルターを絞り込むことができます。このリストは以下のように使用できます:

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

4つの異なるリストが用意されています:

  • :addrbook:personal¹は、アドレスがお客様の連絡先リストにあるかどうかを確認します。このリストは、パラメーターlabelを受け入れ、これは特定の連絡先グループに一致します。このパラメーターは、4つのサブバージョンに派生させることができます:
    • :addrbook:personal?label=somethingは、連絡先グループ“something”に含まれる連絡先と一致します。
    • :addrbook:personal?label.starts-with=somethingは、“something”で始まる少なくとも1つのグループに属する連絡先と一致します。
    • :addrbook:personal?label.ends-with=somethingは、“something”で終わる少なくとも1つのグループに属する連絡先と一致します。
    • :addrbook:personal?label.contains=somethingは、“something”を含む少なくとも1つのグループに属する連絡先と一致します。

一致するメールに関する暗号化情報にアクセスすることもできます:

  • :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 アクションを使用して、単にごみ箱フォルダーに移動することもできます:fileinto “trash”;

変数の作成

コンテキストを管理する際に役立つもう1つのツールは、変数の定義です。変数は、テキストを配置して名前にタグを付けることができる一時的なストレージの場所です。後でお客様はその名前を呼び出すことで、このコンテンツを再利用できます。たとえば、次のようなスクリプトを作成できます。

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!」が入力されます。そして、最後のステップでお客様はこの変数を拒否コマンドで再利用します。

Sieveはネイティブで変数を定義しないため、変数は拡張機能 variables で定義され、お客様のスクリプトの最初に要求する必要があります。変数を定義するには2つの方法があります。

  • 変数の明示的な作成:

変数を作成するために、set アクションが用意されています。

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

最初の文字列はお客様の変数の名前であり、2番目の文字列は変数の値です。したがって、前の例では、Work を含む labelname という変数が作成されます。

変数が定義されると、文字列に ${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}";
}

variables拡張機能とともに使用すると、一致(match)操作の結果が変数に保管されます。数値の名前を持ついくつかの変数が設定されます。まず、変数 0 には完全一致(この例では完全なアドレス:test@proton.me)が含まれます。次に、最初の一致グループが変数 1(この例では test)に割り当てられ、2番目の一致グループが2番目の変数(proton.me)に割り当てられ、最後の一致グループまで同様に続きます。

この例では、fileintoコマンドが実行されます。場所は ${1} に定義され、これは変数として認識されるため、上記で計算された値 test に置き換えられます。

正規表現の一致グループを使用して、:regex テストで変数を割り当てることも可能であることに注意してください。

変数の変換

優れた可能性の1つは、変数の変換です。そのためには、変数を割り当てる前に値を変更するために使用できるフラグを組み合わせて、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}";

ステップバイステップで、フィルターは3つの変数を作成します。最初のコマンド set は変数 labelname を作成します。変数の内容は Work です。実際、元の値「WORK」は、:lower:upperfirst の両方のフラグを使用して変換され、小文字の work に変更され、その後に Work に変更されます。

2番目のsetコマンドは、Genevaという文字列を含む、foldername という2番目の変数を作成します。実際、:lower:upperfirst フラグが使用されました。

最後に、変数の場所(location)が作成されます。値「”${foldername}/${labelname}“」には、foldernamelabelname の2つの変数が含まれています。そのため、Sieveインタープリターはこれらの変数値をそれぞれの値(GenevaとWork)に置き換えます。

最後に、変数の場所(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 ラベルが付けられます。

変数の値を変更するもう1つの方法は、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-facebookx-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のウェブインターフェースでこれを行うには、その他)→ヘッダーを表示(View headers)に進みます。メールのすべてのヘッダーが含まれる新しいウィンドウが開きます。

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

ご覧のように、大きなサイズを指定したい場合は、数値の直後に対応する単位の文字を追加することで、単位を使用することができます。次の3つの単位を利用できます。Kキビオクテット(または1024バイト)用、Mメビオクテット(または1 048 576バイト)用、そしてGギビオクテット (または1 073 741 824バイト)用です。

この場合、「over」は「より大きい」を意味し、「under」は「より小さい」を意味することにご注意ください。つまり、メッセージのサイズがちょうど1000バイトである場合、どちらの

size :under 1000

size :over 1000

も一致しません。

Sieveフィルターは実際のコンテンツにアクセスできず、暗号化済みのサイズのみを表示することにご注意ください。

メッセージに対する高度な操作の実行

Sieveでは、メッセージに対してさまざまな反応を実行できます。前のセクションではすでに、fileintoaddflagdiscard、およびrejectの操作を紹介しました。ここでは、さらに高度な操作を紹介します。

休暇メッセージと日付テスト

Sieveでは、自動返信機能を、vacationコマンドを使用して再現できます。実際、設定にある自動返信機能は、Sieveを利用して動作しています。しかし、スクリプト内でvacationオプションを使用することで、自動返信をカスタマイズする可能性が大幅に広がります。例えば、条件に応じて特定のメッセージを調整することができます。注意:設定の自動返信機能と同様に、vacation 操作は有料プランでのみご利用いただけます。

vacationコマンドは、連絡を試みたすべての人に休暇の応答を送信します。特定の期間内に対答を送信するために、多くの場合、currentdateまたはdateテストと組み合わせて使用されます。

例えば、コロラド時間で2017年7月14日から2017年8月14日まで休暇に入るとします。以下の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コマンドのオプションの引数の1つに、:handleおよび:days引数があります。デフォルトでは、Sieveはタイムアウトと呼ばれる特定の機日数の間、同じ差出人に複数回返信しません。これにより、誤って多数の自動メールを送信してしまうことを防ぎます。

タイムアウトを制御するには、:daysパラメーターを使用できます。:days引数は、アドレスが保持され、応答が返されない期間を指定するために使用され、常に日数で指定します。Sieveスクリプト内に複数のvacationコマンドがあり、(ルールが一致した場合に)それぞれのコマンドが少なくとも1回は返信を送信するようにしたい場合があります。その場合は、: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.";
    }
}

休暇応答に許可されているすべての引数を、渡すべき順序で以下に示します:

  • :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パラメーターは、UTC+1を意味する「+0100」の形式の文字列であるタイムゾーンオフセット、およびICANNデータベース内の実際のタイムゾーンを受け入れます(https://en.wikipedia.org/wiki/List_of_tz_database_time_zones(新しいウィンドウ)を参照)。最後のオプションは、(非標準のSieveではありますが)各タイムゾーンの夏時間もエンコードするため、多くの場合より便利です。

通常の:is/ :contains/ :matchesパラメーターを使用して日付を比較できます。そのため、例えば、次のSieveコマンドは2017年7月の日付と一致します:

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:1858年11月17日UTCからの経過日数
  • weekday:日曜日を0、土曜日を6とする曜日

最後に、currentdateを使用する代わりに、ヘッダーから日付を取得することもできます。このdateコマンドは、フォーマット文字列の前に追加の文字列(ヘッダー名)が必要である点を除き、currentdateと同じように動作します。例えば:

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

ヘッダーは必ずしも正確であるとは限らないことにご注意ください。差出人はヘッダーを自由に変更できるため、信頼性は低くなります。

考慮事項:

  1. 自動応答は、メーリングリストなどの自動生成されたメッセージ、別の自動応答から送信されたメール、またはnoreplyアドレスから送信されたメッセージには応答しません。
  2. 自動応答は、vacationコマンドに異なる:handleが指定されている場合を除き、同じメールアドレスに複数回メッセージを送信することはありません。

有効期限の管理

Proton Mailのユニークな機能の1つは、送信されたメッセージに有効期限を設定できることです。有効期限が切れると、メッセージは受信者のメールボックスから削除されます。

この機能を使用して、有効期限を追加することで受信メッセージを管理することもできます:

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)を追加し、そのフォルダーの通知を無効にすることをご検討ください。
  • 自動応答/不在時応答メッセージの制限事項

正規表現サポートに関するメモ

ProtonによるSieveの実装はSieveメールフィルタリング規格に準拠していますが、この規格では最小限の正規表現サポートのみが含まれています。Sieveでは、\b(単語境界)、\w(単語構成文字)、\W(非単語構成文字)、\d(数字)など、一部の一般的な正規表現の略記法がサポートされていません。その結果、フィルター内でこれらの略記文字を使用すると、警告なしに失敗する原因となる場合があります。この制限は、プラットフォーム間におけるシンプルさと互換性を優先するSieve規格自体によるものです。詳細については、Sieve Regular ExpressionsのドラフトRFCを参照してください。

サポートされているアクションとテストのリスト

パッケージ

Sieveは以下の拡張機能をサポートしています。詳細については、公式ドキュメントを参照してください。

Date

Envelope

FileInto

  • 使用法: fileinto
  • 詳細: メッセージにラベルを適用するか、メッセージをフォルダーに移動します。
  • ドキュメント: https://tools.ietf.org/html/rfc5228#section-4.1(新しいウィンドウ)
  • 実装: スラッシュはフォルダーのフルパスを示し、ラベル名にスラッシュが含まれる場合はエスケープする必要があります。以下のオプションがサポートされています。
    • Work“: これは「Work」と呼ばれるラベルまたはフォルダーです
    • Work/Project1“: これはフォルダー「Work」内にあるサブフォルダー「Project1」です
    • Work/Project1/Docs“: これはフォルダー「Work」内のサブフォルダー「Project1」内にあるサブフォルダー「Docs」です
    • Work/Misc\\/Others“: これはフォルダー「Work」内にあるサブフォルダー「Misc/Others」です
  • 参照: はじめに

Imap4flags

Reject

Vacation

Variables

リレーショナル

  • 使用法: relational
  • 詳細: リレーショナルマッチ演算子を提供します。
  • ドキュメント: https://tools.ietf.org/html/rfc5231

正規表現

  • 使用法: regex
  • 詳細: 正規表現マッチ演算子を提供します。
  • ドキュメント: https://tools.ietf.org/id/draft-ietf-sieve-regex-01.html

ASCII数値比較

外部保管リスト

  • 使用法: 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 ブロックリスト
  • 参照: お客様の連絡先リストへのアクセス

Eval

  • 使用法: vnd.proton.eval
  • 詳細: 文字列で指定された単純な算術関数を評価します。
  • ドキュメント: 変数の変換

Include

有効期限

  • 使用法: vnd.proton.expire
  • 詳細: メッセージの有効期限を管理します。
  • ドキュメント: 有効期限の管理

テスト

現在の日付

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

Date

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

HasFlag

  • 使用法:
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>

アドレス·

  • 使用法:
address [COMPARATOR] [ADDRESS-PART] [MATCH-TYPE] <header-list: string-list> <key-list: string-list>
  • 詳細: アドレスとして解析された指定のヘッダーが、指定のキーと一致するかどうかをテストします。
  • パッケージ: <デフォルト>
  • 参照: Sieveでのメールアドレスとの比較

ヘッダー

  • 使用法:
header [COMPARATOR] [MATCH-TYPE] <header-names: string-list> <key-list: string-list>

HasExpiration

  • 使用法:
hasexpiration
  • 詳細: メッセージに有効期限が設定されているかどうかをテストします。
  • パッケージ: vnd.proton.expire

Exists

  • 使用法:
exists <header-names: string-list>

有効期限

  • 使用法:
expiration :comparator "i;ascii-numeric" [MATCH-TYPE] <unit: "day" / "minute" / "second"> <key-list: string-list>
  • 詳細: メッセージの有効期限を指定されたキーと比較します。有効期限が設定されていないメッセージに対して実行された場合、テストは失敗します。
  • パッケージ: vnd.proton.expire

Size

  • 使用法:
size <":over" / ":under"> <limit: number>

String

  • 使用法:
string [MATCH-TYPE] [COMPARATOR] <source: string-list> <key-list: string-list>
  • 詳細: ソース文字列のいずれかがいずれかのキーと一致するかどうかを評価します。
  • パッケージ: variables

Anyof

  • 使用法:
anyof <tests: test-list>
  • 詳細: 提供されたテストに対して論理和(OR)を実行します。
  • パッケージ: <デフォルト>
  • 参照: はじめに

Allof

  • 使用法:
allof <tests: test-list>
  • 詳細: 提供されたテストに対して論理積(AND)を実行します。
  • パッケージ: <デフォルト>
  • 参照: はじめに

Not

  • 使用法:
not <test: test>
  • 詳細: 指定されたテストの結果を反転させます。
  • パッケージ: <デフォルト>
  • 参照: はじめに

True

  • 使用法:
true
  • 詳細: 常に一致します。
  • パッケージ: <デフォルト>

False

  • 使用法:
false
  • 詳細: 決して一致しません。
  • パッケージ: <デフォルト>

操作

Require

  • 使用法:
require <packages: string-list>
  • 詳細: 指定された拡張機能を読み込んで、そのメソッドや変更が使用できるようにします。
  • パッケージ: <デフォルト>
  • 参照: はじめに

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フィルターは実行されません。
  • パッケージ: <デフォルト>

Return

  • 使用方法:
return
  • 詳細: 現在のSieveフィルターの処理を停止します。以降のSieveフィルターは引き続き実行されます。
  • パッケージ: include

Set

  • 使用法:
set [MODIFIER] <name: string> <value: string>
  • 詳細: 指定された名前と指定された値を関連付ける新しい変数を作成します。
  • パッケージ: variables
  • 参照: 変数の作成

Discard

  • 使用法:
discard
  • 詳細: このSieveフィルターの最後でメッセージを破棄します。破棄した後は、他のSieveフィルターは実行されません。
  • パッケージ: <デフォルト>

Keep

  • 使用法:
keep
  • 詳細: 最後のdiscard(破棄)コマンドを元に戻します。これは同じSieveフィルター内にある場合のみ有効です。破棄が実行されていない場合、このコマンドは何もしません。
  • パッケージ: <デフォルト>

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