Rの計算終了時に{mailR}を使って通知を飛ばして生産性を上げる
はじめに
時間がかかるスクリプトを走らせてる間、僕はついTwitterを見てしまうのですが、いつも処理が終わったのに気づかず、ダラダラとTwitterを見続けてしまっていました。計算が終わった時点で通知がくればいいなと思って、方法をいろいろ調べてみたのですが、結局、{mailR}で自分にメールを飛ばすという方法がいいのではないかと思ったので記事を書きます。
計算終了時に通知を鳴らす方法
計算終了時に通知を鳴らす方法はいくつかあって、こちらによくまとまっていました。
www.slideshare.net
これと他の方法をまとめると、
- 音だけを鳴らす
- メールを自分に送る
- pushoverというアプリを使う
- terminal-notifierを使う
という方法があるようです。ただ1.は超簡単だけどMacをサイレントにしていると気づかない。家ならいいですけどね。3.は有料なので却下。4.に関しては
こちらに記事がまとまっており、実装も簡単なのですが、通知のポップアップが出ない…。通知センターを開くと、通知は来てるんですが、何故かポップアップが出ないので気づけない…RStudioでもnative Rでも同じでした。一応、同じ現象は他の人にも起きているようで、
GitHubにスレッドが立っていましたが、どうやら解決はしていなさそうで諦めました。というわけでメールで通知する方法を考えます。これだと出先でも通知を受け取れるのでいいかもしれません。
{mailR}を使ってメールで通知する
{gmailr}というパッケージもあるようですが、僕は最後のGoogleの認証がうまく行かずに断念しました。なので{mailR}でいいんじゃないかと思います。
{mailR}に関しては、からだにいいものにまとめられています (なんでもあるな、ほんとに…)。ファイルを添付したり、一斉送信などもできるようです。
install.packages("mailR", dep = T) library("mailR") mailR::send.mail(from = "自分のメールアドレス", to = "自分のメールアドレス", subject = "件名", body = "本文", encoding = "utf-8", smtp = list(host.name = "smtp.gmail.com", port = 587, user.name = "自分のメールアドレス", passwd = "パスワード", ssl = T), authenticate = TRUE, send = TRUE)
こんな感じで動きます。僕は
ntf <- function(passwd){mailR::send.mail(from = "自分のメールアドレス", to = "自分のメールアドレス", subject = "件名", body = "本文", encoding = "utf-8", smtp = list(host.name = "smtp.gmail.com", port = 587, user.name = "自分のメールアドレス", passwd = passwd, ssl = T), authenticate = TRUE, send = TRUE)}
という自作関数を作っておいて、ntf()
にパスワードだけ入力すれば動くものを作っています。ただし、{mailR}を使うには下記のエラーメッセージを解決する必要があります。
java.activationを追加する
上記のスクリプトを実行しようとすると
Error: NoClassDefFoundError (Java): javax/activation/DataHandler
とエラーが出ると思います。この原因は下記のQiita記事によると、
OracleJDK 8 から OpenJDK 11 に変更したところ、JavaMail で以下の例外が発生するようになりメール送信が一切できなくなりました。 JavaMail では内部で java.activation パッケージを使用していますが、OpenJDK 11 以降では JEP 320: Remove the Java EE and CORBA Modules によって以下のパッケージが削除されています。 java.activation パッケージが削除されたことにより JavaMail で参照するクラスが見つからなくなり概要で示した例外が発生しています。
ということでした。ただ、この記事の対処法ではうまく行かず、最終的にはStackOverflowの下記の記事が参考になりました。
下記の2つのURLに飛んで、
.jar
ファイルをダウンロードする https://mvnrepository.com/artifact/javax.activation/javax.activation-api/1.2.0 https://mvnrepository.com/artifact/com.sun.activation/javax.activation/1.2.0mailR
が格納されているディレクトリのjava
フォルダに2つの.jar
ファイルをコピペする
ちなみに僕のケースでは、mailR
はここ
/Library/Frameworks/R.framework/Versions/3.6/Resources/library/mailR/java
にありました。
Gmailのセキュリティを変更する
JavaMailのエラーを解決すると今度は、
Error: EmailException (Java): Sending the email to the following server failed : smtp.gmail.com:465
というエラーが出るかもしれません。その場合は、Gmailのセキュリティを変更する必要があります。
https://myaccount.google.com/lesssecureapps?pli=1
にアクセスして、安全性の低いアプリのアクセスを許可するように変更しましょう。計算時間の長いスクリプトを実行した後に、send.mail()
を実行しておけば、計算終了時にRからメールで通知を送ることができます!
追記
他の環境で試したらまたエラーが出たので追記しておきます。
Error: .onLoad failed in loadNamespace() for 'rJava', details: call: fun(libname, pkgname) error: JVM could not be found
まずこのエラーが出てきました。これをぐぐると、
この記事にたどり着きます。ここに
「あなたが使ってる環境は64-bitバージョンのOSとRで、それに対応してないJavaがインストールされてないからだ。下記のリンクからインストールしなさい」
と書いてあるので、Javaのページから従う。
しかし動かず、同じエラーが出てくる。そう言えば、{tabulizar}をインストールするときに異常に苦労した{rJava}がまたエラーになってるなあと気づきました。その時の記事はこちら。
試しに
library(rJava)
を実行すると
Install Java and/or check JAVA_HOME (if in doubt, do NOT set it, it will be detected)
というエラーが。これをググると、この記事にたどり着きました。
export JAVA_HOME=jdk-install-dir export PATH=$JAVA_HOME/bin:$PATH
これでもう一つの環境でも{mailR}が実行できました。この内のどのステップが有効だったのかはわかりませんが、もしよかったら試してみてください。