Google Spread Sheetsで為替情報を取得し、Lineでアラートを通知する

はじめに

今回は「AWSLambdaでLine通知を実装する」と「Google Spread Sheetsで為替情報を取得し、Pythonで使用する」の続編的な内容となっています。

上記2つの記事ではそれぞれ以下の内容を挙げているので、不明な箇所がある場合には参照いただければと思います。

AWSLambdaでLine通知を実装するLine Developerで提供されるLine APIをAWS Lambdaから叩くことで為替レートが一定の閾値を超えたときにLineに通知する方法を紹介。
Google Spread Sheetsで為替情報を取得し、Pythonで使用するGoogle Spread SheetsのGoogleFinance関数を用いて為替レートを取得しPythonで操作する方法を紹介。

本記事では、上記を踏まえて、Google Spread Sheetsの為替情報をAWS Lambdaから定期的に参照し、あらかじめ設定した閾値を超えた際にLineに通知する方法を紹介します。下記は割愛しているので、過去の記事を参照してください。

  • Line APIの開始方法とPythonからの使用方法
  • Google Spread SheetsのPythonからの使用方法

Cloud9でLambda Functionを用意する

AWS Cloud9でPythonのLambda Functionを作成する。操作の詳細は前回(Cloud 9 + lambdaでbot作成)触れているので今回は割愛する。

Pythonライブラリのインストール

ライブラリとして「gspread」、「oauth2client」のインストールが必要となる。そのため下記の通りインストールする。

PythonライブラリのインストールはLambda Functionを自動作成した際に作成されたディレクトリに移動してから実行する。(例:Lambda Functionを「FXAlart」として作成している場合)

$ cd ./FXAlart
$ python -m pip install --target=./ gspread
$ python -m pip install --target=./ oauth2client

Google Spread Sheetsアクセスへの準備

Google Spread SheetsをPythonで使うために、前回キー情報(jsonファイル)を入手してる。今回も同様のキー(jsonファイル)を使用するため、Lambda Functionを自動作成した際に作成されたディレクトリにアップロードしておく。

また、スプレッドシートについても前回の通り、下記の内容で用意している。

閾値を設定して監視したい通貨ペアはAUDNZDとEURGBPのみであれば、上記の通り該当する通貨ペアのminとmaxだけ値を入れているものとする。

Lambda Functionの記載

ここではLambdaのソースコード(lambda_function.py)の中身のみ記載する。Lambdaの記載方法などが分からない方は、Lambdaは個人開発でコストを圧縮したいときには必ず必要な技術だと考えるため、興味がある方は勉強してみてほしい。

ただ、Cloud9にてLambda Functionを自動作成した際にlambda_function.pyも作成されていると思うので、下記コードをコピペしてもらえれば使用可能である。

import urllib.request
import urllib.parse
import json
import gspread
from oauth2client.service_account import ServiceAccountCredentials

#Google Spread Sheetsを定義
ACCESS_KEY_JSON = "XXXXXXXX.json"
SPREAD_SHEET_KEY = "XXXXXXXXXXXXXX"

