見出し画像

短文の迷惑メールがたまに来るので勝手にAIに返信させる

オーガニック!(気さくな挨拶)

最近はメールを使うことも少なくなり、ほとんど会員登録とかネットショッピングの時の確認くらいにしか使わなくなりました。メールを書く相手は大学の教員くらいしかいません。

よくTwitterとかで過去の遺物としてディスられているキャリアメール。docomoを契約しているので「@docomo.ne.jp」のアドレスを持っているのですが、ここ5年以上全く使っていません。

迷惑メールはどのメールアドレスにも来るのですが、docomo宛に来る迷惑メールは日本語短文のものが多いです。

ドコモメールWeb版

預金残高とかはありがちなやつなので良いとして、「席隣同士で良かった」とかいうここから何を引き出したいのかさえ謎なメールがちょくちょく来ます。どうせメールアドレスの有効確認か何かに使って、カモリストに突っ込まれる運命だろう。このLINEレベルの短文日本語にチャットボットが返信するようにしたら面白いのではないかと考えつきました。もしカモリストに入れられても即メールアドレスを変えればいいので、気楽にやってみよう。

チャットボットの選定

最初マイクロソフトのAIりんなにでも返信させようとしましたが、当然APIなんて公開されている訳もなく。LINEグループにりんなを招待して、受信メールの内容をしゃべる自作のbotと勝手に会話させるのもダメらしい。

API形式で簡単に扱える無料のチャットボットは無いかと思ったら、ドロイドちゃんのチャットボットでお馴染みmaKunugi氏のChaplus APIを思い出しました。APIトークンと一緒にPOSTするだけ。あまりにも簡単です。

実装

Node.jsとGCP Cloud Functionsを使うことにしました。ドコモメールをIMAPで扱うにあたって「inbox」とかいうライブラリを使用しました。

まずメールを受信してみようと思います。サンプルにあった通りに書いてみます。

const inbox = require('inbox');

const client = inbox.createConnection(false, 'imap.spmode.ne.jp', {
    secureConnection: true,
    auth: {
        user: 'メールアドレス@docomo.ne.jp',
        pass: 'IMAPパスワード'
    }
})

client.connect()

client.on('connect', function () {
    client.openMailbox('INBOX', function (error, mailbox) {
        if (error) throw error

        client.listMessages(-10, function (err, messages) {
            messages.forEach(function (message) {
                console.log(message.UID + ": " + message.title)
            })
        })
    })
})
受信できた

あっけなく受信できたので、これをChaplusに投げてみます。
としたら、メールの内容を見るためにはまた別のライブラリが必要らしい。mailparserを導入します。

const simpleParser = require('mailparser').simpleParser

短文メールに限るため、件名と内容合わせて140文字を超えたら処理をストップすることにしました。また、下には記していないものの、引用符以下の文字列は無視する処理や、未読メールのみに反応する処理も書いています。

client.listMessages(-10, function (err, messages) {
            messages.forEach(function (message) {
                const messageStream = client.createMessageStream(message.UID)
                simpleParser(messageStream)
                    .then(mail => {
                        const q = `${message.title}
${mail.text}`
                        if(q.length > 50) return false
                        console.log(q)
                    })
                    .catch(err => {
                        console.log(err);
                    });
            })
        })

これをChaplusにPOSTしてみます。返信の右の数字はスコアです。

クエリ:
雪が凄い積もってるんだけど!
駅まで迎えにこれない?
返信:
駅まで迎えに行けない時はどうすればいいですか?(0.75)

クエリ:
席隣同士で良かった?
それとも一個離しておく?
間に座られたら笑うけど
返信:
二人とも席を立ってお話になりませんか(0.75)

クエリ:
本当に困ったよ。
相談に乗ってもらえないかな?
返信:
困った時は、なんでもご相談ください。(0.75)

結構な自然さで驚きました。あとはこれを返信するだけ。

多分無いと思いますが悪意のない間違いメールの可能性があるので、メールの末尾に「これはAIによる自動返信です。もし間違いメールの場合はアドレスをご確認ください。」くらいは貼ってお来ました。

メールの送信にはnodemailerを利用しました。

const NodeMailer = require('nodemailer')
function sendMail(mailData) {
    const smtpData = {
        host: 'smtp.spmode.ne.jp',
        port: '465',
        secure: true,
        auth: {
            user: 'メールアドレス@docomo.ne.jp',
            pass: 'IMAPパスワード'
        }
    }
    const transporter = NodeMailer.createTransport(smtpData)
    transporter.sendMail(mailData, function (error, info) {
        if (error) {
            console.log(error)
        } else {
            console.log('Email sent: ' + info.response)
        }
    })
}

とりあえず自分宛に送信してみます。

1人で食べるのが好きなタイプです。みんなでワイワイするのも好きです。

正しく送信できているので、これをデプロイします。「席隣同士で良かった?」に対する返信なのに、毎回返答が変わるらしいです。面白い。

Google Cloud Funtionsには、
gcloud beta functions deploy mailAutoReply --entry-point=mailAutoReply --trigger-http --runtime=nodejs14
でデプロイできました。HTTPでトリガーするので、最低限の認証機能くらいは付けておくべきです。あとはこのURLをCloud Schedulerかなんかで定期的に叩けば完璧。

とりあえず3時間に一度動かしています。懸念点としては、このプログラムから送信したメールは送信ボックスには残らないみたいです。どうしてだろう。

なので、BCCとして自分にも送るようにしました。

女のオーガニック
ネカマになりました


この記事が気に入ったらサポートをしてみませんか?