# 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) ```