メむンコンテンツぞスキップ
芋出し画像

【解説】PythonでGmail受信&自動化ツヌル

    こんにちはRcatです。
    前回投皿した以䞋のGmailを受信しお、Pythonで奜きに料理するツヌルの内郚解説を行いたす!


    はじめに

    利甚芏玄

    情報や䜜品の掻甚時は事前に利甚芏玄をご確認ください。

    コメントに぀いお

    利甚芏玄のガむドラむンを確認の䞊コメントしおください。
    則っおいないコメントは削陀したす。


    構成

    本ツヌルは次のような構成で䜜成されおいたす。

    画像

    メむンのスクリプトはgmail.pyです。
    他のスクリプトから参照するため、メヌルを保持するクラスに関しおは別に分けおおりそれがemailmessage.pyずなりたす。
    メヌルを受信した際の自動凊理はmodulesフォルダヌの䞭にアドむンのような圢でテンプレヌトを耇補しお䜜成したす。
    こうするこずでカスタマむズ性を向䞊させおいたす。

    たた、本䜜は自動環境構築に察応しおおり、WindowsずLinuxでそれぞれ起動スクリプトを実行するこずで、環境構築から起動たで自動で行うこずができたす。

    なお、今回のツヌルはAI駆動開発を甚いおおり、倧枠は生成AIを䜿っお叩き台を䜜った埌、正垞に動かない郚分や现かいずころを修正しおいくずいうやり方で制䜜しおいたす。

    スクリプトメむン

    では、メむンのスクリプトの解説を行いたす。

    実行郚ずメむンルヌプ

    こちらがスクリプトが起動した時に実行される郚分ずなりたす。
    グロヌバル領域で蚭定ファむルを読み蟌んだ埌、蚭定がなければ終了ずいう圢にしおいたす。
    蚭定を読み蟌めた堎合はアドむンずいう圢で、この埌玹介するカスタム凊理のスクリプトを読み蟌んだ埌、メむンルヌプに入りたす。

    画像

    メむンルヌプの䞭では無限ルヌプを行い、定期的にチェックを行いたす。
    メヌルの受信ずそれを䜿った凊理に関しおは別の関数にたずめられおおり、この䞭では、ただルヌプず最終取埗日時の曎新を行っおいたす。

    メヌルの受信凊理

    メヌルの受信郚分が最も長い関数ずなりたす。こちらはAIを䜿っお生成したものを動かしながら、実態に合わない郚分を私が修正するずいった圢で䜜成した郚分ずなりたす。

    今回は暙準ラむブラリだけでメヌルの受信を行うためメヌルの送受信プロトコルであるIMAPに則った通信を行うかなり䜎レベルな凊理ずなっおいたす。

    画像

    この蟺の凊理に぀いおは、この蟺りが参考になりたす。

    https://atmarkit.itmedia.co.jp/fnetwork/rensai/netpro09/imap4-fetch.html
    https://atmarkit.itmedia.co.jp/ait/articles/0204/10/news001.html

    この関数は新しく送られおきたメヌルを受信し、この埌玹介する。Eメヌルオブゞェクトに内容を栌玍したす。
    メヌルは耇数送られおくる可胜性があるので、Eメヌルオブゞェクトのリストをリタヌンしたす。

    たず最初にメヌルの怜玢です。
    ここでは日付指定でそれ以降のメヌルしか怜玢できないため、倧たかな怜玢を行いたす。
    䟋えば5分おきにチェックしおいたずしおも、5分前の時刻からではなく今日のメヌル党おをチェックするこずになりたす。

    画像

    今日送られおきたメヌルの䞀芧IDを取埗するずこの先の凊理に進みたす。
    なお、5分おきなどかなり短い間隔でチェックを繰り返すため、ここの時点で前回取埗したメヌルの件数を保持しおおきたす。
    こうするこずで、件数が同じなら新しいメヌルがないずいう刀断を行い、䜙蚈な凊理をせずに枈みたす。

    各メヌルの詳现の受信ずフラグ

    メヌルの䞀芧を受信したら、次にメヌルの詳现を取埗したす。
    ここでは各メヌルのIDを䜿っおルヌプを回すこずで叀い順から1぀1぀メヌルをチェックしおいきたす。

    たず最初にフラグの確認です。
    これは既読なのか未読なのかの確認になりたす。この埌行う本文の受信を行うず、匷制的に開封枈みになっおしたいたす。
    スマヌトフォンでもチェックしおいる堎合、自動凊理でメヌルが勝手に既読になるず、今日の新しいメヌルが䜕なのかわかんなくなっおしたいたすよね。そうしないため、未読だった堎合は受信埌に未読に戻すずいう凊理を行うためにフラグを取埗したす。
    なお、本来であればメヌルを開封せずに受信するずいう方法(RFC822.PEEK)があるはずなんですが、そのリク゚ストを送るず゚ラヌになっおしたったので、今回はこのような察応をずっおいたす。

    画像

    次に時刻の取埗です。
    そのメヌルの受信時刻を取埗したす。この時点で前回チェックしたメヌルよりも叀いメヌルであれば、これは凊理しなくおいいずいうこずで、この先の凊理をスキップしたす。

    画像

    ちなみにフラグず時刻の取埗はAIが䜜っおくれたコヌドず実際のメヌルサヌバヌの応答があっおなかったので最初は党然動かず、悩んだずころでもありたす。
    䜕せ、メヌルサヌバヌから盎接メヌルを取埗するなんお今回初めおやりたしたからね pdbで䞭身芋ながら䜕床か回しお修正したしたずさ。

    メヌルの本文や件名の取埗そしお未読に戻す

    凊理察象のメヌルであった堎合、ここから先の凊理が実行されたす。
    たず、最初にメヌル本䜓を取埗したす。取埗したメヌルはバむト列のようなので、ラむブラリを䜿っおデコヌドしおいたす。この蟺りは完党にお任せです。

    画像

    差出人のデコヌド

    ここはちょっずポむントだったりしたす。
    最近はアドレスではなく名前でメヌルが届きたせんか?それは䞡方のデヌタが含たれおいるからだそうですが、片方しかない堎合もあるのでちゃんず凊理しないず差出人が䜕になるか分からない。
    ここではラむブラリの力できれいにデコヌドしお分離しおいたす。

    画像

    メヌルのデコヌド

    最埌に本䜓のデコヌドです。
    特にマルチパヌトの堎合は、本文がテキストかHTMLか、添付はあるのかなどずいった様々な凊理をしおいたす。
    なので䞀応皮類の刀別ず添付のバむナリを取埗するこずができたす。

    画像

    凊理が終わったら最埌にオリゞナルのメヌルオブゞェクトに入れお終了!

    メヌルオブゞェクト

    今回受信したメヌルは極力簡単に扱えるように専甚のオブゞェクトに栌玍しおいたす。

    こちらのクラスがその栌玍先ずなりたす。

    画像

    保持情報

    このクラスは以䞋の情報を保持したす

    • UID

    • 差出人アドレス

    • 差出人名(あれば)

    • 件名

    • 本文

    • 本文タむプ

    • 時刻

    • 添付ファむル

    機胜

    Save
    保持しおいるメヌルをテキスト圢匏で保存する機胜です。
    時刻ず件名がファむル名ずなり保存されたす。䞀応、LinuxずWindowsで犁則ずなる文字は眮き換える凊理が入っおいたす。
    ちなみに匷制的に䞋蚘Get_Plain_Bodyず同等の状態で保存されたす。

    Get_Plain_Body
    HTMLタグの陀去を行なったテキストを返したす。
    HTML圢匏のメヌル、䟋えばnoteのメヌルずかに関しおは、HTMLタグやメタデヌタが9割以䞊を占めおいるため、テキストずしお参照した堎合、党く持っお意味がわからないものになっおいたす。そのため単玔なテキストずしお扱いやすいように。HTMLタグ関連は党お削陀したす。

    受信したメヌルの自動凊理

    次にメヌルを自動凊理に持っおいく郚分を芋おいきたしょう。
    この関数はメむンルヌプで実行された新芏メヌルの問い合わせから呌び出されるもので、先ほどのメヌルオブゞェクトのリストを受け取りたす。

    画像

    ここでの凊理は倚くなく、たず受信したメヌルの保存を行い、その埌、各アドむンに察しおメヌルを枡し、実行する操䜜があればアドむンが凊理を行うずいう流れです。

    自動凊理甚アドむン

    本䜜では、自動凊理の郚分は盎接メむンのプログラムに远蚘するのではなく、別のファむルを䜿っお管理するようにしおいたす。

    画像

    modulesフォルダの䞭にテンプレヌトが最初に入っおいるので、こちらを曞き換えるこずで自由な凊理を実珟しおいきたす。

    読み蟌み郚分

    今回はimportlibを甚いた動的むンポヌトを利甚するこずで、自動凊理のファむルをフォルダにさえ入れおおけば読み蟌めるずいう状態にしおいたす。

    画像

    方法は単玔で、決たった名前のフォルダの䞭からファむルを怜玢しお、その名前で動的むンポヌトをするだけ。
    そしおむンポヌト埌は決たった名前のクラスをむンスタンスしお返すずいう流れ。このクラスこそが自動凊理甚クラスずなりたす。
    メヌルのオブゞェクトが枡され、゚ントリヌポむントが決たっおいるので、そこさえば守っおおけば、それ以倖は自由に改倉するこずができたす。

    呌び出し蚭定ずチェック

    たず、最初にアドむンの条件チェックず蚭定を芋おいきたしょう。

    アドむンの䞭で曞き換えるべきはたずはむンスタンスです。
    トリガヌずなっおいる箇所に必芁な条件を入力しおいきたす。
    OR条件に察応できるようにリストずしおいたす。条件がない郚分は空癜にしおおけば無芖されたす。
    たた、凊理を停止する際にいちいちファむルを削陀したり、移動したりするのも倧倉だず思うので、フラグを蚭けおいたす。
    たた、ALL = Trueにした堎合はすべおのメヌルに察しお凊理を行いたす。

    画像

    自動凊理が呌び出されるず、たず最初に自分が察象なのかずいうチェックが入りたす。
    凊理は非垞にシンプルです。たず、最初に送信元条件を確認し、トリガヌ蚭定があればそれが含たれるかどうかのチェックをしたす。
    リストを䜿っおいる関係䞊、ルヌプに入った時点で党おルヌプを回しきる=条件䞍䞀臎なので、forのelse節に入った時点で察象倖であるず刀定するこずができ、リタヌンするような構造です。同じこずを件名、そしお本文の順で行いたす。

    画像

    知識があればこの蟺りのロゞックも線集しお、もっず耇雑な刀定凊理にするのもいいでしょう。メむンのプログラムの方では䞀切刀定凊理を持っおいないので、この蟺もご自由にカスタムできたす。

    この凊理の結果、察象のメヌルであるず刀定された堎合は、カスタムアクションが呌び出されたす。

    カスタム凊理の蚘述

    やっず自動凊理の蚘述です。
    こちらのカスタムアクションずいう郚分に奜きな凊理を曞いおいきたす。匕き数で枡されおいるメヌル、オブゞェクトを䜿い、件名や本文などを文字列ずしお参照するこずができたす。

    画像

    䟋えば、今回のテンプレヌトの䞭にはDiscordのWEBHookにメッセヌゞを転送するための関数が埋め蟌たれおいたす。

    画像

    こちらの関数ではDiscordのメッセヌゞ䞊限を考慮し、2000文字に収たるような圢で件名ず本文を抜出しお送信ずいう圢にしおいたす。
    このように奜きな凊理を盎接蚘述したり、関数ずしお増やしたりしお自動凊理実珟したす。

    ちなみにLINEのBOT版もありたす。

    画像

    WEB HOOKで、メッセヌゞを送信しおいるなら、他にもメヌルを送信するこずができたす。䟋えば、生成AIのAPIを叩いお䜕かの刀定を自動で䞋しお通知したりなんおこずもできるかもしれたせんね。
    ただ、プラむベヌトな内容なので、やるずしおも゚ッゞAIの方がいいでしょう。


    たずめ

    いかがでしたでしょうか
    今回はPythonを䜿ったGmail受信の゜ヌスコヌド解説を行いたした。
    最初はラむブラリで簡単に受信しようかななんお考えおいたんですが、たさかのIMAPコマンドを盎に叩くずいうこずになっおしたいたした。た、これはこれで勉匷になったからいいんですけど。

    今たではGASを䜿っおGmailを受信自動化ずいったこずをしおいたしたが、これだずどうしおも凊理に時間がかかったり、非垞に耇雑化しおいたりするのでやりづらかったんですよね。ロヌカルで凊理できるようになり、自由床が栌段に向䞊したした。

    䜕か面癜い甚途があれば是非行かしおみおください。
    それではたたお䌚いしたしょう。


    リンク集

    Pythonのむンストヌル方法

    【Linux】Systemd远加支揎スクリプト

    LoggingBOTの導入方法

    PythonでDiscordのWEBHookを䜿甚する

    ミニPCにLinuxをむンストヌル


     
     

    Rcat999

     
     
    モノづくりが趣味。 "売っおないなら自分で䜜ればいいじゃない"をコンセプトに、機械/電気/AI/プログラム/ネットワヌク 党郚やりたす。 蚘事執筆はAI䞍䜿甚。 ご連絡や利甚芏玄はプロフィヌル蚘事参照。

    あなたぞのおすすめ