owned this note
owned this note
Published
Linked with GitHub
# Line Bot Lesson 3 - 專題實作-旅遊購物外幣換算 fastapi+firebase版
:house: [回筆記首頁](https://www.mirai.tw)
###### tags: `python` `Line` `Bot` `api`
[toc]
試試看這個 line-bot吧! <a href="https://lin.ee/VbbJPCq"><img src="https://scdn.line-apps.com/n/line_add_friends/btn/zh-Hant.png" alt="加入好友" height="36" border="0"></a>
![LINE-BOT-QR-CODE](https://qr-official.line.me/gs/M_533mqtcl_GW.png)
在程式中,
我們使用到 fastapi 取代 flask, uvicorn 取代 gunicorn,
資料庫使用firebase 的 nosql 資料庫,有興趣的可以看看詳細使用方法請參閱
[FastAPI與Python內建wsgi]https://hackmd.io/@CSL/Hyzuh83Oo
[Python 連結NoSQL資料庫(Firebase)的 CRUD] https://hackmd.io/@CSL/BJVz8SFl3
因此 你必須先
pip install fastapi,uvicorn,twder,re,linebot-sdk,firebase_admin
這是這個程式的原始碼
```
# 使用fastapi
LINE_CHANNEL_ACCESS_TOKEN='xxxxx'
LINE_CHANNEL_SECRET='xxx'
AUTHOR='林奇賢'
curd={"..":{"美金":"..USD","日圓":"..JPY","韓元":"..KRW","歐元":"..EUR","人民幣":"..CNY","更多":"..,"},
"..,":{"港幣":"..HKD","英鎊":"..GPB","澳幣":"..AUD","泰幣":"..THB","馬來幣":"..MYR","更多":"..,,"},
"..,,":{"菲比索":"..PHP","印尼幣":"..IDR","越南盾":"..VND","加幣":"..CAD","紐元":"..NZD","更多":"..,,,"},
"..,,,":{"瑞士法郎":"..CHF","南非幣":"..ZAR","瑞典幣":"..SEK","新加坡幣":"..SGD","更多":".."},
}
import re
import twder
from fastapi import FastAPI, Request
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent, TextMessage, TextSendMessage, QuickReply, QuickReplyButton, MessageAction
import firebase_admin
from firebase_admin import credentials
from firebase_admin import db
app= FastAPI(docs_url=None, redoc_url=None, openapi_url = None)
myDB='https://myfirstfirebase-601001.firebaseio.com/'
cred = credentials.Certificate("apikey.json")
firebase_admin.initialize_app(cred, {'databaseURL': myDB})
curr_users = db.reference('/bot3')
line_bot_api = LineBotApi(LINE_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(LINE_CHANNEL_SECRET)
# a POST route for our webhook events
@app.post("/")
async def webhook_handler(request: Request):
# verify signature if needed
# add logic to handle the request
signature = request.headers['X-Line-Signature']
body = await request.body()
try:
handler.handle(body.decode(),signature)
except InvalidSignatureError:
raise HTTPException(status_code=400, detail="SignatureError")
return "ok"
@handler.add(MessageEvent, message=TextMessage)
def handling_message(event):
mtext=event.message.text
user_id=event.source.user_id #get userID in Line
query_id=curr_users.child(userid)
currency=query_id.get() # get data-line userID in firebase
if currency is 'None': # if there is no data in firebase
curr_users.update({user_id:"JPY"})
currency='JPY'
try:
regex = r'[^0-9.+-/()*]'
prog = re.compile(regex)
if not prog.search(mtext):
money=eval(mtext)
else:
money=-1
curr=float(twder.now(currency)[2] if twder.now(currency)[4]=='-' else twder.now(currency)[4])
#2:現鈔賣出 4:即期賣出 ,若無即期報價則回傳現鈔報價
except:
curr=0
money=-1
if mtext.upper()=="AUTHOR":
message=TextSendMessage("作者:"+AUTHOR)
elif mtext in curd: # mtext='..' or '...' or '....' and so on
items=[]
for item in curd[mtext]:
items.append(QuickReplyButton(action=MessageAction(item,curd[mtext][item])))
try:
message=TextSendMessage(
'選擇要查詢的外幣',
quick_reply=QuickReply(items)
)
except:
message=TextSendMessage("Error at QuickReply")
elif (mtext[:2]=='..')and(len(mtext)>2):
changecurrency=mtext[2:5].upper()
if changecurrency in twder.currencies():
curr_users.update({user_id:changecurrency})
message=TextSendMessage(f'設定成{twder.currency_name_dict()[changecurrency]}換台幣\n請直接輸入數值或運算式')
elif (money>=0):
message=TextSendMessage(f'''{money} {twder.currency_name_dict()[currency]}\n台幣約為 {str(round(money*curr))}元\n輸入 .. 變換幣別''')
else:
message=TextSendMessage(f'現在查詢的是{twder.currency_name_dict()[currency]}\n輸入..變換幣別\n或是輸入數值或運算式\n例如:\n1500\n50+45*0.7')
line_bot_api.reply_message(event.reply_token,message)
```