sendmailでメールの自動返信

`投稿時期:2019/11/06`

# はじめに
ユーザがメルマガ宛にメールを返信した場合、メルマガ宛にはメールが届かない旨の自動返信を行うことがあります。
これはだいたい自動返信しており、その仕組みを試してみました。

```sh:
TO：no-reply-xxxx@xxxx.com
*注意：このe-mailは送信専用のアドレスのため返信を受け付けておりません。
```

## 結果
メールでの自動返信ができるようになる。

## 概要
ここで試した自動返信の仕組みはこの流れとなります。
sendmail,シェルスクリプトのみを使用して実現しています。

|フロー|実現方法|
|----|----|
|①クライアントがno-reply宛にメール送信|クライアント側で手動実行|
|②sendmailのno-replyユーザでメールを受信|sendmail設定|
|③sendmailがsh実行|sendmail設定|
|④shでクライアントに自動返信|シェルスクリプト設定|

# 環境準備
## 前提
環境としてはlinux,sendmailを使用します。
linux,sendmailの基本的な設定は既に出来ているものとし、ここでの説明は割愛します。
ちなみに私の使用している環境は下記です。
他に特殊な設定はしてないので他の環境でも再現可能かと思います。

```
# cat /etc/system-release
Red Hat Enterprise Linux Server release 7.2 (Maipo)
```
```
# /usr/sbin/sendmail -d0.101
Version 8.14.7
```

## ソフトウェアのインストール
環境にnkfがない場合はインストールします。
nkfはシェルスクリプトで使用します。
>④shでクライアントに自動返信

``` :インストール確認
# which nkf
# which gcc
# which wget
```
``` :yumインストール
# yum install gcc
# yum install wget
```
```:makeインストール
# wget 'https://ja.osdn.net/frs/redir.php?m=jaist&f=nkf%2F64158%2Fnkf-2.1.4.tar.gz' -O nkf-2.1.4.tar.gz
# tar zxvf nkf-2.1.4.tar.gz
# cd nkf-2.1.4
# ll
# make install
```

# sendmail関連設定
## 自動返信用のアドレス(ユーザ)を作成
ここからようやくsendmailの設定となります。
といってもsendmailの設定自体はシンプルなものです。

今回は「no-reply」というアドレスを使用しますので、Linux上でユーザを作成します。
作成したno-reply配下に下記ファイルを作成します。

```
# ll -a /home/no-reply/
-rw-r--r--  1 no-reply no-reply       56 10月 23 11:53 .forward
-rw-rw-rw-  1 no-reply no-reply 16285108 10月 24 14:50 auto-reply-mail.log
-rw-r--r--  1 no-reply no-reply     3204 10月 24 14:49 auto-reply-mail.sh
```

## .forward設定
下記を.forward設定で実現しています。
no-replyユーザでメールを受信し、auto-reply-mail.shを実行するように.forward設定します。
>②sendmailのno-replyユーザでメールを受信
>③sendmailがsh実行

```:.forward
\no-reply, "|/bin/sh /home/no-reply/auto-reply-mail.sh"
```

# シェルスクリプト設定
## auto-reply-mail.sh設定
今回のメインであるシェルスクリプトの設定を行います。
ここで設定したシェルスクリプトが.forwardから呼び出されます。
>④shでクライアントに自動返信

```shell:auto-reply-mail.sh
#!/bin/sh

## 変数指定
# logfile
logfile="/home/no-reply/auto-reply-mail.log"

# from
from="xxxx <no-reply@xxxx>"

# return-path
return-path="bounce@xxxx"

# content
content-type="text/plain; charset=ISO-2022-JP"
content-transfer-encoding="7bit"

# subject
# メールから取得

# body
# 下記指定文言
body=`cat << EOF
【本メールは自動返信にてお送りしております】

自動返信メッセージを記載
EOF
`

## 関数
#mail_function
mail_function () {
    # subject,from,bodyをnkfエンコード
    subject2=`echo Re:$subject | /usr/bin/nkf -Mj`
    #subject2='Auto-Reply Message'
    from2=`echo "$from" | /usr/bin/nkf -Mj`
    body2=`echo "$body" | /usr/bin/nkf -j`

mail=`cat << EOF
Return-Path: $return-path
Reply-To: $return-path
From: $from2
To: $to
Subject: $subject2
Content-Type: $content-type
Content-Transfer-Encoding: $content-transfer-encoding

$body2
EOF
`
    echo "$mail"
}

## メインロジック
# 標準入力有無の判別
if [ -p /dev/stdin ]; then
    # 標準入力取得
    in=$(cat -)

    # debug
    echo "$in" >> $logfile

    # Fromアドレスを抽出
    to=`echo "${in}" | egrep -i "^From: " | sed -e "s/From:\s*\(.*\)/\1/g"| head -1`

    # Subjectを抽出
    subject=`echo "${in}" | egrep -i "^Subject:" | sed -e "s/Subject:\s*\(.*\)/\1/g"| head -1`

    # メール送信
    echo "`mail_function`" | /usr/sbin/sendmai -it
else
    echo "error -no standard input"
fi
```

## auto-reply-mail.sh設定の補足
- 各変数は自由に変更してください。
 
```shell:
content-type="text/plain; charset=ISO-2022-JP"
content-transfer-encoding="7bit"
```

- Fromアドレス,Subjectをユーザ送信メールから抽出しています。

ユーザFromアドレスを抽出して、自動返信の宛先Toアドレスとしています。
Subjectも抽出し、別途処理でRe:を追加して返信用Subjectとしています。

```sh:
# Fromアドレスを抽出
to=`echo "${in}" | egrep -i "^From: " | sed -e "s/From:\s*\(.*\)/\1/g"| head -1`
```

```sh:
# Subjectを抽出
subject=`echo "${in}" | egrep -i "^Subject:" | sed -e "s/Subject:\s*\(.*\)/\1/g"| head -1`
```

- 必要な箇所のエンコードを行います。

```sh:
# subject,from,bodyをnkfエンコード
subject2=`echo Re:$subject | /usr/bin/nkf -Mj`
from2=`echo "$from" | /usr/bin/nkf -Mj`
body2=`echo "$body" | /usr/bin/nkf -j`
```
Subjectのエンコード検証ではoutlook,Becky!は動作に問題がなかったのですが、Thunderbirdだとnkfエンコードしても文字化けしてしまいました。

```
#subject2='Auto-Reply Message'
```
ここは課題ですが、最終的には上記の様にベタ書きにしました。