創作內容

6 GP

將 LINE 聊天機器人部署到自己的雲端 VM (不用 heroku)

作者:游隼│2022-01-31 09:27:19│巴幣:12│人氣:3817
整個 Server 最後會長這樣

由於 LINE bot 的 webhook URL 要求一定要是 https 的網址 所以還要 https 伺服器

我用 nginx 是因為 line-bot 應該沒必要用到 Apache (Apache 比較吃伺服器資源)

nginx 需要設定憑證 才會從 http 伺服器變成 https 伺服器 不過有 certbot 可以自動完成憑證簽發、更新的動作 (好東西、不用嗎?)

不用 heroku 是因為 heroku 免費用戶只要超過 30 分鐘沒人訪問就會關掉 有人在次訪問需要 1-2 分鐘重啟 重啟之後 Line bot 也會被重啟 總之在沒課金的狀況下十分不方便

如果是比較熟悉 Python 的朋友也可以把 Node.JS + express 的組合改成 python + Flask。兩種我都用過,不過我比較熟悉 JS 所以用 JS 寫流程。


創一個新的 VM 實體

~~~如果已經有雲端 VM 的朋友可以跳過這段~~~

有很多廠商提供雲端運算的服務 如 Azure, AWS, GCP...... 等等

有要收費的也有不用收費的 大家可以找一個自己喜歡的來做

在本篇文章中我用 Oracle Cloud 的 Standard E2 示範 映像檔用的是預設的 Oracle Linux 7.9

登入了自己的 Oracle Cloud 帳號後找到 Create a VM instance 點下去

在 Image and shape 點【Edit】然後選【Change Shap】→【Virtual machine】→ 【Specialty and previous generation】→【VM.Standard.E2.1.Micro】

記得保存 SSH 金鑰 (點【Save Private Key】就可以下載了) 或是貼上自己原有的金鑰

點整個網頁左下角的【Create】就可以創建 VM 實體了 (需要等一下才會創好)

創好後把 Public IP addressUsername 記下來待會會用到

在這個頁面順便設定子網路規則
找到 Primary VNIC 中的 Subnet 點進去

找到 Security Lists 中的 Default Security List for XXXXXX 點進去

點【Add Ingress Rules】
Source CIDR:0.0.0.0/0
IP Protocol:TCP (保持預設)
Source Port Range:留空 (保持預設)
Destination Port Range:80 (填入允許的連接埠)

完成後點【Add Ingress Rules】

需要新增兩個連接埠 (80 是給 http 用的、443 是給 https 用的)
所以再【Add Ingress Rules】一次 (這次 Destination Port Range 填入 443)

有了 Public IP address 可以去申請 domain.name 了 (可以用免費域名如 no-ip)
這裡不贅述了 給個 Google 關鍵字:免費域名 申請 教學 no-ip


登入 VM 實體

我習慣用 WinSCP 開 Putty 登入雲端 VM (其實只要 Putty 就好了)

不過有 WinSCP 傳檔案比較方便 反正是免費的總之就先都裝吧

都不想裝也可以用 Windows 內建的 PowerShell 連

