概要
先日、画像を送ると文字に起こしてくれるLINEbotを作成して便利に使っていたんだけど、ついでに翻訳してくれたらなぁ~ってのが今回。
Qiita記事:【GAS】画像を送ると文字に起こすLINEbot【OCR】
上記リンク先で紹介したコードに少し足したら作れたので、追記部分を紹介するのがこの記事。
実行結果
画像送信
↓
文字起こし
↓
言語コード送信※
↓ ↑
翻訳(繰り返しOK)
LINEbotで画像から文字起こしするたびにスプレッドシートに起こした文字が記録され、言語コードを受け取ると記録された文字を翻訳する設計。
※Googleの翻訳機能でサポートされてる言語は何でも行けるようにしてみた^^)b
Translation API:言語サポート
そんなわけで、洋酒のラベルをLINEbotに送信。
ここまでは前と同じ。文字起こしされても私には読めない^^;
と言うことで、日本語(言語コード:ja)に翻訳!
なんかちょっと変だけど、翻訳精度はGoogle翻訳に依存。
マラヤーラム文字(ml)
もちろん韓国語やマラヤーラム文字が読めるわけではない( ´_ゝ`)デザインがクール
コード
全文掲載。追加したのは4ヶ所(量は少し)、コード内で軽く触れつつ後程説明。その他の部分の説明は前の記事を参照。
var TOKEN = "xxxxxxxxxxxxxxxxxxxx";
var replyURL = "https://api.line.me/v2/bot/message/reply";
//追加コード①:スプレッドシートを定義
var sheet = SpreadsheetApp.openById('シートID').getSheetByName('シート名');
function doPost(event) {
var json = JSON.parse(event.postData.contents);
var replyToken = json.events[0].replyToken;
var type = json.events[0].message.type;
var messageId = json.events[0].message.id;
//追加コード②:メッセージがテキストだった場合
if (type === "text"){
//言語コードを受け取るためにメッセージを取得
var userMessage = json.events[0].message.text;
//A1セルを取得(文字起こし前なら空欄)
var origText = sheet.getRange('A1').getValue();
//A1セルが空欄でなければ翻訳する ※追加コード④へ
if(origText){
translationText(userMessage, origText, replyToken);
}
}
if (type !== "image"){
replyBot(replyToken);
return;
}
var imageURL = "https://api-data.line.me/v2/bot/message/" + messageId + "/content";
var image = getImage(imageURL);
//var folder = DriveApp.getFolderById("1gTJgvoX5ldwB69oPRelKEY-89dxGa_Ru");
//folder.createFile(image);
var ocrText = getText(image);
//追加コード③:起こした文字を記録
sheet.getRange('A1').setValue(ocrText);
replyText(ocrText,replyToken);
}
//追加コード④:翻訳してLINEで返信
function translationText(lang, origText, replyToken) {
//ターゲット言語が無効の場合return
try{
var transText = LanguageApp.translate(origText, "", lang);
}catch(e){
return;
}
//メッセージ作成・送信
var payload = JSON.stringify({
"replyToken": replyToken,
"messages": [{
"type": "text",
"text": transText
}]
});
UrlFetchApp.fetch(replyURL, {
"headers": {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": "Bearer " + TOKEN,
},
"method": "post",
"payload": payload
});
return;
}
//画像でも翻訳リクエストでもない場合 画像を求めるメッセージを返す
//出来心で少し改変したので後程説明
function replyBot(replyToken) {
var title = '画像を送ってね';
var text = '画像を送ると文字に起こすよ。\n翻訳するには文字起こし後に言語コードを送信。';
var payload = JSON.stringify({
"replyToken": replyToken,
"messages": [{
"type": "template",
"altText": "ヒント",
"template": {
"type": "buttons",
"title": title,
"text": text,
"actions": [
{
"type": "uri",
"label": "カメラを起動する",
"uri":"https://line.me/R/nv/camera/",
},
{
"type": "uri",
"label": "画像を選択する",
"uri":"https://line.me/R/nv/cameraRoll/single",
},
{
"type": "uri",
"label": "サポート言語を見る",
"uri":"https://cloud.google.com/translate/docs/languages",
}
]
}
}]
});
UrlFetchApp.fetch(replyURL, {
"headers": {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": "Bearer " + TOKEN,
},
"method": "post",
"payload": payload
});
return;
}
//投稿から画像を取得(変更無し)
function getImage(imageURL) {
var image = UrlFetchApp.fetch(imageURL, {
"headers": {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": "Bearer " + TOKEN,
},
"method": "get"
}).getBlob();
return image;
}
//画像を文字に起こす(変更無し)
function getText(image) {
var title = image.getName();
var mimeType = image.getContentType();
var resource = {title: title, mimeType: mimeType};
var fileId = Drive.Files.insert(resource, image, {ocr: true}).id;
var document = DocumentApp.openById(fileId);
var ocrText = document.getBody().getText().replace("\n", "");
Drive.Files.remove(fileId);
return ocrText;
}
//起こした文字をLINEで返信(変更無し)
function replyText(ocrText,replyToken) {
var replyURL = "https://api.line.me/v2/bot/message/reply";
var payload = JSON.stringify({
"replyToken": replyToken,
"messages": [{
"type": "text",
"text": ocrText
}]
});
UrlFetchApp.fetch(replyURL, {
"headers": {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": "Bearer " + TOKEN,
},
"method": "post",
"payload": payload
});
return;
}
解説
まずは追加コード①でスプレッドシートを定義。
前のコードではテキスト判定は行わなかったけど、今回は「追加コード②」でテキスト判定を行っている。テキストでなく画像であれば文字起こし→「追加コード③」でスプレッドシートへ記録。
テキストメッセージが送られてきたら、それをA1セルの文字と一緒に「追加コード④」へ送る。「追加コード④」では、テキストメッセージを言語コードとして.translate
メソッドでA1セルを翻訳。(翻訳前の言語を指定する部分を空欄にしているので、言語は自動で判定。)
翻訳先の言語コードがサポートされていないコードや関係ないテキストだった場合、通常ならエラーになってスクリプトが停止してしまうけどtry...catch
文で停止回避、翻訳エラーの場合はreturnさせる。
これでサポートされている言語を全部使える^^
returnされたのであれば、メッセージタイプは画像ではないので画像を求めるメッセージを返す。
前のままでも使えたけど、カメラ起動・カメラロール・言語サポートリンクのボタンテンプレートを返すようにした。