Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9204

LINEBotを使って海外現地金額から日本円を返してみた

$
0
0

目的

仕事で海外とやりとりすることが多くなってきました。
海外に行ったときに現地通貨が日本円ではいくらなのかをすぐに調べることができるツールがあれば便利だと思って今回、自分で作ってみました。

実現方法

入力

入力についてはLINEを使用しました。

使用したAPI

Foreign exchange rates API
https://exchangeratesapi.io/

ロジック

LINEに入力する文字の形式は固定にしました。
 入力として受け付ける文字
  (国名):(現地金額)は日本でいくら?
 例
  中国:1000は日本でいくら?

LINEで入力した内容をもとにAPIを利用して日本円に換算しています。
1.LINEで入力した国名をもとに通貨名を取得します。
  連想配列でkey:国名、value:通貨名として紐づけを持たせています。
2.1.で取得した通貨名からレートを求め、日本円を取得します。
  今回使用したAPIについては1ユーロあたりのレートが返却される仕様となっていました。
  そのため、まず、入力した現地金額を何ユーロか求めて、1ユーロあたりの日本円をかけて
  求めています。

コード

'use strict';// ########################################//               初期設定など// ########################################// パッケージを使用しますconstexpress=require('express');constline=require('@line/bot-sdk');constaxios=require('axios');// ローカル(自分のPC)でサーバーを公開するときのポート番号ですconstPORT=process.env.PORT||3000;// Messaging APIで利用するクレデンシャル(秘匿情報)です。constconfig={channelSecret:'作成したBotのチャネルシークレット',channelAccessToken:'作成したBotのチャネルアクセストークン'};// 国名と通貨の紐づけをしています。constcurrency=newArray();currency["カナダ"]="CAD:ドル";currency["香港"]="HKD:ドル";currency["アイスランド"]="ISK:クローナ";currency["フィリピン"]="PHP:ペソ";currency["デンマーク"]="DKK:クローネ";currency["ハンガリー"]="HUF:フォリント";currency["チェコ"]="CZK:コルナ";currency["オーストラリア"]="AUD:ドル";currency["ルーマニア"]="RON:レウ";currency["スウェーデン"]="SEK:クローネ";currency["インドネシア"]="IDR:ルピア";currency["インド"]="INR:ルピー";currency["ブラジル"]="BRL:レアル";currency["ロシア"]="RUB:ルーブル";currency["クロアチア"]="HRK:クナ";currency["日本"]="JPY:円";currency["タイ"]="THB:バーツ";currency["スイス"]="CHF:フラン";currency["シンガポール"]="SGD:ドル";currency["ポーランド"]="PLN:ズウォティ";currency["ブルガリア"]="BGN:レフ";currency["トルコ"]="TRY:リラ";currency["中国"]="CNY:人民元";currency["ノルウェー"]="NOK:クローネ";currency["ニュージーランド"]="NZD:ドル";currency["南アフリカ共和国"]="ZAR:ランド";currency["アメリカ"]="USD:ドル";currency["メキシコ"]="MXN:ポンド";currency["イスラエル"]="ILS:新シケル";currency["イギリス"]="GBP:ポンド";currency["韓国"]="KRW:ウォン";currency["マレーシア"]="MYR:リンギット";// ########################################//  APIでデータを取得する部分// ########################################// APIを呼び出し日本円を求めるconstrateFunction=async(event)=>{constuserText=event.message.text;// ユーザーメッセージが「日の出」か「日の入り」かどうかif(userText.indexOf('日本でいくら?')===-1){returnclient.replyMessage(event.replyToken,{type:'text',text:'「(国名):(金額)は日本でいくら?」と話しかけてね'});}else{// 「リプライ」を使って先に返事しておきますawaitclient.replyMessage(event.replyToken,{type:'text',text:'調べています……'});letpushText='';try{constcountry_amt=userText.substring(0,userText.indexOf(''));// LINEに入力した国名constcountry=country_amt.substring(0,userText.indexOf(':'));// LINEに入力した金額constamt=country_amt.substring(userText.indexOf(':')+1,userText.length);// axiosでレート取得のAPIを叩きます(少し時間がかかる・ブロッキングする)constres=awaitaxios.get('https://api.exchangeratesapi.io/latest');// LINEに入力した国名から通貨を取得するconstcountry_tmp=currency[`${country}`];// 通貨(英語名)constcountry_currency=country_tmp.substring(0,country_tmp.indexOf(':'));// 通貨(日本語名)constcountry_currency_jpn=country_tmp.substring(country_tmp.indexOf(':')+1,country_tmp.length);// LINEに入力した国名の1ユーロあたりのレートconstcountry_rates=res.data.rates[`${country_currency}`];// 1ユーロあたりの日本円constjpy_rates=res.data.rates.JPY;// LINEに入力した金額の日本円constjpy_yen=Math.round((amt/country_rates)*jpy_rates);pushText=`日本円で約${jpy_yen}円です!`;}catch(error){pushText='検索中にエラーが発生しました。ごめんね。';// APIからエラーが返ってきたらターミナルに表示するconsole.error(error);}// 「プッシュ」で後からユーザーに通知しますreturnclient.pushMessage(event.source.userId,{type:'text',text:pushText,});}};// ########################################//  LINEサーバーからのWebhookデータを処理する部分// ########################################// LINE SDKを初期化しますconstclient=newline.Client(config);// LINEサーバーからWebhookがあると「サーバー部分」から以下の "handleEvent" という関数が呼び出されますasyncfunctionhandleEvent(event){// 受信したWebhookが「テキストメッセージ以外」であればnullを返すことで無視しますif(event.type!=='message'||event.message.type!=='text'){returnPromise.resolve(null);}// 関数を実行しますreturnrateFunction(event);}// ########################################//          Expressによるサーバー部分// ########################################// expressを初期化しますconstapp=express();// HTTP POSTによって '/webhook' のパスにアクセスがあったら、POSTされた内容に応じて様々な処理をしますapp.post('/webhook',line.middleware(config),(req,res)=>{// Webhookの中身を確認用にターミナルに表示しますconsole.log(req.body.events);// 検証ボタンをクリックしたときに飛んできたWebhookを受信したときのみ以下のif文内を実行if(req.body.events[0].replyToken==='00000000000000000000000000000000'&&req.body.events[1].replyToken==='ffffffffffffffffffffffffffffffff'){res.send('Hello LINE BOT! (HTTP POST)');// LINEサーバーに返答しますconsole.log('検証イベントを受信しました!');// ターミナルに表示しますreturn;// これより下は実行されません}// あらかじめ宣言しておいた "handleEvent" 関数にWebhookの中身を渡して処理してもらい、// 関数から戻ってきたデータをそのままLINEサーバーに「レスポンス」として返しますPromise.all(req.body.events.map(handleEvent)).then((result)=>res.json(result));});// 最初に決めたポート番号でサーバーをPC内だけに公開します// (環境によってはローカルネットワーク内にも公開されます)app.listen(PORT);console.log(`ポート${PORT}番でExpressサーバーを実行中です…`);

結果

LINEに
 中国:1000は日本でいくら?
と入力することで
 日本円で約15807円です!
と返信をもらうことができました。

image.png

考察

目的である現地通貨が日本円ではいくらなのかを調べるツールを作ることができました。
ただ、下記の課題があると思っているので、改善していければと思ってます。

1.国名と通貨名の紐づけを連想配列にしているが、もう少しスマートな書き方を検討する。
2.連想配列に存在しない国名がきたときの制御ができていない。
3.入力として受け付ける文字が(国名):(現地金額)は日本でいくら?と指定しづらい。
  下記のように対話形式で実現させる。
  国名を入力してね!
  →中国
  →何元?
  →1000
  →1000元は日本円で約15807円です!


Viewing all articles
Browse latest Browse all 9204

Trending Articles