標籤

LINE Notify

除錯 Python 套件遇到 Command Line 無法使用的問題 | lotify

click command

前言

近期收到了一個來自 Lotify 的 Pull Request,主要功能是加入 Command Line 的功能,讓用戶在安裝 Lotify 之後即可在終端機上測試,感謝來自熱情的網友幫忙。

原以為 Merge 之後應該要可以用了,於似乎開始安裝要開始使用測試,沒想到遇到了一個錯誤

ModuleNotFoundError: No module named 'lotifyCli'

於是就開始的抓蟲之旅。✍️

繼續閱讀

如何建置與使用 GitHub Actions 市集的 LINE Notify 套件

前言

以前不管在單元/整合測試部署或是一些週期性的工作,有點經驗的工程師通常會很習慣寫個 Script 去跑相關指令集。而隨著寫的服務越來越多,許多部分也微服務化後,同一個指令集可能會服務到對象也越來越多,因此就開始有了像是 Jenkins、Drone、Travis 以及本篇會介紹 GitHub Actions 這類的 CI 工具,但既然是工程師當然要把指令集內的耦合性盡可能的降到最低,因此就有像是 GitHub Marketplace 的套件市集,讓大家可以在上面選擇不同功能的工具套入於自己的 CI 中,接下來就讓我帶你來了解一下平時會遇到什麼問題,以及如何建立與使用 LINE Notify 於 GitHub Actions 上吧!

以前如何知道結果?

  • 寫 Script 並用 Linux 的排程(Crontab)在固定時間跑測試案例、爬資料、部署...等狀態
  • CI/CD 過了之後自己上網站看 log (沒通知)
  • 即便寫通知程式在 Script 裡,未來的可用性極低(不好管控金鑰、換程式語言...)

Why GitHub Actions?

  • GitHub 自家出的 CI 工具
  • 專案大多放在 GitHub 上的情況
    • 可達到資源 Single Source of Truth
  • 市集(Marketplace)已經有許多工具可以合併使用

Why LINE Notify?

繼續閱讀

Twitch Bot 全面升級! 增加 LINE Notify 綁定與推播實現 LINE 的三項之力!

滿滿的三項之力 🏋️‍♂️

來幫我的 Twitch Bot 按個星星 ⭐️⭐️

更新功能

  • 使用 LIFF 來綁定 Notify
繼續閱讀

Day5 - 做一個與 LINE Notify 連動的服務

建立 LINE Notify 服務

第一步先到 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

以下這三個要設定成你的當時輸入的字串

  • YOUR_REDIRECT_URI
  • YOUR_CLIENT_ID
  • YOUR_CLIENT_SECRET

若不清楚 Client_id & Client_secret 的話就回到 Notify 頁面並點選剛剛建立的服務就能看到 token 了

建立一個 views/ 的資料夾,並建立兩個檔案

  • notify_index.html

    這邊需要修改 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>
  • notify_confirm.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

參考

資源管理器 flask CORS CORS

繼續閱讀