iT邦幫忙

2018 iT 邦幫忙鐵人賽
23
Modern Web

只要有心,人人都可以做卡米狗系列 第 31

只要有心,人人都可以作卡米狗 - 完賽心得

參加感想

其實一開始參加的時候是想說反正隨時棄坑都沒關係,至少我有開始過。但沒想到讀者比我預想的還要多,情況有點不受控制,我似乎不得不把質跟量都作出來,不然就會辜負這些讀者。不過也感謝大家的支持,我才能順利完賽,在沒有任何文章存稿的情況下參賽,連我都不相信我能完賽。

讀者群的設定

因為卡米狗粉都是沒有接觸資訊領域,不會寫程式的人,所以在我寫文的一開始,就把讀者群設定在電腦只有開過 IE、只安裝過 MMORPG 的等級。要從檔案總管和記事本教起,這件事比我一開始想像中的還要累。在講到任何知識之前,我都得要先想一下,我應該要假設讀者已經學過了嗎?如果我這裡跳過不講,讀者會不會放棄治療,一輩子卡關在這裡呢?還是說我不應該講這麼細節的東西,應該讓讀者用肌肉記憶就好?我是覺得如果我不講,讀者放棄治療的機率很高啦。

對於 iT邦幫忙既有的讀者來說,我設定的讀者群程度可能就太淺了,抱歉占用到你們的版面。不過,我從一開始就不是打算寫給你們(工程師們)看的。

關於選題

只要有心,人人都可以作卡米狗,這個選題已經說明了讀者群的設定就是麻瓜。而聊天機器人說穿了就是個只有後端的網站,製作難度肯定低於架網站,我只需要確保每個讀者都懂 HTTP 協定,並且會架 HTTP Server 即可。主要目標是讓讀者看完之後能夠有基礎的網站概念,開始能看得懂工程師寫的技術文章,以及知道遇到問題時要在 GOOGLE 輸入什麼關鍵字的能力。

關於文章內容的編排

我首篇先講什麼是聊天機器人,並以卡米狗舉例說明,當然也是為了置入一波卡米狗。

在我作任何教學之前,我會希望讀者能夠先知道為什麼他要學這個,所以我選擇採用從上而下的講解方式,先講最大的框架是由什麼構成,接下來再去認識細節和實作的部分,而每一個實作的部分都是遇到才教。我就是怕我一教難的你們就跑了。

如果我今天第一篇開頭就說,我們要用 sublime、ruby、rails、git、heroku 哦~先安裝吧,然後前面10篇都在安裝,這樣的編排真的有人讀得下去嗎?我很懷疑。我認為要讓讀者能夠在初期就取得巨大的成就感,讀者才會有信心能夠跟著文章走下去。所以我在第三篇就讓讀者建立一個 Line chatbot 帳號,而且可以講一些廢話。後面花了20篇的篇幅在教怎麼作出跟 Line@ 提供的後台一模一樣的東西。

不過這樣的篇排有個缺點,就是不能跳著讀。

目錄

大致的切分如下:

基本觀念的建立

從聊天機器人帶到 Webhook,再帶到 HTTP 協定以及 Web Server。
第一天:認識聊天機器人
第二天:認識卡米狗
第三天:作一隻最簡單的 Line 聊天機器人
第四天:認識 Webhook
第五天:認識 Line Messaging API Webhook
第六天:認識網站
第七天:認識網頁伺服器

開發環境的建立

從 Web Server 帶到 Rails,再帶到 Command Line、Sublime Text
第八天:安裝 Rails 和認識小黑框
第九天:作一個最簡單的 Rails 網站
第十天:認識文字編碼
第十一天:認識文字編輯器

HTTP 協定的深入了解

從各個角度了解 HTTP,從瀏覽器發送和接收、也從網站伺服器發送和接收
第十二天:從瀏覽器認識 HTTP 協定
第十三天:認識 Ruby 的資料型態
第十四天:最基本的 Rails 運作流程
第十五天:從 Rails 認識 HTTP 協定
第十六天:做一個最簡單的爬蟲

發布環境的建立

介紹發布環境,帶到 Heroku 和 Git
第十七天:怎麼讓別人連到我作好的網站?
第十八天:發布網站到 Heroku
第十九天:發布網站到 Heroku (續)

