はてなブックマークへ新規追加したページとコメントの情報をGAE側で受け取りブログへメール投稿する。



□やりたかったこと

はてなブックマークへ新規追加したページとコメントの情報をGAE側で受け取って
一日一回Blogサイトへメールで投稿する。

□用意

・はてなブックマークWebHookの設定および仕様
http://developer.hatena.ne.jp/ja/documents/bookmark/apis/webhook

・Apache Commons Lang(v3.1)
http://commons.apache.org/proper/commons-lang/
一部の文字列処理のため


作成したクラス
・Servletクラス:HBCatch.java…
はてなブックマークWebHookが送ってくるリクエストを受け取ってDatastoreに保存する。

・HBAction.java…HBModelの示すKindを操作するクラス
・HBModel.java…保存用のデータを表すクラス
・Servletクラス:HBMail.java…
HBModelとして保存されたデータをまとめて指定されたメールアドレスへ送信するサーブレット。CronによるKickを想定

□ソース

置き換える必要があるデータ:
yourpkgはお使いのJavaパッケージ名
{KeyString}はWebHook側で指定したKeyの文字列
{AppID}はAppEngineでのアプリケーションID(http://●.appspot.comの●部分)
blogpostaddress@example.comはブログサイトのメール投稿用のアドレス

■Servletクラス:HBCatch.java
-------------------------------------
package yourpkg;
import java.io.IOException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;

public class HBCatch extends HttpServlet {
 private static final long serialVersionUID = -407391631604806983L;

 public void doGet(HttpServletRequest req, HttpServletResponse resp)
   throws IOException {
  resp.setContentType("text/plain");
 }

 public void doPost(HttpServletRequest req, HttpServletResponse resp)
   throws IOException {
  if (req.getParameter("status").equals("add")&&req.getParameter("key").equals("{KeyString}")){
    String title =req.getParameter("title");
    String url=req.getParameter("url");
    String comment=req.getParameter("comment");
    HBAction actor = new HBAction(title,url,comment);
    actor.saveDS();
  }
 }
}
//////////////////////
■HBAction.java
------------------
package yourpkg;
import com.google.appengine.api.datastore.*;
import org.apache.commons.lang3.*;
public class HBAction {
 HBModel hbmodel;
 String  text;
 DatastoreService ds;

 public HBAction(String title,String url,String comment){
  text = "■"+title+":\n"+
      url+"\n"+
      "# "+ObjectUtils.defaultIfNull(comment,"")+"\n\n";
  this.hbmodel = new HBModel(text);
 }
 private HBAction(){}
 public void saveDS(){
  ds = DatastoreServiceFactory.getDatastoreService();
  ds.put(hbmodel.getEntity());
 }
}
////////////////////
■HBModel.java
-----------------------------
package yourpkg;
import org.apache.commons.lang3.*;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
public class HBModel {
 Key hbk;
 Entity ent;
 public static final String KindName ="HBModel";
 String text;
 long recdate;

 private HBModel(){
 }
 public HBModel(String text){
  this.text=text;
  this.recdate = new java.util.Date().getTime();
  this.hbk = KeyFactory.createKey(KindName,recdate);
  this.ent = new Entity(hbk);
  ent.setUnindexedProperty("Text", text);
 }

 public  Key getKey(){
  return hbk;
 }
 public Entity getEntity(){
  return ent;
 }
}
////////////
■サーブレットHBMail.java
-------------------------------
package yourpkg;
import java.util.ArrayList;
import java.util.List;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.mail.*;
import java.io.IOException;
import javax.servlet.http.*;
import org.apache.commons.lang3.time.*;
public class HBMail extends HttpServlet {
 private static final long serialVersionUID = -6499070837519522335L;
 DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
 public void doGet(HttpServletRequest req, HttpServletResponse res)
 throws IOException {
  if (getHBList().size()>=1){
   FastDateFormat dateformat = FastDateFormat.getInstance("yyyy/M/d");
         String mailsubject ="はてブ投稿:"+dateformat.format(new java.util.Date());
         String msgBody =concatHB();
        
          com.google.appengine.api.mail.MailService.Message msg =
            new com.google.appengine.api.mail.MailService.Message();
          msg.setSender("sender@{AppID}.appspotmail.com");
          msg.setTo("blogpostaddress@example.com");
          msg.setSubject(mailsubject);
          msg.setTextBody(msgBody);
          MailServiceFactory.getMailService().send(msg);        
          removeHBList();
  }

 }


 List<Entity> getHBList(){
  Query q = new Query(HBModel.KindName);
  PreparedQuery pq = ds.prepare(q);
  List<Entity> hbentList = pq.asList(FetchOptions.Builder.withDefaults());
  return hbentList;
 }

 String concatHB(){
  StringBuffer sb = new StringBuffer("");
  for(Entity ex:getHBList()){
   sb.append(ex.getProperty("Text"));
  }
  return sb.toString();
 }

 void removeHBList(){
  Query q = new Query(HBModel.KindName);
  PreparedQuery pq = ds.prepare(q);
  List<Entity> results = pq.asList(FetchOptions.Builder.withDefaults());
  List<Key> resultsKey = new ArrayList<Key>();
  for (Entity ent:results){
   resultsKey.add(ent.getKey());
  }
  ds.delete(resultsKey);
 }
}
/////////////////////
■cron.xmlに追加
--------------------
   <cron>
    <url>/cron/hbmailr</url>
    <description>Cron09Mail</description>
    <schedule>every day 6:00</schedule>
    <timezone>Asia/Tokyo</timezone>
  </cron>
/////////////////////
■web.xmlに追加
--------------------
 <servlet>
 <servlet-name>HBCatch</servlet-name>
 <servlet-class>yourpkg.HBCatch</servlet-class>
 </servlet>
 <servlet-mapping>
 <servlet-name>HBCatch</servlet-name>
 <url-pattern>/hbcatch</url-pattern>
 </servlet-mapping>
 <servlet>
 <servlet-name>HBMail</servlet-name>
 <servlet-class>yourpkg.HBMail</servlet-class>
 </servlet>
 <servlet-mapping>
 <servlet-name>HBMail</servlet-name>
 <url-pattern>/cron/hbmailr</url-pattern>
 </servlet-mapping>
<security-constraint>の要素に以下を追加
      <web-resource-collection>
  <web-resource-name>cron</web-resource-name>
        <url-pattern>/cron/*</url-pattern>
      </web-resource-collection>
      <auth-constraint>
        <role-name>admin</role-name>
      </auth-constraint>
////////////////////

コメント

このブログの人気の投稿

4.3.0 Temporary Lookup Failureでドツボってた話

tomcat起動時の環境変数でJRE_HOMEを指定するときに

何が得られて何処へ向かうかだけを問うべき