GCP の Vision AI を試してみた🐻🐰

# はじめに
LINEbotで、ドイツ語から英語と日本語への翻訳ボットを以前に作りました。
次は、ドイツ料理とかドイツの建築物の写真から、それが一体何なのか情報を気軽に取れたらいいなと感じています。GoogleさんのAIの力をお借りしてつくってみます。

◆YouTubeでの解説↓
https://youtu.be/u_NcB1rtsPU

## 今回使うURLたち
◆ドイツ語から英語と日本語への翻訳ボット(この続きです)
https://zenn.dev/njn0te/articles/a6c0d8640cdede

◆Google Cloud Vision API (Vision AI)
https://cloud.google.com/vision

◆LINE Developers
https://developers.line.biz/

# GCPの下準備
まずはGoogle Cloud Platformにアクセスしてください。
https://console.cloud.google.com/

左上の「ナビゲーション メニュー」から「API とサービス」の「ライブラリ」を選択。
![スクリーンショット 2022-02-25 5.43.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216701/09779459-6ed5-e21d-8cb9-12ad92d79cdb.png)

ライブラリの中から「Cloud Vision API」を見つけて、有効にしてください。
![スクリーンショット 2022-02-25 5.45.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216701/c5d5a396-97a1-2fa3-12b1-5830810c3b11.png)
※1000回のアクセスまで無料

もう一度、「ナビゲーション メニュー」から「API とサービス」の「認証情報」を選択。
![スクリーンショット 2022-02-25 5.48.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216701/bb323eec-f5c4-5d7b-ae13-4c21ba46d655.png)

「認証情報を作成」から「APIを作成」を押して、キーを下記のプログラムにコピペして使います。
※本番環境での不正利用を回避するため、「Cloud Vision API」にチェックを入れてキーを制限してください。
![スクリーンショット 2022-02-25 5.54.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216701/37e9170f-0ee8-3bb1-c585-eee29a973661.png)