LINE API 的串接

基礎知識備齊,終於來到正題。讀者設定為一般工程師的話,第一篇大概會從這邊開始寫起。
第二十天:串接 Line Messaging API Webhook
第二十一天:讓 Line Bot 回覆訊息
第二十二天:用 Line Messaging API 實作關鍵字回覆

資料庫的操作

缺乏的一塊基礎知識,因為得在這個階段才能感受到為什麼需要資料庫,所以選擇在這個時候才講。寫給工程師看的話,這兩篇大概就略過了。
第二十三天:認識資料庫
第二十四天:認識資料庫(續)

學習成果的應用

這是大家想看的部分
第二十五天:卡米狗學說話
第二十六天:卡米狗推齊
第二十七天:卡米狗見人說人話,見鬼說鬼話
第二十八天:建立管理後台
第二十九天:卡米狗發公告
第三十天:卡米狗查天氣

關於開發環境

選擇在 windows 上開發 rails,而不是選在 macbook 上開發,是因為我認為大多數一般人家裡沒有 macbook,為了降低進入障礙,所以選擇在 windows 上開發,我的卡米狗從一開始就是在 macbook 上開發的,而在我寫文之前,我沒有用過 windows 開發過 rails。選擇用 windows 開發,在後期確實是導致比較多的障礙。不過讀者們會因為這樣而去安裝 linux 或者買一台 macbook 嗎?

關於瀏覽量

老實講,最前面的三篇文章我有在卡米狗上面發公告宣傳,成效不錯。但每次發公告,好友人數就掉1%是蠻傷的,應該要作個訂閱機制,針對那些有在 LINE 上訂閱系列文的人,我再每天 PUSH 就好。不過文章寫到一半也沒那個心力去加功能就是了。不過後面有兩篇莫名4千多,我是懷疑有別人在洗我的瀏覽量。

最後

在這裡感謝那些留言給我的人,不論你們是提出問題,或回報錯誤,或感謝我,你們都能幫助到我。之後可能會把在這三十篇裡面沒提到的,關於 Line Messaging API 部分也講一講,像是 imagemap messagetemplate message 這種比較酷炫的功能。

以下開放許願,我考慮有時間的時候再回來講講。


上一篇
第三十天:卡米狗查天氣
下一篇
系統不讓我回文惹
系列文
只要有心,人人都可以做卡米狗33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
5
QQBoxy
iT邦新手 1 級 ‧ 2018-01-23 15:37:52

恭喜米大完賽,
感謝細心製作教學文章。

/images/emoticon/emoticon41.gif

2
s12873514
iT邦新手 5 級 ‧ 2018-01-23 15:54:37

恭喜完賽,感謝你詳細的教學文章

不過還想知道幾件事情
1.關於發公告的設定能詳細說明嗎,假如輸入了A群組的ID跟B群組的ID後發了公告
下次發公告也是A跟B群組一起發??可以在每次發完之後設定值RESET?
2.想知道「卡米狗壞壞」「卡米狗安靜/說話」這兩個的寫法

目前教的發公告程式是對所有 channel 都發公告,所以並沒有講到有關於指定 channel 發公告的部分。

請問你說的輸入 A群組的ID跟B群組的ID 是在那裡輸入?

s12873514 iT邦新手 5 級 ‧ 2018-01-23 19:40:30 檢舉

卡卡米
疑?原來是對全部channel發喔,因為我在程式碼裡面有看到channel_ID跟text,我以為是要先輸入channel_ID再輸入text,哈哈

channel_ID我是從Keyword_mapping那邊看到的

XD

0
lee98064
iT邦新手 5 級 ‧ 2018-01-23 17:40:06

恭喜卡米大完賽,也感謝你的教學文章讓我學到不少~

然後想問一下
1.不同的Heroku專案的資料庫是否能共用同一個?
2.然後卡米狗也可以串接到FB的Messenger嗎?

/images/emoticon/emoticon41.gif

看更多先前的回應...收起先前的回應...
  1. 可以
  2. 可以 我也有串 https://m.me/kamigo01
lee98064 iT邦新手 5 級 ‧ 2018-01-23 17:58:25 檢舉

