2018-03-01

LINEでMM号と打つと、DMMからサンプル動画を送ってくるLine Botを作成しました。

前回は画像オブジェクトをメッセージとして送信したのですが、今回はテンプレートオブジェクトで、バックグラウンドがDMM APIから取得した画像、さらに共有するURLがDMMのサンプル動画のスクリプトを作成しました。





本来であれば、動画をリスト形式で送りたいのですが、念のためバックアップを取りたいので、こちらにメモしておきます。





残存TODO

- LINEで呼び出したときに、ランダム形式で取得できるようにすることで、同じキーワードでもバラエティがあるような形にする
- 複数の動画が送信できるようにする
- 人間の検索仮説、つまりそもそも検索する言葉で目的に合致した網羅性の高いコンテンツに出会うことができないので、それを手助けできるシステムを構築する




// プロパティ取得
var PROPERTIES = PropertiesService.getScriptProperties();//ファイル > プロジェクトのプロパティから設定した環境変数的なもの

//LINE・DMMの設定をプロジェクトのプロパティから取得
var LINE_ACCESS_TOKEN = PROPERTIES.getProperty('LINE_ACCESS_TOKEN')
var DMM_AFFILIATE_ID = PROPERTIES.getProperty('DMM_AFFILIATE_ID')
var DMM_API_ID = PROPERTIES.getProperty('DMM_API_ID') 
var reply_token; 
var query; //検索クエリ

//LINEのエンドポイント

var LINE_END_POINT = "https://api.line.me/v2/bot/message/reply"

//DMM・商品情報検索APIのエンドポイントに指定する値
var searchHits = 10 //検索結果のヒット数

//LINEに返すAVの数
var hits = 10
var maxLengthOfTitle = 40 //LINEに返すAVタイトルの最大値

function doGet() {
  return HtmlService.createTemplateFromFile("test").evaluate();
}


//LINEからPOSTリクエストを受けたときに起動する
function doPost(e){
  if (typeof e === "undefined"){ //デバッグのとき
    reply_token = "debug"
    query = "上原亜衣"
  } else { //POSTリクエストのとき
    var json = JSON.parse(e.postData.contents);
    reply_token= json.events[0].replyToken;
    //送られたLINEメッセージを取得
    query = json.events[0].message.text;    
  }
    Logger.log("検索キーワード:" + query)
    //DMMからキーワードで検索した結果のAVをリスト形式で取得  
    var DMMAVList = getDMMAVListByQuery(query)
    //var DMMAVList = getDMMAVListByQueryTest() //テストコード(デバッグ用)
    Logger.log("AVを取得しました")
    //AVをひとつひとつLINEに送信する
    for (var i in DMMAVList){
      Logger.log(i + "本目のAVをLINEに送信します")
      postAVToLineByAV(DMMAVList[i])
      Logger.log(DMMAVList[i] + "を送信しました")
    }
}

function getDMMAVListByQuery(query){ //検索キーワードから、DMMのAVのリストを取得
  var encoded_query = encodeURI(query); //パーセントエンコーディングを行う
  var DMM_end_point = "https://api.dmm.com/affiliate/v3/ItemList?"
     + "api_id=" + DMM_API_ID
     + "&affiliate_id=" + DMM_AFFILIATE_ID
     + "&site=DMM.R18&service=digital&floor=videoa"
     + "&hits=" + searchHits.toString()
     + "&sort=date"
     + "&keyword=" + encoded_query
     + "&output=json"
  var response = UrlFetchApp.fetch(DMM_end_point)
  var txt = response.getContentText();    
  var json = JSON.parse(txt);
  var items = json.result.items
  var list = []
  for (var i in items){
    if (i == hits){ //LINEに返すAVの指定値に達したら処理を終了する
       break;
    }
    try {  
      var photoURL = items[i].imageURL.large
      var sampleVideoUrl = items[i].sampleMovieURL.size_476_306 //サンプル動画のURLを取得
      sampleVideoUrl = sampleVideoUrl.replace(/^http?\:\/\//i, "https://");
      var title = items[i].title
      title = title.substring(0,maxLengthOfTitle)
      Logger.log(photoURL)
      Logger.log(sampleVideoUrl)
      Logger.log(title)
      var DMMAV = [sampleVideoUrl, photoURL, title]
      list.push(DMMAV)
      Logger.log(i + "本目のAVを取得しました")
    } catch (e){
        Logger.log("サンプル動画が見つかりませんでした。次のAVを取得します。")
    }
  }
  Logger.log(list.length + "本のAVを取得しました")
  return list;
}

function postAVToLineByAV(AV){

  var messages = [{
    "type": "template",
    "altText": "This is a buttons template",
    "template": {
      "type": "buttons",
      "thumbnailImageUrl": AV[1],
      "title": AV[2],
      "text": "Please select",
      "actions": [
        {
          "type": "uri",
          "label": "動画で抜く",
          "uri": AV[0]
        }
      ]
    }
  }];
  Logger.log(messages)

  /* 画像ファイルを送信する場合
  Logger.log("送信する画像: " + AV[1])
  var messages =[{
        'type': 'image', 
        'originalContentUrl': AV[1], 
        "previewImageUrl":AV[1],
      }]
  */
  //HTTP POSTリクエストをLINE BOTに送信
  UrlFetchApp.fetch(LINE_END_POINT, {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + LINE_ACCESS_TOKEN,
    },
    'method': 'post',
    'payload': JSON.stringify({
      'replyToken': reply_token,
      'messages': messages,
    }),
  });   
  return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}

注目の投稿

 PythonのTweepyを利用して、Twitter APIを利用している。 その中で、ハマったポイントをメモしておく。 まず、Searchに関して。 Twitter検索は、クライアントアプリ側では、全期間の検索が可能になっている。 一方で、APIを利用する際は、過去1週間しか...