#Google Spread Sheetsを開く
credentials = ServiceAccountCredentials.from_json_keyfile_name(ACCESS_KEY_JSON, ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive'])
worksheet = gspread.authorize(credentials).open_by_key(SPREAD_SHEET_KEY).sheet1

#Line APIを定義
lineUserId="XXXXXXXXXX"
lineAccessToken="XXXXXXXXXXXX"

#Line通知関数を定義
def line_push(lineAccessToken, lineUserId, text):
    url = 'https://api.line.me/v2/bot/message/push'
    data = {
        "to": lineUserId,
	    "messages":[
            {
                "type":"text",
                "text":text
            }
        ]
    }
    headers = {
        'Content-Type': 'application/json',
	    'Authorization': 'Bearer {'+lineAccessToken+'}',
    }
    req = urllib.request.Request(url, json.dumps(data).encode(), headers)
    urllib.request.urlopen(req)

def lambda_handler(event, context):
    # FXアラートのMain処理を実行
    pairs = worksheet.col_values(2)
    del pairs[0]
    for pair in pairs:
        cell_list = worksheet.row_values(worksheet.find(pair).row)
        if len(cell_list)>3:
            if cell_list[3]!="":
                if float(cell_list[2]) < float(cell_list[3]):
                    body = pair+"が【"+cell_list[3]+"】を下まわりました。"
                    line_push(lineAccessToken, lineUserId, body)
                    body = pair+"は現在【"+cell_list[2]+"】です。"
                    line_push(lineAccessToken, lineUserId, body)
        if len(cell_list)>4:
            if cell_list[4]!="":
                if float(cell_list[2]) > float(cell_list[4]):
                    body = pair+"が【"+cell_list[4]+"】を上まわりました。"
                    line_push(lineAccessToken, lineUserId, body)
                    body = pair+"は現在【"+cell_list[2]+"】です。"
                    line_push(lineAccessToken, lineUserId, body)            
    return ''

コード解説

AWS Lambdaで実行されるlambda_handler(event, context)関数の中身に触れていく。

まず、pairsというリストにスプレッドシートのB列に表記されている通貨ペアを取得する。取得方法は下記の通り。

このようにして用意した通貨ペアリストをForループで回して、一つずつ閾値を超えていないか検証する。

また、自身の認証情報に書き換えが必要なのは以下である。

変数内容参考記事
ACCESS_KEY_JSONスプレッドシートへの認証情報が記載されたjson名ダウンロード方法
SPREAD_SHEET_KEYスプレッドシートのキー情報取得方法
lineUserId自身のLine User ID確認方法
lineAccessTokenLineアクセストークン確認方法

おわりに

為替情報をPythonで手に入れる手段はなかなかないため、Google Spread SheetsのGoogleFinance関数を利用した取得方法を記載した。

今回コストがかかる部分はAWS Lambdaの費用だが、AWS Lambdaは起動時間が2秒ほどであれば30分に一回起動していても1円未満で利用できるため、コストパフォーマンスに優れる方法だと考える。

おまけ

過去のおまけにて仮想通貨のアラート用サンプルコードを載せていたが、スプレッドシートを利用するコードをアップする。

用意したシート

  • FXワークシート
  • Binanceワークシート
import urllib.request
import urllib.parse
import json
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from binance.client import Client

#Google Spread Sheetsを定義
ACCESS_KEY_JSON = "XXXXXXXXX.json"
SPREAD_SHEET_KEY = "XXXXXXXXXXX"

#Line APIを定義
LINE_USER_ID="XXXXXXXXX"
LINE_ACCESS_TOKEN="XXXXXXXXX"

#バイナンスAPI定義
BINANCE_API_KEY = 'XXXXXXXXXX'
BINANCE_API_SECRET = 'XXXXXXXXX'
client = Client(BINANCE_API_KEY, BINANCE_API_SECRET)

#Google Spread Sheetsを開く
credentials = ServiceAccountCredentials.from_json_keyfile_name(ACCESS_KEY_JSON, ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive'])
FXWorksheet = gspread.authorize(credentials).open_by_key(SPREAD_SHEET_KEY).worksheet("FX")
BinanceWorksheet = gspread.authorize(credentials).open_by_key(SPREAD_SHEET_KEY).worksheet("Binance")

#Line通知関数
def line_push(lineAccessToken, lineUserId, text):
    url = 'https://api.line.me/v2/bot/message/push'
    data = {
        "to": lineUserId,
	    "messages":[
            {
                "type":"text",
                "text":text
            }
        ]
    }
    headers = {
        'Content-Type': 'application/json',
	    'Authorization': 'Bearer {'+lineAccessToken+'}',
    }
    req = urllib.request.Request(url, json.dumps(data).encode(), headers)
    urllib.request.urlopen(req)

#バイナンス通貨レート取得関数	
def get_avg_trades(pair):
    trade_sum = 0
    trade_num = 0
    trades = client.get_recent_trades(symbol=pair)
    for trade in trades:
        trade_sum = trade_sum + float(trade['price'])
        trade_num = trade_num + 1
    trade_avg = trade_sum / trade_num
    return str(trade_avg)

# Lambdaメイン処理
def lambda_handler(event, context):
    # FXアラートのMain処理を実行
    pairs = FXWorksheet.col_values(2)
    del pairs[0]
    for pair in pairs:
        cell_list = FXWorksheet.row_values(FXWorksheet.find(pair).row)
        if len(cell_list)>3:
            if cell_list[3]!="":
                if float(cell_list[2]) < float(cell_list[3]):
                    body = pair+"が【"+cell_list[3]+"】を下まわりました。"
                    line_push(LINE_ACCESS_TOKEN, LINE_USER_ID, body)
                    body = pair+"は現在【"+cell_list[2]+"】です。"
                    line_push(LINE_ACCESS_TOKEN, LINE_USER_ID, body)
        if len(cell_list)>4:
            if cell_list[4]!="":
                if float(cell_list[2]) > float(cell_list[4]):
                    body = pair+"が【"+cell_list[4]+"】を上まわりました。"
                    line_push(LINE_ACCESS_TOKEN, LINE_USER_ID, body)
                    body = pair+"は現在【"+cell_list[2]+"】です。"
                    line_push(LINE_ACCESS_TOKEN, LINE_USER_ID, body)     
    # 仮想通貨アラートのMain処理を実行
    pairs = BinanceWorksheet.col_values(2)
    del pairs[0]
    for pair in pairs:
        cell_list = BinanceWorksheet.row_values(BinanceWorksheet.find(pair).row)
        rate = get_avg_trades(pair)
        if len(cell_list)>3:
            if cell_list[3]!="":
                if float(rate) < float(cell_list[3]):
                    body = pair+"が【"+cell_list[3]+"】を下まわりました。"
                    line_push(LINE_ACCESS_TOKEN, LINE_USER_ID, body)
                    body = pair+"は現在【"+rate+"】です。"
                    line_push(LINE_ACCESS_TOKEN, LINE_USER_ID, body)
        if len(cell_list)>4:
            if cell_list[4]!="":
                if float(rate) > float(cell_list[4]):
                    body = pair+"が【"+cell_list[4]+"】を上まわりました。"
                    line_push(LINE_ACCESS_TOKEN, LINE_USER_ID, body)
                    body = pair+"は現在【"+rate+"】です。"
                    line_push(LINE_ACCESS_TOKEN, LINE_USER_ID, body)  					
    return ''

インストールモジュール

  • gspread
  • oauth2client
  • binance

設定値(必須)

  • ACCESS_KEY_JSON
  • SPREAD_SHEET_KEY
  • LINE_USER_ID
  • LINE_ACCESS_TOKEN
  • BINANCE_API_KEY
  • BINANCE_API_SECRET
Spread the love