那想請問一下共用資料庫的方法是?

lee98064 iT邦新手 5 級 ‧ 2018-01-23 18:07:37 檢舉

OK~~
謝謝卡米大~
/images/emoticon/emoticon41.gif

1
nienst
iT邦新手 5 級 ‧ 2018-01-23 19:23:04

感謝米大深入淺出的教學

看更多先前的回應...收起先前的回應...

/images/emoticon/emoticon41.gif

nienst iT邦新手 5 級 ‧ 2018-04-30 00:03:42 檢舉

之前安裝的 防翻機器人 只能有一個群主可以下指令
多人共同管理時 就顯得不方便

昨天測試 讓BOT 當群主
其他管理者 可以對BOT下指令 控制防翻功能
感覺挺方便的

另外,一個群只能有一隻BOT...
我想用之前卡米大大教的 "用網頁發公告的方式"
讓兩隻BOT可以透過 網頁 互相傳遞訊息...
但 不知道要怎麼下手...

兩隻 Bot 互相傳訊息 你可以考慮假裝你自己是 Line Server 把訊息傳給另一個 Bot 的方法

nienst iT邦新手 5 級 ‧ 2018-05-06 23:07:47 檢舉

恩,我目前是在研究怎麼用做爬蟲的方式
把要丟的訊息,透過之前做的公告網頁傳過去
但對網頁語法不懂,還在摸索中

1
UMVUE
iT邦新手 5 級 ‧ 2018-01-23 20:30:08

感謝 從卡米狗的文章獲益良多/images/emoticon/emoticon07.gif

/images/emoticon/emoticon41.gif

0
rin6908
iT邦見習生 ‧ 2018-01-23 20:32:15

我想要請問一下 才能讓卡米狗 記住別人說過的話

2
ray19990613
iT邦新手 5 級 ‧ 2018-01-24 00:36:43

謝謝卡卡米超詳細的教學,
我終於實現我的夢想,
製作出一隻專屬於自己的機器人 :)

/images/emoticon/emoticon12.gif

0
van1770
iT邦新手 5 級 ‧ 2018-01-24 22:21:32

謝謝卡卡米大大,超詳細教學。

這種手把手的教學讓人學起來超無痛,一定下不少心思跟繁瑣的截圖與解說,教學文中也屬少見,很讚!!

/images/emoticon/emoticon41.gif

1
luke90329
iT邦新手 5 級 ‧ 2018-01-26 19:48:08

感謝卡米大這一個月的努力 實現了不少人的願望 也帶給我們許多成就感

不過有幾點問題想問
1.就是關於不同群組間的學說話問題 現在的程式碼是如果在A群組教了一句話
但是在B群組還沒教過的情況下輸入關鍵字還是會跑出A群組教的 所以不知道怎麼讓卡米狗像是新的一樣甚麼都沒學過
2.卡米狗安靜的問題 這邊我想了很多 像是再建立一個模型 然後只有channel ID跟status
當收到關鍵字的時候就改變status 不過這樣好像太麻煩了 所以希望卡米大之後有機會能再講解一下這個部分 感謝

看更多先前的回應...收起先前的回應...

這邊就簡單回復喔 有空的話再用文章完整回應

  1. 修改 https://ithelp.ithome.com.tw/articles/10197234 文章中的 keyword_reply 函數,把最後一行程式碼刪掉即可,你必須要能夠看懂這些程式碼每一行在幹嘛,才能改得動。要不然你只能抄我的程式碼,這樣是不會進步的喔。

  2. 就是你說的那樣

luke90329 iT邦新手 5 級 ‧ 2018-02-05 23:13:23 檢舉

感安卡米大 花了四個小時終於研究出卡米狗安靜 回去把文章複習過一次XD