下載 WinSCPPutty 然後無腦安裝 ((總之一直下一步就對了XD

打開 WinSCP 會有一個登入視窗
檔案協定:SFTP (保持預設)
主機名稱:填入剛剛的 Public IP address
連接埠:22 (保持預設)
使用者名稱:填入剛剛的 Username
點【進階】→ SSH → 身分核對 找到【私鑰檔案】選剛剛下載的 SSH 金鑰

【進階】的左邊有一個【儲存】 上面都設定好後可以把連線設定儲存起來 就不用每次連都要重打這些了

完成連線設定後點【登入】
第一次連線會問你要不要信任該主機 點【是】

※之後有需要傳檔案到伺服器可以在這邊傳

※可以在【指令】→【於 Putty 開啟】快速開啟終端機視窗


部署 Web Server

第一次打開 Putty 先更新一下已安裝的套件 (需要等幾分鐘)
sudo yum -y update

安裝 RHEL 庫 (標準 CentOS 不用 如果安裝 nginx 或 snap 出現 not available 再安裝)
sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

安裝 nginx
sudo yum install -y nginx

有關  nginx 的指令可以參考: nginx: Beginner’s Guide

用 vim 設定 nginx.conf
sudo vim /etc/nginx/nginx.conf

把 server_name  改成你從 no-ip 或其他地方申請到的域名 (domain.name)

在 server 區塊的最後加入 反向代理 /express/ 到 3000 埠的設定
(路由名字可以自己取 不過待會是要傳給 express 的 我就取作 express)
server {
    listen       80;
    server_name  domain.name;

    ...

    location /express/ {
        proxy_pass http://localhost:3000/;
    }
}
設定完成後儲存

這時啟動 nginx
sudo nginx

設定訪火牆 允許連接埠 80 和 443 (443 還沒用到 不過之後也要開就先打開吧XD)
sudo firewall-cmd --permanent --zone=public --add-port=80/tcp
sudo firewall-cmd --permanent --zone=public --add-port=443/tcp
sudo firewall-cmd --reload

在瀏覽器打開 http://domain.name
如果有出現網頁 Welcome to nginx! 代表 nginx 正確運作

打開 http://domain.name/express
如果出現 404 Not Found 代表上面反向代理沒設好
如果出現 An error occurred. 這是正常的 因為 3000 埠上還沒有程式在監聽

如果啥也沒出現可能是 nginx 沒有執行、防火牆沒設定好......等等 請先排查故障

安裝 Certbot

安裝 snap
sudo yum install -y snapd
sudo systemctl enable --now snapd.socket
sudo ln -s /var/lib/snapd/snap /snap

安裝 Certbot
sudo snap install core; sudo snap refresh core

centos 安装 snapd 报错: too early for operation, device not yet seeded or device model not acknowledged
sudo setenforce 0

sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo certbot --nginx

之後會提示你輸入 email 就輸入常用的 email 就行了

問你同不同意他們的服務規則之類的 輸入 y

問你要不要 email 訂閱他們的消息 要的話輸入 y

問你你的 domain.name 是什麼 輸入你的域名

在瀏覽器打開 https://domain.name/ 如果有出現網頁左上角也有鎖頭的話 代表 https 設定成功


將 bot 放到 VM 上

當環境部屬好之後 接著就是將寫好的 LINE bot 放上去運行了

這裡用 LINE Developers 官方提供的範例程式碼

Messaging API 本身提供很多程式語言的 SDK 可以依照自己習慣的語言來

我比較熟悉 JavaScript 所以選擇 Node.js 的 SDK

安裝 Node.js
sudo yum install -y nodejs

新增資料夾用來放 LINE bot
mkdir echo-bot
cd echo-bot

用 npm 安裝依賴項
npm install @line/bot-sdk --save
npm install express --save

把官方範例裡的 index.js 下載下來

第 8 行、第 9 行填上 LINE bot 的 tokensecret
const config = {
  channelAccessToken: 填上TOKEN,
  channelSecret: 填上SECRET,
};

第 21 行可以設定 express 的路由預設是 /callback
如果有多個 LINE bot 的話可以在這邊設定成你要的路由路徑
app.post('/callback', ...) => { ... });

第 46 行可以設定 express 的所監聽的連接埠 預設是 3000
如果 3000 埠被占用可以設定成其他的 不過前面 nginx 反向代理的連接埠也需要改
const port = process.env.PORT || 3000;
app.listen(port, () => {
  console.log(`listening on ${port}`);
});

改好 index.js 並放到伺服器上之後就可以執行了
node index.js

直接開的話當終端機視窗被關閉 伺服器上也會被一併關閉
如果是要長期執行可以用 nohup 在背景執行
nohup node index.js&


回去更新 Webhook URL

回去登入您的 LINE Developers 帳號

在 Messaging API 的頁籤裡有 Webhook settings

更新 Webhook URL 成 https://domain.name/express/callback/

儲存之後驗證看看 出現 Success 你的 line-bot 就能正常運作了~~灑花
引用網址:https://home.gamer.com.tw/TrackBack.php?sn=5377263
All rights reserved. 版權所有,保留一切權利

相關創作

留言共 18 篇留言

001
大大你好,想請問一下全部都是在linux的環境下做的嗎?還是windows? 部署 Web Server這一part看起來好像在linux上下的指令...(新手還在摸索中)

05-01 00:58

游隼
用任一電腦連到遠端的Oracle Cloud (免費的都是Linux 所用的是Linux指令)05-01 09:14
游隼
本機設備是Windows還是Linux沒差 我甚至常常直接用手機登SSH連線到OrcaleCloud的遠端VM實體05-01 09:14
游隼
可以簡單理解為Oracle有一台超級電腦 然後把超級電腦切成無數個虛擬機器(VM)提供租賃服務05-01 09:17
游隼
所以可以理解為你跟Oracle租了一台Linux電腦 並在上面部署你的程式05-01 09:20
游隼
所以本機端用的是什麼不重要 遠端是Linux環境沒錯05-01 09:20
游隼
如果覺得這篇很複雜又只是想寫簡單的Line bot 可以先用google app script 去做05-01 09:22
游隼
可以上網找教學搭配我這篇看
https://home.gamer.com.tw/creationDetail.php?sn=541848205-01 09:23
001
了解了,感謝,這篇寫得很詳細,但目前跟著操作到--安裝 snap--這邊就卡住了...好像缺了什麼東西,一直裝不過,報錯如下:
Error:
Problem: package snapd-2.55.3-1.el7.x86_64 requires snapd-selinux = 2.55.3-1.el7, but none of the providers can be installed
- conflicting requests
- nothing provides policycoreutils-python needed by snapd-selinux-2.55.3-1.el7.noarch
(try to add '--skip-broken' to skip uninstallable packages or '--nobest' to use not only best candidate packages)

這邊好像也不能跳過(?
看起來好像是缺了那個package?但不知道要怎樣抓下來 還在摸索中

05-01 13:54

游隼
你是卡在安裝SNAP?現在Orcale Cloud預設的系統是基於CentOS8的OrcaleOS 已經不用yum安裝SNAP了05-01 14:03
游隼
你可以在卡住的地方看點超連結找 官方對於CentOS8 的安裝步驟05-01 14:04
001
對 是卡在snap 所以說可以直接跳過snap 直接安裝Certbot的意思? 我試試看 感謝感謝

05-01 14:06

游隼
不是 你先照https://snapcraft.io/docs/installing-snap-on-centos 的步驟做看看
$ sudo dnf install epel-release
$ sudo dnf upgrade
$ sudo dnf install snapd
$ sudo systemctl enable --now snapd.socket
$ sudo ln -s /var/lib/snapd/snap /snap05-01 14:15
001
有有我已經有照著做了 不過從第一個指令開始就看起來不正常,然後執行$ sudo dnf upgrade的時候就開始跳錯
Error:
Problem: cannot install the best update candidate for package libidn2-2.2.0-1.el8.x86_ 64
- nothing provides libunistring.so.0()(64bit) needed by libidn2-2.3.2-1.el7.x86_64
(try to add '--skip-broken' to skip uninstallable packages or '--nobest' to use not onl y best candidate packages)

然後就卡在這邊了,昨天已經有試到這邊但還是解決不了..

05-01 14:31

001
大大你好,我找到問題點了,在安裝 RHEL 庫要改成"sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm"
然後再照你說的步驟就可以了,拍謝一直打擾XD

05-01 15:06

游隼
恭喜 有問題還是可以來問問看
如果有我幫得上忙的話05-01 15:24
001
那我再問個問題,我原本已經有line bot寫好也部屬在heroku上,如果想要搬到oracle這邊的VM上,是不是在vm上把我Line bot的檔案抓下來再vm上執行,然後一樣把 Webhook URL改掉就好?我在VM上可以執行,也有 listening on http://localhost:3000,在line上測試也有得到Success,但直接用line跟line bot講話卻不會回話,在PuTTY的terminal上確有看到該回的句子(我有console.log出來),感覺應該是我設定上少了些什麼?

05-01 15:49

游隼
路由有設好嗎?感覺上是路由沒設好05-01 16:20
游隼
nginx 跟 express 都會影響到URL05-01 16:21
游隼
尤其是nginx的location少一個/代表的意思就不一樣了05-01 16:22
游隼
喔喔沒事05-01 16:23
游隼
terminal 有出來應該是沒問題05-01 16:35
游隼
可以的話先測一下官方的echo範例檔確定其他地方有沒有問題05-01 16:36
001
你好,我剛測了很久然後有測道出error的話,server就停了,然後我去裝了個叫pm2的東西,好像是會一直讓server運行?就算crash也會自動重啟,這東西跟nohup一樣概念對吧?我用postman戳line的API在terminal都正常,唯一不正常的就只有line bot沒丟回應回來,用ps aux | grep查了之後給了這個東西opc 329132 0.0 0.1 221924 1040 pts/0 R+ 08:31 0:00 grep --color=auto poe-app(我的app name) 這也看不出代表什麼意思XD,不過我直接node index.js 也是一樣的情況,功能都正常,就line那邊掛掉。

05-01 16:36

游隼
對了你nohup的log寫了些什麼05-01 16:39
游隼
方便的話順便貼出來05-01 16:40
游隼
nohup跟pm2作用一樣都是讓他在背景跑的05-01 16:41
游隼
line那邊掛掉可以將詳細一點嗎05-01 16:43
游隼
其實聽你講感覺一切都運作得很良好05-01 16:43
001
我目前全關掉然後去nginx確定sever關了之後只用 node xxx.js然後一樣還是一樣問題terminal會有console.log的東西,但line沒有丟訊息出來,nohup的log這個我不太懂意思第一次用,抱歉,我要查一下

05-01 16:47

游隼
沒關係先不用管那個 用nohup在同一個目錄底下就會產生他的log檔05-01 16:49
游隼
上面回的有點亂 我這邊回好了
不用背景執行的狀況;
用console.log可以接到你傳的東西
然後不會回也沒有跳error是這樣嗎?

05-01 16:48

001
line那邊掛掉的意思就是user跟line bot講話,應該要回我設定的訊息,但卻沒有任何訊息丟回給user,有確定server運行中,Webhook URL測試也正常(按verify後有success),在VM裡面的terminal也有反應。

05-01 16:50

游隼
你的VM的terminal 有反應是指可以秀出你傳的訊息嗎?05-01 16:52
001
對我有寫console.log要秀出line那邊該回傳什麼訊息給user,代表有接收到user的訊息,也正確回傳對應的訊息,不過line視窗那邊的line bot就毫無回應...拍謝我解釋得不是很清楚

05-01 16:55

游隼
其實我覺得一切都沒問題欸05-01 16:55
游隼
你是用你自己的程式嗎?05-01 16:56
游隼
先用官方的echo範例檔測一下05-01 16:56
游隼
如果官方的OK 你之前在heroku上的不行可能就是SDK套件版本不一樣05-01 16:57
游隼
npm裝個之前你在heroku上的版本試試05-01 16:57
001
我也覺得很怪阿,server沒問題,webhook url也檢查過了...之前用heroku的話是正常,不過搬到oracle cloud的vm,line本身那邊就有問題了...

05-01 16:58

001
我沒有用SDK寫echo,不過現在正在試試看把一開始它教學給的echo貼上我的程式試試看。

05-01 16:59

游隼
npm install @line/bot-sdk --save
^^這行就是裝sdk

你之前的程式應該也有用SDK
不然所有的動作都要包成HTTP Request才能回傳給Line05-01 17:05
游隼
我在想可能是你舊的程式用的sdk版本不一樣05-01 17:06
001
"不然所有的動作都要包成HTTP Request才能回傳給Line" 我現在就是這樣做沒錯,官網上一開始是這樣教,我就照著寫下去,然後我把全部的功能跟回應都包成request,我應該是沒用到SDK才對?

05-01 17:08

游隼
是喔@@ 一般在寫都會用SDK比較方便 你是照這篇做的話的確是沒用SDK https://developers.line.biz/en/docs/messaging-api/nodejs-sample/#start-developing
05-01 17:33
001
我好像發現問題在哪裡了...應該是VM那邊沒有Channel access token,因為我把token放在.env然後gitignore了,現在在想我要怎樣在我pull下來的資料夾裡面加上.env檔然後把access token加進去,理論上這樣應該可行?XD

05-01 17:37

游隼
我沒這樣試過 不過印象中 dotenv 可以辦到
我都直接存在env.json然後git 設ingnore而已05-01 17:43
001
抱歉真的是我耍蠢,用vim把access token直接寫進去原本的程式裡面就正常了!!!

05-01 17:54

游隼
也可以 不過這樣就不要傳到github上05-01 18:08
andyfish
超級受用!必須讚一個,太感謝大大分享了
之前一直使用heroku來部屬linebot,但想要多開發一些功能時就覺得能部屬在VPS上就好了,但苦於網路的知識不足,nginx的 reverse proxy 卡了很久,config不知道怎麼寫才是對了,看到大大的例子後終於弄懂了!

06-13 23:43

游隼
恭喜 有其他問題可以儘量問我~06-13 23:50
永武Canyue
您好
想請問一下
我最近在開發line api 我把flask api 包成docker port3000
然後用nginx 反向代裡 我的ssl與domain name並proxy_pass http://ip:3000

但當我在Webhook URL輸入
https://domain name/webhook
卻出現An SSL connection error occurred. For more information, see SSL/TLS specification of the webhook source in the Messaging API documentation.

確認過api有正常運作,ssl與網域名都有對ip與沒過期與TWCA簽發
已經沒招了,想訊問還有什麼我沒發現的問題,感謝您

02-28 20:15

我要留言提醒:您尚未登入,請先登入再留言

6喜歡★ding890326 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:TEST... 後一篇:【line.gs BOT...

追蹤私訊切換新版閱覽

作品資料夾

dhreekingdon幸運看見的你
給你一顆紅心~讓你能保有一整天的好心情~祝你有個愉快的一天喲(<ゝω・)~❤看更多我要大聲說昨天20:38


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】