Google App Script で、いろいろな仮想通貨取引所のAPI認証を行うまとめ

Bitflyer

function bitflyer () {
 const apiKey = '...'
 const secretKey = '...'
 const timestamp = Date.now().toString()
 const method = 'GET'
 const path ='/v1/me/getcollateral'

 const text = timestamp + method + path 
 const signature = Utilities.computeHmacSha256Signature(text, secretKey)
 const sign = signature.reduce(function(str,chr){
   chr = (chr < 0 ? chr + 256 : chr).toString(16);
   return str + (chr.length==1?'0':'') + chr;
 },'')

 const endPoint = 'https://api.bitflyer.jp'
 const url = endPoint + path 

 const options = {
   method: method,
   headers: {
     'ACCESS-KEY': apiKey,
     'ACCESS-TIMESTAMP': timestamp,
     'ACCESS-SIGN': sign,
     'Content-Type': 'application/json'
   }
 }

 const response = UrlFetchApp.fetch(url, options)
 const responseCode = response.getResponseCode()
 const responseText = response.getContentText()
 const responseData = JSON.parse(responseText)

 if (responseCode === 200 || responseCode === 404) {
   Logger.log('[SUCCESS]' + responseData)
   // スプレッドシート A2に書き込む
   writeSpreadsheet(responseData.collateral, 'A2')
 } else {
   Logger.log('[ERROR]' + responseText)
 }
}

GMOコイン

function gmo () {
 const apiKey = '...'
 const secretKey = '...'
 const timestamp = Date.now().toString()
 const method = 'GET'
 const endPoint = 'https://api.coin.z.com/private'
 const path = '/v1/account/assets'
 const url = endPoint + path
 const text = timestamp + method + path
 const signature = Utilities.computeHmacSha256Signature(text, secretKey)
 const sign = signature.reduce(function(str,chr){
   chr = (chr < 0 ? chr + 256 : chr).toString(16);
   return str + (chr.length==1?'0':'') + chr;
 },'')

 const options = {
   method: method,
   headers: {
     'API-KEY': apiKey,
     'API-TIMESTAMP': timestamp,
     'API-SIGN': sign
   }
 }

 const response = UrlFetchApp.fetch(url, options)
 const responseCode = response.getResponseCode()
 const responseText = response.getContentText()
 const responseData = JSON.parse(responseText)

 if (responseCode === 200 || responseCode === 404) {
   Logger.log('[SUCCESS!] ' + responseData)
   writeSpreadsheet(responseData.data[0].amount, 'B2')
 } else {
   Logger.log('[ERROR] ' + responseText)
 }
}

Liquid

function liquid () {
 const tokenId = '...'
 const userSecret = '...'
 const endPoint = 'https://api.liquid.com'
 const path = '/fiat_accounts'
 const url = endPoint + path

 const payload = {
   path: path,
   nonce: Date.now().toString(),
   token_id: tokenId
 }

 const signature = encodeJWT(userSecret, payload)

 const options = {
   headers: {
     'X-Quoine-API-Version': '2',
     'X-Quoine-Auth': signature,
     'Content-Type': 'application/json'
   }
 }

 const response = UrlFetchApp.fetch(url, options)
 const responseCode = response.getResponseCode()
 const responseText = response.getContentText()
 const responseData = JSON.parse(responseText)

 if (responseCode === 200 || responseCode === 404) {
   Logger.log('[SUCCESS] ' + responseData)
   writeSpreadsheet(responseData[1].balance, 'C2')
 } else {
   Logger.log('[ERROR] ' + responseText)
 }
}

/**
* Encode JWT
* @param {String} secret
* @param {Object} payload
* @see https://wtfruby.com/gas/2018/11/21/jwt-app-scripts.html
*/
function encodeJWT (secret, payload) {
 var header = JSON.stringify({
   typ: 'JWT',
   alg: 'HS256'
 })
 
 var encodedHeader = base64Encode(header)
 var encodedPayload = base64Encode(JSON.stringify(payload))
 var toSign = [encodedHeader, encodedPayload].join('.')
 var signature = Utilities.computeHmacSha256Signature(toSign, secret)
 var encodedSignature = base64Encode(signature)

 return [toSign, encodedSignature].join('.')
}

/**
* base64 Encode
* @param {String} str
*/
function base64Encode (str) {
 var encoded = Utilities.base64EncodeWebSafe(str)
 return encoded.replace(/=+$/, '')
}

Zaif

function zaif () {
 const apiKey = '...'
 const secretKey = '...'
 const endPoint = 'https://api.zaif.jp/tapi'
 const url = endPoint 
 const method = 'POST'
 const timestamp = (new Date().getTime() / 1000).toFixed(0)

 const signature = 'method=get_info&nonce=' + timestamp
 const sign = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512, signature, secretKey)

 const options = {
   method: method,
   payload: signature,
   headers: {
     'sign': to_bytehex(sign),
     'key': apiKey,
     'Content-Type': 'application/x-www-form-urlencoded',
   }
 }

 const response = UrlFetchApp.fetch(url, options)
 const responseCode = response.getResponseCode()
 const responseText = response.getContentText()
 const responseData = JSON.parse(responseText)

 if (responseCode === 200 || responseCode === 404) {
   Logger.log('[SUCCESS] ' + responseData)
   writeSpreadsheet(responseData.return.funds.jpy, 'D2')
 } else {
   Logger.log('[ERROR] ' + responseText)
 }
}