不過現在還有一個問題就是在一個新的聊天室必須要先說卡米狗講話才能開啟機器人的功能

  def webhook
    # 改變聊天室狀態
    reply_text = change_channel_status(channel_id, received_text)
    
    # 檢測聊天室狀態
    channelstatus = channel_status(channel_id) 
    if channelstatus.nil?
      # 回應 200
      head :ok

      return 
    end

    # 查天氣
    reply_image = get_weather(received_text)

    # 有查到的話 後面的事情就不做了
    unless reply_image.nil?
      reply_text = get_time_from_cwb

      # 傳送圖片到 line
      response = reply_image_to_line(reply_image, reply_text)

      # 回應 200
      head :ok

      return 
    end

    # 紀錄頻道
    Channel.find_or_create_by(channel_id: channel_id)
   
    #發送公告
    reply_text = send_announcement(channel_id, received_text) if reply_image.nil? 

    # 學說話
    reply_text = learn(channel_id, received_text) if reply_text.nil?

    # 關鍵字回覆
    reply_text = keyword_reply(channel_id, received_text) if reply_text.nil?

    # 推齊
    reply_text = echo2(channel_id, received_text) if reply_text.nil?

    # 記錄對話
    save_to_received(channel_id, received_text)
    save_to_reply(channel_id, reply_text)

    # 傳送訊息到 line
    response = reply_to_line(reply_text)

    # 回應 200
    head :ok
  end 

  # 改變聊天室狀態關鍵字
  def change_channel_status(channel_id, received_text)
    return nil unless received_text[0..5] == '卡米熊安靜' or received_text[0..5] == '卡米熊講話'
    ChannelStatus.create(channel_id: channel_id, status: 'quiet') if received_text[0..5] == '卡米熊安靜'
    ChannelStatus.create(channel_id: channel_id, status: 'speak') if received_text[0..5] == '卡米熊講話'
    received_text
  end

  # 檢測聊天室狀態
  def channel_status(channel_id)
    statuses = ChannelStatus.where(channel_id: channel_id).last&.status
    return nil if statuses == 'quiet'
    statuses
  end

不知道這個是卡在哪邊

你的預設值是安靜,可以調整一下預設值

nienst iT邦新手 5 級 ‧ 2018-02-23 22:37:15 檢舉

我也有嘗試這個功能,但感覺一直create,怕資料庫越來越龐大
我想要把 channel_id 當索引,然後去更新 status 的值

有找到一個指令create_or_update 但卻試不出來我要的結果
試了很久試不出來.... 應該是我的指令用法有問題...
ChannelStatus.create_or_update(channel_id: channel_id, status_text: 'quiet')

我是用 Channel.find_or_create_by(channel_id: channel_id)
你可以這樣寫:

channel = Channel.find_or_create_by(channel_id: channel_id)
channel.status = 你要的值
channel.save
nienst iT邦新手 5 級 ‧ 2018-02-24 18:33:04 檢舉

太感謝了~~ 這樣就不怕資料太多了~~
/images/emoticon/emoticon07.gif

3

1/27~2/4 在泰國耍廢,所有回應會在2/5之後回應哦~

看更多先前的回應...收起先前的回應...
van1770 iT邦新手 5 級 ‧ 2018-02-01 23:23:30 檢舉

可以許願教怎麼做抽正妹圖的功能嗎XD

螢光貓 iT邦新手 5 級 ‧ 2018-02-03 00:14:08 檢舉

想學閉嘴的功能~我也想去泰國!!

我只知道卡米狗有正妹圖的功能
看完才知道原來功能很多
對不起開發者

van1770
首先你要弄一隻爬蟲去收集正妹圖的連結,當然他最好一開始就是可以直接被 line 接受的格式,也就是 https 的圖床。

然後你可以參考 第三十天:卡米狗查天氣 傳送圖片的方法去傳送圖片。

haaaiamjoy
需要在 channel 上紀錄每個 channel 是不是正在安靜狀態,如果是安靜狀態就略過所有功能。
泰國好好玩哦~

lovesharepc
卡米狗沒有正妹圖的功能喔,因為怕被告所以這種功能我都不敢作呢

van1770 iT邦新手 5 級 ‧ 2018-02-13 00:06:45 檢舉

謝謝卡米大回覆~ 我再來研究看看

0
ds910258
iT邦新手 5 級 ‧ 2018-02-05 15:23:33

請問如果像是關鍵字設定「早安」

但想要讓「早安阿」「早安呀」...等等有「早」「安」兩字的都被判斷到

是不是只能把收到的訊息切開讀字元?

有沒有更簡單的方式呢?

