メールで要求して処理を実行するスクリプト

地域図書館の貸出記録を取得  で 作成したデータベースをメールで操作できるようにしました。

まず、スクリプト専用に gmail捨てアドレスを取得しました。 gmail の受信にあたっては

Linux bashでGmailの受信メールを見る - min117の日記 を参考にさせてもらいました。なお、今はアカウント設定で「安全性の低いアプリのアクセス」を有効にしておかないと、 curl を使用した場合 gmail は「401エラー」を返してきます。

f:id:S_E_Hyphen:20191104135815p:plain



gmail の feed はXML形式なのでxpathコマンドでentry ごとに送信者アドレスや表題(subject)、本文を取得してゆきます。取得した値は別途データベースに登録しておき、既に処理済みのメールなのか、初見のメールなのかを判断します。

当初はsubjectに特定の文字が入っていることをトリガーとして処理を実行させようとしていたのですが、subjectが一緒だと同一スレッドとして取り扱われてしまい、変数bodyに期待していたのとは違う値が入ってしまうことがわかりました。そこで仕方なしに発信者アドレスをトリガーとして、ジョブは本文ではなく表題で実行することにより問題を回避しました。

最後に検索結果は mail コマンドにより普段使いのアドレスから発信することにしています。本当は gmail捨てアドレスから送信できるようにしたかったのですが、 .mailrc でSMTP認証の設定が良く判らなかったため、このようになりました。 

#! /bin/bash
mysql -h 192.168.0.16 life_log << _SQL_
 create table if not exists gmail (
  id varchar(100),
  address varchar(30),
  sub tinytext,
  body tinytext
)
ENGINE=InnoDB DEFAULT CHARSET=utf8;
_SQL_

username="XXXXXXXX"
password="YYYYYYYY"
myaddress="mmm@ooo.zzz.ne.jp"

# GMAIL の受信
temp=`mktemp ./XXXX`
curl -u $username:$password --silent "https://mail.google.com/mail/feed/atom" > $temp
num_entry=`\
cat $temp |\
 xpath -q -e "//fullcount/text()" 2>/dev/null  `
for (( entry=1; entry<=${num_entry}; entry++ ))
do

# ID
 id=`\
 cat $temp |\
  xpath -q -e "//entry[${entry}]" 2>/dev/null |\
  xpath -q -e "//id/text()" 2>/dev/null `
# 発信者
 address=`\
 cat $temp |\
  xpath -q -e "//entry[${entry}]"  2>/dev/null |\
  xpath -q -e "//author/email/text()" 2>/dev/null `
# 表題
 sub=`\
 cat $temp |\
  xpath -q -e "//entry[${entry}]" 2>/dev/null |\
  xpath -q -e "//title/text()" 2>/dev/null`
# 本文
 body=`\
 cat $temp |\
  xpath -q -e "//entry[${entry}]" 2>/dev/null |\
  xpath -q -e "//summary/text()" 2>/dev/null |\
  awk '{print $1}'`

# もしIDが一致するレコードが存在すればループへ戻る
num_line=`\
mysql -h 192.168.0.16 life_log -N << _SQL_
 select count(*) from gmail where id="${id}";
_SQL_`
if [ $num_line -ne 0 ]
then
 continue
fi
# 初見ならばデータベース登録しlibrary検索を実施
mysql -h 192.168.0.16 life_log << _SQL_
 insert into gmail(id,address,sub,body)
  value("${id}","${address}","${sub}","${body}");
_SQL_
if [ ${address} = ${myaddress} ]
then
 cat << + > to_mail.txt
図書館借用記録の検索結果【${sub}】
+
 mysql -h 192.168.0.16 -N life_log << _SQL_ >> to_mail.txt
  select title,出版社,発行年月 from library where auther like "%${sub}%";
_SQL_
fi

address="${address}"
title="検索結果【${sub}】"
cat to_mail.txt |\
  tee -a /dev/stderr |\
  mail -v -s "$title" ${address}

done
rm $temp to_mail.txt

 あちこち工事中のような印象のスクリプトではありますが、これを crontab に登録するなどして定期的に実行させることにより、図書館に居ながら著者名をメール送信するだけで「この本は既に借りたことがあったか」確認できるようになりました。