【AWS】bitflyer注文一覧取得

【きっかけ】

過去の記事参照
 
buffalokusojima.hatenablog.com


1. 使用するサービス

(AWS)

  • Lambda
  • IAM

(外部サービス)

bitflyer Lightning API


2. 概要

Lambdaを使用して、bitflyerから注文一覧を取得します。通常注文と特殊注文で叩くAPIのパスが異なるので、2回叩き、両方とも取得します。
API Gatewayに紐付けてブラウザ形式でAPIを叩くことが出来ます。詳細は前回記事参照
buffalokusojima.hatenablog.com


3. 実装
以下、Lambda実装

const ssm = new (require('aws-sdk/clients/ssm'))();
const request = require('request');
const crypto = require('crypto');

exports.handler = (event, context, callback) => {
    
    var apikey;
    var sercretKey;
    var returnData;
    
    // bitflyerのAPIKeyを取得(パラメータストアに事前登録必要)
    getParameterFromSystemManager('bitflyer-keys',callback)
    .then(function(data){
       
        apikey = data.split(",")[0];
        sercretKey = data.split(",")[1];
        
        var timestamp = Date.now().toString();
        var method = 'GET';
        var path = '/v1/me/getparentorders?product_code=FX_BTC_JPY&parent_order_state=ACTIVE';
        
        var text = timestamp + method + path;
        var sign = crypto.createHmac('sha256', sercretKey).update(text).digest('hex');
        
        var option = {
          url: 'https://api.bitflyer.jp' + path,
          method: method,
          headers: {
            'ACCESS-KEY': apikey,
            'ACCESS-TIMESTAMP': timestamp,
            'ACCESS-SIGN': sign,
            'Content-Type': 'application/json'
            }
        }
        // 特殊注文取得
        return sendRequest(option, callback);
    }).then(function(data){
        
        if(data.response.statusCode != 200){
          console.error("Error:",data.response);
          callback(null, {
            statusCode: data.response.statusCode,
            body: JSON.stringify({message: data.response}),
            headers: {"Content-type": "application/json"}
          });
          return;
        }
        
        data = JSON.parse(data.body);
       
        console.log(data)
        
        // global変数に特殊注文を保持
        returnData = data;
        
        var timestamp = Date.now().toString();
        var method = 'GET';
        var path = '/v1/me/getchildorders?product_code=FX_BTC_JPY&child_order_state=ACTIVE';
        
        var text = timestamp + method + path;
        var sign = crypto.createHmac('sha256', sercretKey).update(text).digest('hex');
        
        var option = {
          url: 'https://api.bitflyer.jp' + path,
          method: method,
          headers: {
            'ACCESS-KEY': apikey,
            'ACCESS-TIMESTAMP': timestamp,
            'ACCESS-SIGN': sign,
            'Content-Type': 'application/json'
            }
        }
        
        // 通常注文取得
        return sendRequest(option, callback);
    }).then(function(data){
        
        if(data.response.statusCode != 200){
          console.error("Error:",data.response);
          callback(null, {
            statusCode: data.response.statusCode,
            body: JSON.stringify({message: data.response}),
            headers: {"Content-type": "application/json"}
          });
          return;
        }
        
        data = JSON.parse(data.body);
        
        console.log(data)
       
        // 特殊注文と通常注文を結合
        returnData = returnData.concat(data)

        if(returnData.length == 0){
            console.log('No data Found');
            callback(null,{
                statusCode: 200,
                body: JSON.stringify({message: 'No data Found'}),
                headers: {"Content-type": "application/json"}
            });
            return;
        }
        callback(null, {
            statusCode: 200,
            body: JSON.stringify({data: returnData}),
            headers: {"Content-type": "application/json"}
        });
        return;
    });
   
    function getParameterFromSystemManager(apikey_name, callback) {
    
        return new Promise(function (resolve) {
            var apikey = process.env[apikey_name];
            
            if(!apikey || typeof apikey == undefined){
            
                // Fetches a parameter called REPO_NAME from SSM parameter store.
                // Requires a policy for SSM:GetParameter on the parameter being read.
                var params = {
                    Name: apikey_name,
                    /* required */
                    WithDecryption:true
                };
                
                ssm.getParameter(params, function(err, apikey) {
                    if (err){
                        console.error(err.stack);
                        callback(null,{
                            statusCode: 500,
                            body: JSON.stringify({message: err.toString()}),
                            headers: {"Content-type": "application/json"}
                        });
                        resolve(null);
                        return;
                    }
                    process.env[apikey_name] = apikey.Parameter.Value;
                    resolve(apikey.Parameter.Value);
                });
            }else resolve(apikey);
        });
    }
    
    
    function sendRequest(option, callback){
        
        return new Promise(function (resolve) {
            request(option, function(error, response, body){
                    
                    if(error){
                        console.error(error);
                        callback(null,{
                            statusCode: 500,
                            body: JSON.stringify({message: error.toString()}),
                            headers: {"Content-type": "application/json"}
                        });
                        resolve(null);
                    }
                    var data = {response, body}
                    resolve(data);
            });
            });
    }
};

SSMのパラメータストアへのAPIキー登録方法やその他実装方法の説明については過去記事参照
buffalokusojima.hatenablog.com

4. 以上で簡単にbitflyerから注文一覧を取得出来ます。次回はフロントエンド側の注文表示をやっていきたいと思います。