メールに添付されているファイルのタイトル抽出方法について
メールに添付されているファイルのタイトル抽出方法について
お世話になっております。
現在、外部メールサーバーで受信したメールを解析し、タイトルや本文などを抽出しRedmineで処理するジョブフローを作成しています。そこでメールに添付されたファイルのタイトルについても抽出したいと考えているのですが、どのようにソースコードを書けばいいか教えていただけませんか。
ソースコードは以下の通りです。mail_parseライブラリを用いて辞書オブジェクトに変換後、Filenameキーで添付ファイル名の取り出しを試みています。 Kompiraドキュメント内、mail_parseの説明での下記記載を参照しました。
メールのヘッダ情報に加え、'Body'キーでメールの本文に、'Filename'キーでファイル名にアクセスすることができます(添付ファイルが存在しない場合は'Filename'キーはnullとなります)。また、29行目から47行目までは本コミュニティ内にあった、「添付ファイル付きメールを受信・送信する方法」という投稿でご担当者様がご回答されている内容を参考にしております。
- | raw_mail_text |
- print("メールを受信しました")->
- {try|
- #メール本文(Teams)の要素抽出
- [mail_text = mail_parse(raw_mail_text)]->
- print(mail_text)->
- {if type(mail_text['Body'])=="String"|
- then:
- [
- From= mail_text['From'],
- Subject= mail_text['Subject'],
- Date= mail_text['Date'],
- Body= mail_text['Body'],
- Filename= mail_text['Filename']
- ]
- else:
- [
- From= mail_text['From'],
- Subject= mail_text['Subject'],
- Date= mail_text['Date'],
- Body=mail_text['Body'][0].Body,
- html_content=mail_text['Body'][1].Body,
- Filename= mail_text['Filename']
- ]
- }->
- {if mail_text['Is-Multipart']|
- then:
- print("$from からマルチパートメールを受信しました")->
- {for part in mail_text['Body']|
- {if part['Filename']|# 添付ファイルパート
- then:
- print("---- 添付パート: ファイル名=%Filename ----"% part)->
- ["cat > $dest/%Filename"% part << part['Body']]
- else:
- print("---- 本文パート ----")->
- print(part['Body'])
- }
- }
- else:
- print("$from からシングルパートメールを受信しました")->
- print(mail_text['Body'])
- }->
-
正式なコメント
フィックスポイントの高橋です。
ご質問にある「メールに添付されたファイルのタイトル」とは具体的にどのような情報を指しておられますでしょうか?
mail_parse() を用いて各パートのヘッダ情報とコンテンツ(Body)を抽出することは出来ますが、それ以外の情報、たとえばコンテンツ中に記述された情報を抽出するような機能は持っておりません。
「メールに添付されたファイルのタイトル」がファイル名のことであれば提示されたジョブフローで取得できており、おそらく別の情報のことを指しておられるのかと推測しますが、上記のとおりヘッダに含まれていない情報ですと mail_parse() だけでは抽出できないかと思います。
mail_parse() で抽出した「本文に記述された特定の情報」を抜き出したい、ということになりますと、例えばテキストのパターンマッチを用いる方法などが考えられますが、解析する対象の本文のフォーマットに応じた実装を行なう必要がでてきます。例えば、以下のコラムではメールの件名に特定の文字列が含まれているか、を判定して処理の分岐を行なっています。
https://support.kompira.jp/column/forward_alert_mails/
参考になさってみてください。
コメントアクション -
ご回答いただきありがとうございます。
>ご質問にある「メールに添付されたファイルのタイトル」とは具体的にどのような情報を指しておられま>すでしょうか?
たとえば、以下のようなメールを受信した場合、メールに添付されている.txtファイル中の『TestTitle.txt』の部分が該当します。この部分を抜き出したいと考えております。

>mail_parse() を用いて各パートのヘッダ情報とコンテンツ(Body)を抽出することは出来ますが、それ以外>の情報、たとえばコンテンツ中に記述された情報を抽出するような機能は持っておりません。
>「メールに添付されたファイルのタイトル」がファイル名のことであれば提示されたジョブフローで取得>できており
メールヘッダ側を確認したところ、”Filename”と定義されたフィールド内に”TestTitle.txt”が確認されました。そのため、コンテンツ内の抽出ではなくFilenameの要素を個別に抽出できると考えています。一方で、以下のような図①のコンソールでのエラー内容からは、Filenameフィールドを参照できていないように見受けられます。
改めて受信トレイ内、処理対象メールを確認したところ、図②の通り.txtファイル以外にも.p7sファイルが添付されていることを確認しました。
例えば、一つのメールに複数添付ファイルが含まれる場合でも、Filenameで参照可能なのでしょうか。あるいはフィールドの指定方法は変化するのでしょうか。
【図①】コンソール出力結果

【図②】受信トレイ内 添付ファイルについて

また、必要であればメールヘッダー情報についてもご提供したいのですが、ユーザ情報も含まれるため、別途メール等で個別にお送りさせていただきたいと考えております。メールでのご連絡先がございましたら、ご教授いただけますでしょうか。
お忙しいところ恐縮ですが、よろしくお願いいたします。
-
たとえば、以下のようなメールを受信した場合、メールに添付されている.txtファイル中の『TestTitle.txt』の部分が該当します。この部分を抜き出したいと考えております。
ということであれば、これは添付パートのファイル名と考えられますので、添付パートの part["Filename"] で参照できると思います。
一方で、以下のような図①のコンソールでのエラー内容からは、Filenameフィールドを参照できていないように見受けられます。
これは 26 行目でマルチパートの場合に Filename=mail_text['Filename'] と参照している箇所に問題があり、この場合の mail_text はマルチパートメールの添付パートではなく、マルチパートメール全体のヘッダを参照しており、そこには Filename 情報は含まれていないためにエラーになっていると考えられます。ファイル名情報は添付パート部分に含まれます。
例えば、一つのメールに複数添付ファイルが含まれる場合でも、Filenameで参照可能なのでしょうか。あるいはフィールドの指定方法は変化するのでしょうか。
マルチパートメールでは、複数の添付ファイルパートを持つ場合や、本文パートも複数(たとえば text と html)ある場合もあります。環境によっては様々な構成のマルチパートメールを受信する可能性もあるかと思いますので、なるべく柔軟に抽出できるように各パートをループで辿りながら必要な情報を抽出するようにされるとよいかもしれません。以下に簡単なサンプルを示します。
| raw_mail_text = ./test_mail['text'] |
| dest = '/tmp'|
[mail = mail_parse(raw_mail_text)] ->
print("%From からメールを受信しました: %Subject" % mail) ->
{ if mail['Is-Multipart'] |
then:
# マルチパートメールを受信した
{ for part in mail['Body'] |
[content_type = part['Content-Type']] ->
{if part['Filename'] |
then:
print("---- 添付パート: Filename=%Filename ----" % part) ->
["cat > '$dest/%Filename'" % part << part['Body']]
elif content_type =~ g'text/html*':
print("---- 本文パート(HTML): Content-Type=$content_type ----" % part) ->
print(part['Body'])
elif content_type =~ g'text/plain*':
print("---- 本文パート(TEXT): Content-Type=$content_type ----" % part) ->
print(part['Body'])
else:
print("---- その他のパート: Content-Type=$content_type ----" % part) ->
print(part['Body'])
}
}
else:
# シングルパートメールを受信した
print("---- 本文: Content-Type=%{Content-Type} ----" % mail) ->
print(mail['Body'])
}参考になさってみてください。
サインインしてコメントを残してください。
コメント
3件のコメント