Apache James + Groovy でメール連携アプリケーション その1
ちょっと時間ができたので、Java製メールサーバJamesとGroovyで
メールを受信した時に何か応答するアプリケーションを作ってみます.
以前の記事にも書いたのですが、この組み合わせの理由は、
「jarに固めて、サーバに配置して、James再起動」
という開発は面倒くさそうだから、デバックが必要な部分を
Groovyで記述してしまえばいいのでは?と思ったからです.
JavaとGroovyの連携は以前調べていたので・・・
http://fujishinko.exblog.jp/7216773
これを応用して、JamesからGroovyのスクリプトが呼べるようにします。
■MainProcess.java
package jp.dip.dkdc.james;
import javax.mail.*;
import javax.mail.internet.*;
import org.apache.avalon.cornerstone.services.datasources.DataSourceSelector;
import org.apache.avalon.excalibur.datasource.DataSourceComponent;
import org.apache.avalon.framework.service.DefaultServiceManager;
import org.apache.james.Constants;
import org.apache.mailet.Mail;
import org.apache.mailet.GenericMailet;
import org.apache.mailet.MailetContext;
import java.sql.*;
import groovy.lang.Binding;
import groovy.util.GroovyScriptEngine;
//Jamesがメールを受信した時に呼ばれるクラス
public class MainProcess extends GenericMailet{
//DBコネクションプール
private DataSourceComponent dsc;
//Groovyスクリプト実行
private GroovyScriptEngine gse;
//実行するスクリプト名
private String script;
public void init() throws MessagingException {
try {
DefaultServiceManager dsm = (DefaultServiceManager) getMailetContext().getAttribute(Constants.AVALON_COMPONENT_MANAGER);
DataSourceSelector dss = (DataSourceSelector) dsm.lookup(DataSourceSelector.ROLE);
dsc = (DataSourceComponent) dss.select("dkdc");
} catch (Exception e){
throw new MessagingException("DB接続初期化エラー", e );
}
try {
gse = new GroovyScriptEngine("/var/local/james/");
} catch (Exception e){
throw new MessagingException("GroovyScriptEngine初期化エラー", e);
}
script = getInitParameter("script");
if (script == null) {
throw new MessagingException("スクリプトファイル名取得エラー");
}
}
//メール受診時の動作
//Groovyスクリプトを実行する
public void service(Mail arg0) throws MessagingException {
Binding binding = new Binding();
Connection con = null;
try {
con = dsc.getConnection();
MailData data = new MailData(arg0);
System.out.println(data.getSender());
//自分宛のメールは処理しない
if (data.getSender().equals("a@exmple.com")) {
return;
}
binding.setVariable("mail",data);
binding.setVariable("db", con);
//スクリプト呼び出し
MailData result = (MailData)gse.run(script, binding);
//結果を送信
if (result != null) {
MimeMessage mm = new MimeMessage((Session)null);
mm.setHeader("Content-Transfer-Encoding", "7bit");
mm.setSubject(result.getSubject(),"ISO-2022-JP");
mm.setText(result.getBody(), "ISO-2022-JP");
mm.setFrom(new InternetAddress("a@dkdc.dip.jp"));
mm.setSentDate(new java.util.Date());
mm.setRecipient(Message.RecipientType.TO,new InternetAddress(result.getSender()));
//送信
MailetContext mc = getMailetContext();
mc.sendMail(mm);
}
} catch(Exception e){
throw new MessagingException("", e);
} finally {
try {
if (con != null) {
con.close();
}
} catch (Exception ex){}
}
}
}
■MailData.java
package jp.dip.dkdc.james;
import java.io.IOException;
import javax.mail.MessagingException;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimePart;
import org.apache.mailet.*;
//メールデータ保持クラス
public class MailData {
//送信者
private String sender = "";
//件名
private String subject = "";
//本文
private String body = "";
public MailData() {
}
//Jamesで受信したメールのパースを実行
public MailData(Mail mail) throws MessagingException {
MailAddress addr = mail.getSender();
sender = addr.toString();
try {
MimeMessage message = mail.getMessage();
subject = message.getSubject();
body = getText(message);
} catch(Exception e){
subject = "";
body = "";
throw new MessagingException("メールパースエラー", e);
}
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public String getSubject() {
return subject;
}
public void setSubject(String title) {
this.subject = title;
}
// MimeMessage解析
private String getText( MimePart part ) throws MessagingException, IOException {
// Mime Type により分岐
if( part.isMimeType( "text/plain" ) ) {
return part.getContent().toString();
} else if( part.isMimeType( "text/html" ) ) {
return part.getContent().toString();
} else if( part.isMimeType( "multipart/mixed" ) ) {
MimeMultipart mp = (MimeMultipart)part.getContent();
return mp.getBodyPart(0).getContent().toString();
} else if( part.isMimeType( "multipart/alternative" ) ){
MimeMultipart mp = (MimeMultipart)part.getContent();
int num = mp.getCount();
for( int i = 0; i < num; i++ ) {
MimeBodyPart body = (MimeBodyPart)mp.getBodyPart(i);
String ret = getText( body );
if( ret != null ) {
return ret;
}
}
return null;
} else {
return null;
}
}
}
もどる