# プログラム
'*************'の部分を適切な値にしてご利用ください。
```js:コード.gs
// 応答メッセージURL
const REPLY = "https://api.line.me/v2/bot/message/reply";

// アクセストークン
const ACCESS_TOKEN = '*************';

// スプレッドシート情報
const SHEET_ID   = '*************';
const SHEET_URL  = 'https://docs.google.com/spreadsheets/d/*************/edit#gid=0';
const SHEET_LOG = SpreadsheetApp.openById(SHEET_ID).getSheetByName('検索履歴');

// VISION AI で Googleドライブにアクセス
const GOOGLE_DRIVE_ID = '*************';
const CLOUD_VISION_API_KEY = '*************';

function doPost(e) {

  //メッセージ受信
  const data = JSON.parse(e.postData.contents).events[0];
  //ユーザーID取得
  const lineUserId = data.source.userId;
  // リプレイトークン取得
  const replyToken = data.replyToken;
  // 送信されたメッセージの種類を取得
  const postType = data.message.type;
  // 送信されたメッセージ取得
  const postMsg = data.message.text;
  // LINEに送信
  let replyMsg;
  if ( "image" === postType ) {
    replyMsg = LanguageApp.translate(imageSave(replyToken, lineUserId, data), 'en','ja');
  } else {
    // 翻訳
    const lang = 'de';
    const englishMsg = LanguageApp.translate(postMsg, lang,'en');
    const japaneseMsg = LanguageApp.translate(postMsg, lang,'ja');
    const franceMsg = LanguageApp.translate(postMsg, lang,'fr');
    // 検索履歴にユーザーID、原文、翻訳（英語・日本語）、日時を記載
    debugLog(lineUserId, postMsg, englishMsg, japaneseMsg, franceMsg);
    replyMsg = `EN: ${englishMsg}\nJA: ${japaneseMsg}\nFR: ${franceMsg}`
  }
  sendMessage(replyToken, replyMsg);
  
}

function imageSave(replyToken, lineUserId, data) {

  const IMG_DATA = getImg(data);　// LINEから画像取得
  const IMG_INFO = saveImg(IMG_DATA, lineUserId);　// Googleドライブに保存
  const ANA_MSG = analyseMsg(IMG_INFO.encodedFile); // 解析

  return ANA_MSG;

}

function getImg(data) {

  const IMG_URL = 'https://api-data.line.me/v2/bot/message/' + data.message.id + '/content';
  const HEAD = {
    "method":"get",
    "headers": {
      "Authorization" : "Bearer " + ACCESS_TOKEN
    }
  }
  const IMG_DATA = UrlFetchApp.fetch(IMG_URL, HEAD);
  return IMG_DATA;

}

function saveImg(imgBinary, lineUserId){

  const FOLDER = DriveApp.getFolderById(GOOGLE_DRIVE_ID);
  const FILE_NAME = Math.random().toString(36).slice(-8);
  const IMAGE_FILE = FOLDER.createFile(imgBinary.getBlob().setName(FILE_NAME));
  
  const IMAGE_URL = 'https://drive.google.com/uc?export=view&id=' + IMAGE_FILE.getId();
  const FETCH_IMG = Utilities.base64Encode(UrlFetchApp.fetch(IMAGE_URL).getContent());

  IMAGE_FILE.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);

  const IMG_INFO = {
    folder : FOLDER,
    file : IMAGE_FILE,
    encodedFile : FETCH_IMG
  }

  return IMG_INFO;

}

function analyseMsg(contents) {
  
  const URL = `https://vision.googleapis.com/v1/images:annotate?key=${CLOUD_VISION_API_KEY}`;// ウェブ エンティティおよびページの検出
  
  const BODY = {
    "requests":[
      {
        "image": {
          "content": contents
        },
        "features":[
          {
            "type":"WEB_DETECTION",
          }
        ]
      }
    ]
  };
  const HEAD = {
    "method":"post",
    "contentType":"application/json",
    "payload":JSON.stringify(BODY),
    "muteHttpExceptions": true
  };
  
  let response = UrlFetchApp.fetch(URL, HEAD);
  let description = '';
  // 画像検出
  if(JSON.parse(response).responses[0].webDetection) {  
    if (JSON.parse(response).responses[0].webDetection.hasOwnProperty('webEntities')){
      let x = JSON.parse(response).responses[0].webDetection.webEntities.length;
      for (  let i = 0;  i < x;  i++  ) {
        const Entities = JSON.parse(response).responses[0].webDetection.webEntities[i].description;
        const EntScore = JSON.parse(response).responses[0].webDetection.webEntities[i].score;
        
        if (Entities != null && EntScore > 0.5) {
          description += "・" + Entities + "\n";
        }
      }
      if(description == ""){
        description = "関連性が薄い情報のみです";
      }
    }else{
      description = "情報がありません。";
    }
    
  }
  console.log(description)
  return description;
  
}

function debugLog(userId, text, eng, jap, fra) {
  const date = Utilities.formatDate( new Date(), 'Asia/Tokyo', 'yyyy-MM-dd HH:mm:ss');
  SHEET_LOG.appendRow([userId, text, eng, jap, fra, date]);
}

function sendMessage(replyToken, replyText) {
  const postData = {
    "replyToken" : replyToken,
    "messages" : [
      {
        "type" : "text",
        "text" : replyText
      }
    ]
  };
  const headers = {
    "Content-Type" : "application/json; charset=UTF-8",
    "Authorization" : "Bearer " + ACCESS_TOKEN
  };
  const options = {
    "method" : "POST",
    "headers" : headers,
    "payload" : JSON.stringify(postData)
  };
  return UrlFetchApp.fetch(REPLY, options);
}

```

# 完成したLINE BOT
気ままに新機能は追加していく気がするので、もし良ければ友達追加してね🐻🐰
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216701/bdcfe6ef-72ca-769b-a308-09a0c76ff19a.png)