mask

認領區

  • 抓資料 script: @secminhr
  • 前端: @t510599
  • firebase: @a91082900 & @secminhr

Repo

https://github.com/stoneapptech/mask-frontend
https://github.com/stoneapptech/mask-backend
https://github.com/stoneapptech/mask-data
https://github.com/stoneapptech/mask-utils

Feature

  • 請使用者輸入身分證尾數(0是偶數)
  • 使用者可登錄同一鄉/鎮/市/區中的數間藥房(僅一鄉/鎮/市/區)
  • push notification
  • 藥局開賣前?分鐘通知

Implementation

  • fcm

    • fcm topic 以 鄉/鎮/市/區 分(共 371 個)
    • 整理各鄉/鎮/市/區有口罩藥局的醫事機構代碼,送到前端
    • 前端從收到的 list 裡面篩選使用者登錄的藥房
      • 若有,判身分證和星期幾,再發出通知 (Notification API)
      • 沒有,不做事
    • 需要後端接收前端來的 token 送到 firebase
  • service worker

  • localStorage 存選擇的藥局清單

    • service worker 拿不到
  • IndexedDB

  • 後端

    • crontab
      • 每半小時戳 script 抓資料
    • 資料處理
    • /register
      ​​​​​​​​{
      ​​​​​​​​    token: string,
      ​​​​​​​​    area_id: string,
      ​​​​​​​​    is_even: boolean
      ​​​​​​​​}
      
      • return value:
        • succeed
        ​​​​​​​​​​​​{
        ​​​​​​​​​​​​    succeeded: true
        ​​​​​​​​​​​​}
        
        • failed due to invalid area id
        ​​​​​​​​​​​​{
        ​​​​​​​​​​​​    succeeded: false,
        ​​​​​​​​​​​​    message: 'invalid argument'
        ​​​​​​​​​​​​}
        
        • failed while registering fcm
        ​​​​​​​​​​​​{
        ​​​​​​​​​​​​    succeeded: false,
        ​​​​​​​​​​​​    message: 'subscription failed',
        ​​​​​​​​​​​​    errors: error messages from firebase
        ​​​​​​​​​​​​}
        
        For errors property, see Firebase document.
    • /update
      ​​​​​​​​{
      ​​​​​​​​    token: string,
      ​​​​​​​​    old_area: string,
      ​​​​​​​​    new_area: string,
      ​​​​​​​​    is_even: boolean
      ​​​​​​​​}
      
      • return value:
        • succeed
        ​​​​​​​​​​​​{
        ​​​​​​​​​​​​    succeeded: true
        ​​​​​​​​​​​​}
        
        • failed due to invalid area id
        ​​​​​​​​​​​​{
        ​​​​​​​​​​​​    succeeded: false,
        ​​​​​​​​​​​​    message: 'invalid argument'
        ​​​​​​​​​​​​}
        
        • failed while unregistering fcm
        ​​​​​​​​​​​​{
        ​​​​​​​​​​​​    succeeded: false,
        ​​​​​​​​​​​​    message: 'unsubscription failed',
        ​​​​​​​​​​​​    errors: error messages from firebase
        ​​​​​​​​​​​​}
        
        • failed while registering fcm
        ​​​​​​​​​​​​{
        ​​​​​​​​​​​​    succeeded: false,
        ​​​​​​​​​​​​    message: 'subscription failed',
        ​​​​​​​​​​​​    errors: error messages from firebase
        ​​​​​​​​​​​​}
        
        For errors property, see Firebase document.
    • /unregister
      ​​​​​​​​{
      ​​​​​​​​    token: string,
      ​​​​​​​​    area_id: string,
      ​​​​​​​​    is_even: boolean
      ​​​​​​​​}
      
      • return value:
        • succeed
        ​​​​​​​​​​​​{
        ​​​​​​​​​​​​    succeeded: true
        ​​​​​​​​​​​​}
        
        • failed due to invalid area id
        ​​​​​​​​​​​​{
        ​​​​​​​​​​​​    succeeded: false,
        ​​​​​​​​​​​​    message: 'invalid argument'
        ​​​​​​​​​​​​}
        
        • failed while unregistering fcm
        ​​​​​​​​​​​​{
        ​​​​​​​​​​​​    succeeded: false,
        ​​​​​​​​​​​​    message: 'unsubscription failed',
        ​​​​​​​​​​​​    errors: error messages from firebase
        ​​​​​​​​​​​​}
        
        For errors property, see Firebase document.

