こんなもの作って遊んでみました↓
SendGrid Parse Webhook with voicetext4j - YouTube
受信したメール内容を音声で読み上げるだけなんですが(^^;
先日のJJUGで@makingさんがLTで紹介されたVoiceText Web APIと、それを簡単にJavaで使えるvoicetext4jライブラリが印象的で、色々遊べそうだよなぁと。
で、SendGridが提供しているParse Webhook使ったら面白そうかなぁと。
単純にPOSTされたメール内容をvoicetext4jで読み上げるだけなのですが(^^;
ちなみにSendGridのParse Webhookについては以下に詳細がのってます。
Parse Webhookテクニカルガイド【入門】 | ブログ | SendGrid
POST先のサーバどうしよう…と思ったら、上記の記事で自分のローカルにトンネルする方法まで書いてあった(^^;;
ということで、ngrok使ってみました。
ngrok - secure introspectable tunnels to localhost
サーバはJava EE使うまでもない…ということで、Spark使いました(^^;
Sparkは前にちょっとだけ試してました。
Java 8でSpark 2.0.0が楽しそう - Challenge Java EE !
コードはかなりテキトー(^^; StreamAPI使って綺麗に書きたかったけど、リファクタは後で…。
package jp.co.sample.voicereadingfrommail;
import am.ik.voicetext4j.EmotionalSpeaker;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;
import static spark.Spark.*;
SendGrid Parse Webhookでpostしてメール内容を音声読み上げする.
@author
public class App {
public static void main(String[] args) {
System.setProperty("voicetext.apikey", "****************");
setPort(8080);
post("/", "plain/text", (req, res) -> {
ServletFileUpload parse = new ServletFileUpload();
FileItemIterator itm;
try {
itm = parse.getItemIterator(req.raw());
while(itm.hasNext()){
FileItemStream stream = itm.next();
if(stream.isFormField()){
String str = Streams.asString(stream.openStream(), "iso-2022-jp");
if(stream.getFieldName().equals(("text"))){
EmotionalSpeaker.HARUKA.ready()
.pitch(100)
.speed(100)
.happy()
.speak(str);
}
}
}
} catch (FileUploadException | IOException ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}
return req.body();
});
}
}
SendGridのブログではPOSTされるデータがJSONぽく書いてありますが、実際にはファイルアップロードなどでformをPOSTするときのmultipart/form-dataの形式でデータが来ました。
なのでサンプルではApache Commons Uploadを使ってます(^^;