GAEでメール受信&メール送信 〜勝手に思ってるサークルの問題点に、勝手に取り組む
勝手に思ってるサークルの問題点に、勝手に取り組むシリーズ 第二弾~新入生メールアドレス自動登録編~
やりたいこと
煩雑なメール登録作業の軽減がしたい!!
毎年、新入生歓迎の時期になると多くの新入生がサークルに集まってくる。うちのサークルでは、GMailを使って連絡を行っている。そのため、その度に何10人、最終的には100人規模でメールアドレス登録するという地獄の作業が待っている。これはなかなか辛い。
ちょっと前までは、紙にアドレスを書いてもらっていた
いままでは、紙にアドレスと名前を書いてもらって、後で転記、メールアドレス登録、メール送信という手段を取っていたみたい。
んなアホなっ!!!!
案の定、記入者の記入ミス、転記者の転記ミス、登録者の登録ミスが多発。せっかくアドレスを書いてもらっても、情報を伝える大切な機会を失っていた。
そこで、自分は、次の方法に切り替えた。
- Gmailアドレスのエイリアス(+freshman)を使って新入生勧誘用のGmailアドレスを生成
- 新入生勧誘用のGmailアドレスのQRコードを生成
- そのQRコードをケータイで読み取ってもらい、名前(と大学名)だけ入れてもらい送信
- Gmail側で新入生のフィルリング処理
これによって、転記ミスの大幅軽減に成功!!
それでも、アドレスを管理するために、結局は、アドレスを登録するという作業は残されている。
そこで、Google App Engineを使って、メール受信して、名前とメールアドレスをパース。それをDB登録。そこからGmailのアドレス帳を出力できるようにすれば便利なんじゃ?と考えた。が、当時は、そこまでの技術はなくて断念。若干時間にゆとりのある今だからこそ、改めて挑戦したい!!! ってことで、まずはGAEでメール受信&送信にチャレンジ
GAEでメール受信&メール送信
Google App Engineでのメール受信とメール送信なんて、公式ドキュメントにも載ってるしまずは簡単に出来るだろうっ!って思ってた自分が間違いでした。チュートリアルを見ても全然上手くいかない。色々と、探しているうちに、次のページを見つけて参考(流用・・・)にさせてももらいました!ありがとうございます!!!
Google App Engine for Javaでのメール受信コード -きしだのはてな
これでやっと、メール受信、そのメールを送った先のメールアドレスとの本文を丸ごと取得、本文をそのまま取得したメールアドレスに送信という流れができました。ソースを↓に載せておきます。
次回の作業
次は、メール受信から本文のパースとDB登録です。パースは、調べれば出来そうですが、DB登録がなかなかのくせ者のよう。まずは、BigTableの概念を掴まないと始まらないですね。
明日は今日とは違う自分になる
金曜日は、ジュンク堂にいき、常々欲しいと思ってた2冊の本を買いました。「情熱プログラマー」と「自分の小さな「箱」から脱出する方法」の2冊です。2冊とも、Twitterでオススメされた本なので、非常に楽しみです。また、気付いたこと、感じたことをまとめたいと思います。明日は今日とは違う自分になるでした。
package javamail;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.Properties;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@SuppressWarnings("serial")
public class JavaMailServlet extends HttpServlet {
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/plain");
resp.getWriter().println("Hello, world");
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
try {
MimeMessage message = new MimeMessage(session, req.getInputStream());
MimeMessage mail = new MimeMessage(session);
mail.setSubject(message.getSubject());
//ローカルサーバーでは文字化けするので次のようなコードが必要。本番サーバーでは不要
//mail.setSubject(new String(message.getSubject().getBytes("8859_1"), "UTF-8"));
//返信元アドレスを構成
URL url = new URL(req.getRequestURL().toString());
String senderAddress = "echo@" + url.getHost().replace("appspot", "appspotmail");
Address sender = new InternetAddress(senderAddress);
mail.setFrom(sender);
mail.setRecipient(Message.RecipientType.TO, message.getFrom()[0]);
//mail.setRecipient(Message.RecipientType.TO, TO);
String contentType = message.getContentType();
InputStream is = null;
//2009/12/11 挙動がかわったことに対応
String mess = "";
if(message.isMimeType("text/plain")){
//ふつうのメールの処理
/* 2009/12/11 ここも挙動が変わってたので、ClassCastExceptionになります。
is = (InputStream) message.getContent();
*/
mess = (String)message.getContent();
}else{
//HTMLメールや添付メールの処理
/* 2009/12/3 挙動が変わったのでこれではClassCastExceptionが発生する
Multipart content = new MimeMultipart(
new ByteArrayDataSource(
(InputStream)message.getContent(),
message.getContentType()));
*/
Multipart content = (Multipart)message.getContent();
for(int i = 0; i < content.getCount(); ++i){
BodyPart bp = content.getBodyPart(i);
if(!bp.isMimeType("text/plain")) continue;
is = bp.getInputStream();
contentType = bp.getContentType();
break;
}
}
if(is != null){
//contentTypeからエンコーディングを取得
String encoding = null;
String[] elms = contentType.split(";");
for(String elm : elms){
if(elm.trim().startsWith("charset=")){
encoding = elm.trim().substring("charset=".length());
}
}
Reader r = null;
if(encoding != null){
//エンコーディングが入っている
if(encoding.startsWith("\"")) encoding = encoding.substring(1);
if(encoding.endsWith("\"")) encoding =
encoding.substring(0, encoding.length() - 1);
r = new InputStreamReader(is, encoding);
}else{
//エンコーディングが入っていない
r = new InputStreamReader(is);
}
//2009/12/11 挙動がかわったことに対応
//String mess = "";
BufferedReader buf = new BufferedReader(r);
for(String line; (line = buf.readLine()) != null;){
mess += line + "\n";
}
//2009/12/11 挙動がかわったことに対応
//mail.setText(mess);
}
//2009/12/11 挙動がかわったことに対応
mail.setText(mess);
Transport.send(mail);
} catch (MessagingException ex) {
ex.printStackTrace();
}
}
}
参考図書
Related contents
TECH
2010.09.23
TECH
2010.07.13
TECH
2010.05.29
TECH
2011.04.18
TECH
2009.05.19
TECHBOOK
2009.05.14
TECH
2008.05.31