Data

  • 為縣市與鄉鎮市區建立 ID

    • <area_id> = <City.Town>
    • Example: 臺北市(A) 大同區(01) = A.01
    • 縣市用身分證英文字母 鄉鎮市區建立流水號
  • 醫事機構代碼

    • <code>
    • Example: 5901012061
  • API endpoint (?) https://stoneapptech.github.io/mask-data/

  • folder structure

    • mask-data/ (host on github.io, update by git push)
      • area/
        • $area_id.json (此區域中有哪些藥局)
          • ​​​​​​​​​​​​​​​​​​{
            ​​​​​​​​​​​​​​​​​​  city: "臺北市"
            ​​​​​​​​​​​​​​​​​​  town: "大同區"
            ​​​​​​​​​​​​​​​​​​  store: [
            ​​​​​​​​​​​​​​​​​​    {name: "範例藥局1", address: "某市某區某路", tel: 0212345678, code: 5901012061},
            ​​​​​​​​​​​​​​​​​​    {name: "範例藥局2", address: "某市某區某某路", tel: 0212345679, code: 5901012062}
            ​​​​​​​​​​​​​​​​​​  ]
            ​​​​​​​​​​​​​​​​​​}
            
      • store/
        • $code.json (藥局資料 p.s. 不用經緯度)
          • ​​​​​​​​​​​​​​​​​​{
            ​​​​​​​​​​​​​​​​​​  area_id: "A.01"
            ​​​​​​​​​​​​​​​​​​  city: "臺北市",
            ​​​​​​​​​​​​​​​​​​  town: "大同區",
            ​​​​​​​​​​​​​​​​​​  name: "範例藥局1", 
            ​​​​​​​​​​​​​​​​​​  address: "某市某區某路",
            ​​​​​​​​​​​​​​​​​​  tel: 0212345678,
            ​​​​​​​​​​​​​​​​​​  note: "備註"
            ​​​​​​​​​​​​​​​​​​}
            
      • area_available
        • $area_id.json
          • [5901012061, 5901012062] # 醫事機構代碼
      • mask_number/
        • $code.json (各藥局口罩庫存)
          • {adult: 10, child: 10}
      • update_time.txt (後端抓資料的時間)
        • <unix timestamp>
      • area_id.json (https://file.stoneapp.tech/area_id.json)(https://stoneapptech.github.io/mask-data/area_id.json)
        • ​​​​​​​​​​​​​​{
          ​​​​​​​​​​​​​​  "A": {
          ​​​​​​​​​​​​​​    name: "臺北市",
          ​​​​​​​​​​​​​​    town: {
          ​​​​​​​​​​​​​​      "01": "大同區",
          ​​​​​​​​​​​​​​      ...
          ​​​​​​​​​​​​​​    }
          ​​​​​​​​​​​​​​  },
          ​​​​​​​​​​​​​​  "B": {
          ​​​​​​​​​​​​​​    name: "臺中市",
          ​​​​​​​​​​​​​​    town: {
          ​​​​​​​​​​​​​​      "01": "X區",
          ​​​​​​​​​​​​​​      ...
          ​​​​​​​​​​​​​​    }
          ​​​​​​​​​​​​​​  },
          ​​​​​​​​​​​​​​  ...
          ​​​​​​​​​​​​​​}
          

推送的 data

{
    area_id: "<area_id>"
    available: [1234567890,1234567892,1234567894]
}

流程

  • 設定 (Frontend)
st=>start: 第一次進入
e=>end: 設定完成
digit=>operation: 詢問身分證最後碼
area=>operation: 選擇區域 (縣市 & 鄉鎮市區)
stores=>operation: 選擇藥房 (此區域內的數間)
ask=>condition: 詢問是否開啟通知
register=>operation: 註冊 fcm
(傳送area_id & token)

st->digit->area->stores->ask
ask(yes)->register->e
ask(no)->e

  • 更新資料 (backend)
Server->Open Data: 取得口罩數量
Open Data->Server: 回傳口罩數量
Server-->>github: 上傳更新口罩數量
Server-->>Client: 區域中有口罩藥房清單,依使用者登錄之區域推送
Client->github: 取得詳細數量

Open Data

https://data.nhi.gov.tw/Datasets/DatasetResource.aspx?rId=A21030000I-D50001-001

API 參考

https://api.maskhelp.info/swagger-ui.html

鄉鎮市區清單

https://www.post.gov.tw/post/internet/Postal/index.jsp?ID=208

藥局地址

https://file.stoneapp.tech/健保特約醫事機構-藥局_藥局.csv
把地址帶有?的補齊了

整理串

https://g0v.hackmd.io/@kiang/mask-info
https://github.com/kiang/
https://github.com/WJWang/mask-help-info-api/issues/2

技術筆記

https://www.sentinelstand.com/article/device-group-management-with-firebase-cloud-messaging
https://firebase.google.com/docs/cloud-messaging/js/topic-messaging
https://developers.google.com/web/updates/2015/12/background-sync

Select a repo