function to_bytehex (data) {
   return data.map(function(e) {
   var v = (e < 0 ? e + 256 : e).toString(16)
   return ('00' + v).slice(-2)
 }).join("")
}

Coincheck

function coincheck () {
 const apiKey = '...'
 const secretKey = '...'

 const endPoint = 'https://coincheck.com'
 const path = '/api/accounts/balance'
 const url = endPoint + path 
 const method = 'GET'
 const timestamp = Date.now().toString()
 const text = timestamp + url 

 const signature = Utilities.computeHmacSha256Signature(text, secretKey)
 const sign = signature.reduce(function(str,chr){
   chr = (chr < 0 ? chr + 256 : chr).toString(16);
   return str + (chr.length==1?'0':'') + chr;
 },'')

 const options = {
   method: method,
   headers: {
     'ACCESS-KEY': apiKey,
     'ACCESS-NONCE': timestamp,
     'ACCESS-SIGNATURE': sign
   }
 }

 const response = UrlFetchApp.fetch(url, options)
 const responseCode = response.getResponseCode()
 const responseText = response.getContentText()
 const responseData = JSON.parse(responseText)

 if (responseCode === 200 || responseCode === 404) {
   Logger.log('[SUCCESS] ' + responseData)
   writeSpreadsheet(responseData.jpy, 'E2')
 } else {
   Logger.log('[ERROR]')
 }
}

Bybit

function bybit () {
 const apiKey = '...'
 const secretKey = '...'
 const timestamp = Date.now()
 const method = 'GET'
 const coin = 'BTC'
 const path ='/v2/private/wallet/balance'
 const options = {
   timestamp: timestamp,
   coin: coin,
   api_key: apiKey,
 }

 const sign = getSignature(options, secretKey)
 options.sign = sign

 const endPoint = 'https://api.bybit.com'
 const url = endPoint + path + `?api_key=${apiKey}&coin=BTC&timestamp=${timestamp}&sign=${sign}`

 const response = UrlFetchApp.fetch(url)
 const responseCode = response.getResponseCode()
 const responseText = response.getContentText()
 const responseData = JSON.parse(responseText)

 if (responseCode === 200 || responseCode === 404) {
   Logger.log('[SUCCESS]' + responseData)

   if (responseData.result &&  responseData.result[coin]) {
     writeSpreadsheet(responseData.result[coin].wallet_balance, 'F2')
   }
   
 } else {
   Logger.log('[ERROR]')
 }
}

function getSignature (parameters, secret) {
 var orderedParams = "";
 Object.keys(parameters).sort().forEach(function(key) {
  orderedParams += key + "=" + parameters[key] + "&";
 });
 orderedParams = orderedParams.substring(0, orderedParams.length - 1);
 signature = Utilities.computeHmacSha256Signature(orderedParams, secret);
 return to_bytehex(signature)
}

function to_bytehex (data) {
 return data.map(function(e) {
 var v = (e < 0 ? e + 256 : e).toString(16)
  return ('00' + v).slice(-2)
 }).join("")
}

FTX

function ftx () {
 const apiKey = '...'
 const secretKey = '...'
 const timestamp = Date.now().toString()
 const method = 'GET'
 const endpoint = 'https://ftx.com'
 const path ='/api/account'
 const url = endpoint + path
 const body = null
 const subaccount = null

 const payload = timestamp + method + path + (body && method === 'POST' ? body : '')
 const signature = Utilities.computeHmacSha256Signature(payload, secretKey)
 const sign = to_bytehex(signature)

 const options = {
   method: method,
   headers: {
     'FTX-KEY': apiKey,
     'FTX-SIGN': sign,
     'FTX-TS': timestamp
   }
 }

 if (subaccount) {
   options.headers['FTX-SUBACCOUNT'] = subaccount
 }

 const response = UrlFetchApp.fetch(url, options)  
 const responseCode = response.getResponseCode()
 const responseText = response.getContentText()
 const responseData = JSON.parse(responseText)

 if (responseCode === 200 || responseCode === 404) {
   Logger.log('[SUCCESS]')
   Logger.log(JSON.stringify(responseData))

   if (responseData.result) {
     writeSpreadsheet(responseData.result.collateral, 'G2')
     Logger.log(responseData.result.collateral)
   } else {
     writeSpreadsheet('Null', 'G2')
   }
   
 } else {
   Logger.log('[ERROR]' + responseText)
 }
}

スプレッドシート に書き込む

今回は口座残高をスプレッドシートに書き込みました。

function writeSpreadsheet (data, cell) {
 const sheetName = 'シート1'
 const sheet = SpreadsheetApp.getActive().getSheetByName(sheetName)
 sheet.getRange(cell).setValue(data)
}

手間を惜しまないならただ書き込むだけでなく、行が追加されるようにして過去のデータが蓄積されるようにするとよさそう。

定期的に更新されるように

Google App Script のトリガー設定で、イベントを時間主導型30分おきなどに設定して定期的に更新されるようにする。

この記事が気に入ったらサポートをしてみませんか?