第一步先到 LINE Notify 管力登入服務去建立一個服務
接著按下登入服務
把該填的填一填,要注意的是 Callback Url 這邊先暫時先打 localhost:5500,等頁面上傳後再回來改 domain
建立完成之後就到剛剛填的信箱去收信點下網址並啟動服務
這樣第一步就建立完成嚕!
接著上次的透過上次的專案並使用 flask_restful 來改造成 Restful 格式的專案(後面開發會比較輕鬆)
因為我們會讓前端呼叫,CORS 設定成*比較輕鬆,若是有要設定跨域問題的在這邊設定哦 ?
加入套件到 requirements.txt
flask==1.0.2
Flask-RESTful==0.3.6
Flask-Cors==3.0.6
requests==2.22.0
透過使用 flask_restful 幫忙轉發並管理路由
將 api.py 改為以下的 code
from flask import Flask
from flask_restful import Api
from flask_cors import CORS
from controller.notify_controller import NotifyController
app = Flask(__name__)
CORS(app, resources={r"*": {"origins": "*", "supports_credentials": True}})
api = Api(app)
api.add_resource(NotifyController, '/notify')
if __name__ == '__main__':
app.run(debug=True)
這邊我使用 Postgresql,並在專案底下建立一個 lib/ 的資料夾,裡頭放著名為 db.py (這裡還是要記得建立 init.py 哦!)
這邊只簡單建立 Context Manager 讓連線可以被我呼叫。
db.py:
import psycopg2
import psycopg2.extras
class Database():
conns = []
def __enter__(self):
return self
def connect(self):
conn = psycopg2.connect(
database=PG_DB,
user=PG_USER,
password=PG_PWD,
host=PG_HOST,
port=PG_PORT
)
self.conns.append(conn)
return conn
def __exit__(self, type, value, traceback):
for conn in self.conns:
conn.close()
self.conns.clear()
新增一下資料夾名為 controller,建立 init.py & notify_controller.py,這邊搭配 with 做資源管理器,
DB 部分則見黎一個 notify 表,然後一個 token 的欄位。
在這個 class 類別下方法只要輸入
def get/post/put/patch/delete
的函式就可以對應 CRUD 的功能了!
notify_controller.py code is:
from flask_restful import Resource, reqparse
import requests
import json
from lib.db import Database
import psycopg2.extras
class NotifyController(Resource):
def post(self):
parser = reqparse.RequestParser()
parser.add_argument('code', required=True, help='code can not be blank!')
args = parser.parse_args()
code = args['code']
client = {'grant_type': 'authorization_code', 'code': code, 'redirect_uri': 'YOUR_REDIRECT_URI',
'client_id': 'YOUR_CLIENT_ID', 'client_secret': 'YOUR_CLIENT_SECRET'}
r = requests.post(
'https://notify-bot.line.me/oauth/token', data=client)
req = json.loads(r.text)
if req['status'] == 200:
token = req['access_token']
# Here is use PostgreSQL, you can change your love db
with Database() as db:
with db.connect() as conn:
with conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) as cur:
cur.execute(
f"INSERT INTO notify(token) VALUES ('{token}')")
return {'access_token': req['access_token']}, 200
else:
return {'message': r.text}, 200
以下這三個要設定成你的當時輸入的字串
若不清楚 Client_id & Client_secret 的話就回到 Notify 頁面並點選剛剛建立的服務就能看到 token 了
建立一個 views/ 的資料夾,並建立兩個檔案
這邊需要修改
client_id
以及redirect_uri
這個檔案主要功能是讓使用者有個可以按按鈕觸發的地方,當然這只是個範例,實際上線可能就會直接 call API 導向 LINE Notify 頁面等等
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Link Notify</title>
</head>
<body>
<button onclick="Auth();">點選這裡連結到LineNotify</button>
<script>
function Auth() {
var URL = "https://notify-bot.line.me/oauth/authorize?";
URL += "response_type=code";
URL += "&client_id=YOUR_CLIENT_ID";
URL += "&redirect_uri=YOUR_REDIRECT_URI";
URL += "&scope=notify";
URL += "&state=nostate";
window.location.href = URL;
}
</script>
</body>
</html>
修改 ajax 裡的 url,將網址換成之前部署的網址,若忘了可以在部署一次
sls deploy
當導回來的時候透過 ajax 來呼叫 serverless api 讓後端發 requests 給https://notify-bot.line.me/oauth/token
來獲取access_token
。
因為這個路由有 CORS 的問題,若透過瀏覽器來的話會出錯,這邊則是讓後端去處理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>message check</title>
</head>
<body>
verify messate:
<div class="message"></div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js"></script>
<script>
var urlParams = new URLSearchParams(window.location.search);
var notify_code = urlParams.get("code");
var state = urlParams.get("state");
$(function() {
$.ajax({
url: "https://SLS_URI.execute-api.us-east-2.amazonaws.com/dev/notify",
type: "POST",
dataType: "json",
data: { code: notify_code },
success: function(response) {
console.log(response);
$(".message").text(response["access_token"]);
},
error: function(xhr) {
console.log(xhr);
alert("Ajax request 發生錯誤");
}
});
});
</script>
</html>
接著就是測試程式碼是不是正常的,把這兩個檔案丟到 S3 上面
把 object url 複製到 LINE Notify 上的 callback url 欄位,這樣就可以實機測試了 ?
接著按下 index page 的按鈕應該就會看到連動成功(進資料庫應該也會被 insert 一筆)
到了這邊如果沒問題真的是恭喜你,我踩了好多坑 Orz
你好 請教下
就算我已經連動過 進去Index是不是還是一樣要再連動一次才行?
如果有存在 DB 就不用喔!
另外這份 code 可以參考我之後改寫的,因為當時對 flask 還不是很熟 XD
https://github.com/louis70109/flask-line-notify