有很多更難的方式喔!

ds910258 iT邦新手 5 級 ‧ 2018-02-05 16:57:46 檢舉

感謝回覆,
所以切開讀字元已經是最簡單了嗎QQ

對呀

0
lee98064
iT邦新手 5 級 ‧ 2018-02-07 20:07:24

有問題想問卡米大
我今天在做資料庫遷移時(Heroku上的)
卻出現No File !?
想問要如何跳過或刪除那個No File 因為遷移卡在那邊就沒法下一步了

本地端遷移沒出現No File 在Heroku上才出現,剛剛查Google後有人用
heroku run rake db:reset 但資料會消失
有方法能讓資料不消失但刪除No File嗎?

D:\機器人\ironman公開>heroku run rails db:migrate:status
Running rails db:migrate:status on kamicat-line... up, run.5790 (Free)

database: d5kadmc1d54hqr

 Status   Migration ID    Migration Name
--------------------------------------------------
D, [2018-02-07T11:59:47.063899 #4] DEBUG -- :    (1.3ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
   up     20180115132118  Create keyword mappings
   up     20180115133730  Create receiveds
   up     20180115133740  Create replies
   up     20180115134724  Add channel id to keyword reply
   up     20180116101004  Devise create users
   up     20180118081505  Create channels
   up     20180207093537  ********** NO FILE **********
  down    20180207095422  Create channel statuses

就把 file 補上就可以惹

lee98064 iT邦新手 5 級 ‧ 2018-02-07 21:08:33 檢舉

ok了,謝謝卡米大~
/images/emoticon/emoticon41.gif

0
nienst
iT邦新手 5 級 ‧ 2018-03-13 18:24:50

GG了.... 免費配額 負兩百多小時....
創另一個帳號 資料庫應該都會消失吧...
要再研究一下 資料庫怎麼被分和轉移了...
/images/emoticon/emoticon02.gif

Free dyno hours quota remaining this month: -275h -51m (-50%)
For more information on dyno sleeping and how to upgrade, see:
https://devcenter.heroku.com/articles/dyno-sleeping

=== web (Free): bin/rails server -p $PORT -e $RAILS_ENV (1)
web.1: idle 2018/03/13 18:05:40 +0800 (~ 8m ago)

看更多先前的回應...收起先前的回應...

哇 信用卡登記一下可以多250小時吧?

nienst iT邦新手 5 級 ‧ 2018-03-13 18:59:50 檢舉

原來他三田前有通知我 都被我忽視 ㄎㄎ 我登記看看
感謝卡米大大

如果您使用信用卡驗證您的帳戶,您可以每月獲得450多個免費的Dyno時間。
一個或多個免費的Dyno應用程序正變得越來越流行。將您的應用程序升級到Hobby dynos,每月7美元的代碼,這樣它就不會睡覺,用戶可以全天候使用它。

nienst iT邦新手 5 級 ‧ 2018-03-13 19:00:30 檢舉

只是登記 應該不會自動扣款之類的吧 ㄎㄎ

nienst iT邦新手 5 級 ‧ 2018-03-13 19:08:47 檢舉

登記完了 扣掉欠的兩百多小時 還剩一百多小時

Free dyno hours quota remaining this month: 175h 9m (17%)
For more information on dyno sleeping and how to upgrade, see:
https://devcenter.heroku.com/articles/dyno-sleeping

=== web (Free): bin/rails server -p $PORT -e $RAILS_ENV (1)
web.1: idle 2018/03/13 18:05:40 +0800 (~ 1h ago)

nienst iT邦新手 5 級 ‧ 2018-03-13 19:18:32 檢舉

疑? 已經增加配額,也重新啟動過
BOT還是出現一樣的錯誤

2018-03-13T11:16:41.669048+00:00 heroku[router]: at=info code=H82 desc="Free app
running time quota exhausted" method=POST path="/kamigo/webhook" host=nien-love
-kamigo.herokuapp.com request_id=4ec2ea4e-7bab-4bfb-9e74-4caa614632f6 fwd="203.1
04.146.154" dyno= connect= service= status=503 bytes= protocol=https

試試看 heroku restart

nienst iT邦新手 5 級 ‧ 2018-03-15 21:37:57 檢舉

恩恩 試過了
也試者在heroku的網頁上執行 Restart all dynos
結果也是一樣
本想試著調整配額,但免費的無法調整

我後來先創另一個帳號 把程式搬過去了

nienst iT邦新手 5 級 ‧ 2018-03-15 23:42:32 檢舉

2018-03-15T15:40:29.945575+00:00 heroku[web.1]: State changed from down to starting
2018-03-15T15:40:37.221666+00:00 heroku[web.1]: Starting process with command bin/rails server -p 38007 -e production
2018-03-15T15:40:45.372742+00:00 heroku[web.1]: State changed from starting to up
2018-03-15T15:40:45.383045+00:00 heroku[web.1]: Idling
2018-03-15T15:40:45.383045+00:00 heroku[web.1]: State changed from up to down
2018-03-15T15:40:45.397485+00:00 heroku[web.1]: Idling because quota is exhausted
2018-03-15T15:40:45.203411+00:00 app[web.1]: => Booting Puma
2018-03-15T15:40:45.203474+00:00 app[web.1]: => Rails 5.1.5 application starting in production
2018-03-15T15:40:45.203476+00:00 app[web.1]: => Run rails server -h for more startup options
2018-03-15T15:40:45.203482+00:00 app[web.1]: Puma starting in single mode...
2018-03-15T15:40:45.203484+00:00 app[web.1]: * Version 3.11.3 (ruby 2.3.4-p301), codename: Love Song
2018-03-15T15:40:45.203490+00:00 app[web.1]: * Min threads: 5, max threads: 5
2018-03-15T15:40:45.203492+00:00 app[web.1]: * Environment: production
2018-03-15T15:40:45.203493+00:00 app[web.1]: * Listening on tcp://0.0.0.0:38007
2018-03-15T15:40:45.203495+00:00 app[web.1]: Use Ctrl-C to stop
2018-03-15T15:40:46.541036+00:00 heroku[web.1]: Stopping all processes with SIGTERM
2018-03-15T15:40:46.573119+00:00 app[web.1]: - Gracefully stopping, waiting for requests to finish
2018-03-15T15:40:46.584668+00:00 app[web.1]: === puma shutdown: 2018-03-15 15:40:46 +0000 ===
2018-03-15T15:40:46.584720+00:00 app[web.1]: - Goodbye!
2018-03-15T15:40:46.584870+00:00 app[web.1]: Exiting
2018-03-15T15:40:46.713674+00:00 heroku[web.1]: Process exited with status 143

0
herobt
iT邦見習生 ‧ 2018-04-14 23:23:26

想問一下 手機版要怎麼做後續的功能 因為我已經創好一隻了 可是後面的還不會

請問你說的手機板是什麼呢?

0
nienst
iT邦新手 5 級 ‧ 2019-06-19 21:04:09

今天LINE 更新後
PUSH_MESSAGE 無法發出訊息了

看更多先前的回應...收起先前的回應...

trial 的 push 免費使用次數在改版後降為 一個月 500 次

nienst iT邦新手 5 級 ‧ 2019-06-24 23:47:24 檢舉

恩...500 好少....
考慮改用微信BOT是看看好了

telegram 不錯

nienst iT邦新手 5 級 ‧ 2019-06-26 19:25:33 檢舉

恩恩 我兩個都試看看

1
rchin
iT邦新手 5 級 ‧ 2019-08-14 17:41:02

感謝卡米狗一連串的教學,由於連假要跟朋友們到外島玩,但有些人搶到的機票時間不太好
所以用了 LineBot + Node.js + Heroku 完成了查詢特定航班的機票
若一有機票,LineBot 才會推送通知到群組,一個月基本上應該不會超過 500 則訊息
每十分鐘發一組 Request,應該也不會被航空公司網站當作是惡意請求
另外這組 Request 也包含 Heroku 的首頁,所以照理來說 App 不會超過三十分閒置而被休眠
配合 Heroku 的勞基法,凌晨 00~08 會讓整組 App 休息
參考了部份文章,實作成功後成就感爆棚,期待航空公司若有釋票,朋友們能順利搶到 /images/emoticon/emoticon12.gif

太神啦~

我要留言

立即登入留言