繼之前三篇的聊天機器人 try try 抗後,又為 Chat-DOMO 新增了繪圖功能惹~👏👏👏 是進化到可以畫圖了嗎?當然不是,是你可以畫圖給它啦(好廢喔哈哈哈😂 趁還沒忘記簡單記錄一下!
因為剛好要來研究一下 LIFF 是什麼碗糕?所以呢,就乾脆把我的 DOMO 拿來進化一下!就看到網路上有大大也是給它們的機器人加了這個功能耶!先貼來致敬一下:
最早是這篇 LINE 日本官方開發文章做的畫圖功能(連結在這),幾乎都是依據這篇範例下去開發,我前台的 html 也是依據上面的範例寫的,所以我也來記錄一下唄!
開始前,先講一下目標,這樣比較知道到底在幹麻:
讓使用者可以在 LINE 裡面畫圖,並將圖發給機器人。
恩⋯ 怎麼聽起來好像很簡單咧?但是啊人類誕生在地球上的每個動作可都不簡單啊!(三小 😂
中間的過程可是涉及很多細節⋯ 先大致解析這故事的流程:
- 用 Canvas 做好畫圖的靜態 HTML 頁
- 為此畫圖頁面向 LINE 取得可使用的 LIFF App ID
- 在 server 端設定好頁面路徑和開發存圖功能
- 當使用者畫好圖送出,client 端將圖用 ajax 傳給 server 端並儲存在雲端上
- server 端儲存完畢後,回傳圖片網址給 client 端
- client 端接收圖片網址後,讀取使用者的 LINE ID,送出圖片訊息
呼~大致概念是這樣,但是細節還是很多,只好一步一步來吧!
STEP 1. 將畫圖頁開發好
我這邊用原生 Canvas 2D 製作(因為很懶,就拿之前的開發過的來改~😆),看滿多人是找網路上的套件來用(若使用套件可以直接跳過此步驟),假設你已有 Canvas 2D 開發基礎(如果沒有,可以參考很久以前寫的這篇 Canvas 2D 學習筆記),接下來的步驟會簡略說明。
我這邊主要是用一個畫布(canvas)、七個按鈕(button),按鈕有五個是顏色選取、一個是清除鍵、一個是送出鍵,以及一個測試元素:

上面有預留一個小空位做測試,因為 LIFF 是 in app 的網站,不是很好除錯,於是留一個位置顯示有沒有抓對使用者的 id。
取得使用者畫圖時的座標:

儲存座標點和 touchstart, touchend, touchmove 的監聽事件:

將儲存的筆畫顯示出來:

登登登登!完成後大概就會長這樣:

STEP 2. 向 LINE 取得可使用的 LIFF App ID
一樣先登入 LINE Developers,找到要使用的 Channel,點擊上方的「LIFF」,就可以進來這邊加入畫圖頁網址!(也可用 curl 指令取得,直接參考這篇)


主要要新增的項目是這三個:
- Name 是 LIFF App 的名稱,會顯示在最上面
- Size 是開啟 LIFF App 的尺寸,這邊提供三種:Full、Tall、Compact
- Endpoint URL 是畫圖頁的網址(網址一定要是 https)

設定完畢後,會在 LIFF URL 上取得一組 line://app/ 開頭的網址,這個就是將會在 LINE 裡面開啟的網址!

STEP 3. 設定好頁面路徑和開發存圖功能
在 node 上,設定頁面路徑和存圖的方法很多種,沒有一定的方式,因為不是很懂深層技術,我無法正確解釋,這邊我先貼一下網路上找的神秘方法⋯
簡單來說,使用者畫好的圖片從 client 端傳到 server 端要經過:Canvas 畫完圖存成 base64 編碼,然後用 ajax 把這串碼傳給 server,server 再將拿到的 base64 編碼轉成 png 檔案,是有點繁複的過程⋯所以這邊是拿到 base64 編碼後再將它轉成 png,然後存起來!

另外,要記得設定可以在 LINE 裡面打開該 LINE App 的方式!
STEP4. 取得使用者的 LINE ID
設定完 Server 後,再回頭新增 Client 頁面上的程式碼,首先在畫圖頁會需要取得使用者的 LINE ID,要載入 LIFF SDK:
<script src="https://d.line-scdn.net/liff/1.0/sdk.js"></script>
要使用 LIFF 要先做 init 的動作,這邊就可以直接取得 userId:
liff.init(function (data) { console.log(data.context.userId); //直接取得 userId });
STEP5. 使用者送出圖片並自動發送圖片訊息
這邊我使用 jQuery 的 ajax 來傳遞圖片資料,貼一下主要的部分:
var imgData = canvas.toDataURL("image/png"); // canvas 圖片資料存成 base64 // 傳到伺服端 $.ajax({ url: "/fileupload", type: "POST", datatype: "json", data: { image: imgData }, success: function (res, status) { //成功時回傳 var data = JSON.parse(res); var filename = data.image; // 取得圖片名稱 liff.getProfile().then(function (profile) { // 取得使用者資料正確時 liff.sendMessages([ //使用者自動發送圖片訊息 { type: 'image', originalContentUrl: 'https://example.com/uploads/' + filename + '.png', previewImageUrl: 'https:/example.com/uploads/' + filename + '.png' } ]).then(function () { // 發送完關閉視窗 liff.closeWindow(); }).catch(function (error) { window.alert('Error sending message: ' + error.message); }); }).catch(function (error) { window.alert("Error getting profile: " + error.message); }); } });
來看看最後的成果吧!




以上就是瘋狂亂開發 LIFF 的小測試啦!