LANG SELRCT

コードを書く場所についてはこちら

2019年3月3日日曜日

LambdaでSlackのchannels.historyを取得してみる(hostとpathもpayloadで渡す)


AWS LambdaでSlackのchannels.historyを取得してみる(テスト用)では、Lambdaの環境変数にSlackのAPI Tokenを入れました。

今回はGASからSlackのAPI Tokenを渡して
API GatewayのSecurityを「Open with API key」にして
そのAPI KeyもGASから渡すコードに書き換えてみます。


以下の方法の合わせ技です

API GatewayとLambdaを作る方法

API GatewayのSecurityを「Open with API key」にする方法

API GatewayにGASからPayloadでデータを渡す方法


Google Apps Script側のコード

このコードの要約
API Gateway の endpoint の API Key を options の headers に入れて
payload の中に host と path を入れて
path のパラメータに channel_id, latest, inclusive, count, slack_token を入れて
UrlFetchApp.fetch(url, options) で endpoint の url に options を渡す。


コード.gs
var url = 'https://API_ID.execute-api.us-east-1.amazonaws.com/default/FUNCTION_NAME';//API Gatewayのendpoint
var channel_id = 'ID';//SlackのChannel ID
var oldest = getUnixTime("2019/02/14 13:26:12");//この日時から
var latest = getUnixTime("2019/02/23 22:17:12");//この日時まで
var inclusive = true;//それらの日時を含める(true)か否(false)か
var count = 2;//取得する件数

function run() {
  var payload = getPayload();
  var options = getOpen(payload);
  var response = UrlFetchApp.fetch(url, options);
  var jobj = JSON.parse(response);
  Logger.log(jobj);
}
  
function getPayload() {
  var payload = {
    'data':{
    'host': 'slack.com',
    'path': '/api/channels.history' + getParams()
   }
  }
  var json = JSON.stringify(payload);
  return json;
}

function getParams() {
  var params = '?channel=' + channel_id +
              '&latest=' + latest +
              '&inclusive=' + inclusive +
              '&count=' + count +
              '&token=' + getProp('slack_token');
  return params;
}

function getOpen(payload) {
  var options = {
    'method': 'post',
    'contentType': 'application/json',
    'headers': get_headers(),
    'payload': payload
  }
  return options;
}

function get_headers() {
  var headers = {
    "x-api-key": getProp('apigateway_key')
  }
  return headers;
}

function getProp(key) {
  return PropertiesService.getScriptProperties().getProperty(key);
}

function getUnixTime(dateTime) {
  var date = new Date(dateTime);
  var milsec = date.getTime();
  var sec = milsec / 1000;
  var time = sec.toString();
  return time;
}



Lambda側のコード

このコードの要約
host と path を event['body'] からで受け取ってそのAPIをたたいた結果を返す。
LambdaのFunction側には何一つ固有の情報を持たせていないため、Slack用ですらない空っぽのライブラリ的なコード。


index.js
var https = require('https');
var host;
var path;

exports.handler = async function(event) {
  var body = event['body'];
  var jobj = JSON.parse(body);
  var data = jobj['data'];
  host = data['host'];
  path = data['path'];
  var results = await getData(); //getData()の処理が終わってから次の処理を実行する
  var json = returnJson(results);
  return json;
};

//Promise
function getData() {
  return new Promise(resolveFunc);
}

//Promise resolved
function resolveFunc(arg) {
  https.get(getOptions(), function(res) {
    var body = '';
    res.setEncoding('utf8');
    res.on('data', function(chunk) {
      body += chunk;
    });
    res.on('end', function(chunk) {
      arg(body);
    });
    res.on('error', function(e) {
      console.log(e.message);
      arg(e.message);
    });
  });
  //ここまでの処理をPromiseでやりたい
}

function getOptions() {
  var options = {
    'method': 'post',
    'host': host,
    'path': path
  };
  return options;
}

//JSONを返す
function returnJson(results) {
  const response = {
    body: results,
  };
  console.log(JSON.parse(results));
  return response;
}