iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 22
5
Modern Web

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

第二十二天:用 Line Messaging API 實作關鍵字回覆

今天我要讓你能抓到一點寫程式的感覺,所以我們會一直不斷地修改程式碼,這麼做可以讓你對程式碼的操作更熟悉。

先從最簡單的功能開始作,今天的目標是讓卡米狗能針對關鍵字回應訊息。

程式碼的重構

在加程式碼之前,我們先整理一下目前的程式

  def webhook
    # Line Bot API 物件初始化
    client = Line::Bot::Client.new { |config|
      config.channel_secret = '9160ce4f0be51cc72c3c8a14119f567a'
      config.channel_token = '2ncMtCFECjdTVmopb/QSD1PhqM6ECR4xEqC9uwIzELIsQb+I4wa/s3pZ4BH8hCWeqfkpVGVig/mIPDsMjVcyVbN/WNeTTw5eHEA7hFhaxPmQSY2Cud51LKPPiXY+nUi+QrXy0d7Hi2YUs65B/tVOpgdB04t89/1O/w1cDnyilFU='
    }
    
    # 取得 reply token
    reply_token = params['events'][0]['replyToken']

    # 設定回覆訊息
    message = {
      type: 'text',
      text: '好哦~好哦~'
    }

    # 傳送訊息
    response = client.reply_message(reply_token, message)
      
    # 回應 200
    head :ok
  end 

目前程式碼是這樣,我覺得有點太長了,我們要讓他更好閱讀。首先要制定一個目標。

  def webhook
    # 核心程式
    reply_message = reply(received_message)

    # 回覆訊息
    reply_to_line(message)

    # 回應 200
    head :ok
  end 

只保留最重要的,當卡米狗看到 received_message 時,要回應 reply_message,剩下的東西都放到別處。我們先假設卡米狗只會對純文字有反應,並且只會回應純文字。

移出 client

    # Line Bot API 物件初始化
    client = Line::Bot::Client.new { |config|
      config.channel_secret = '9160ce4f0be51cc72c3c8a14119f567a'
      config.channel_token = '2ncMtCFECjdTVmopb/QSD1PhqM6ECR4xEqC9uwIzELIsQb+I4wa/s3pZ4BH8hCWeqfkpVGVig/mIPDsMjVcyVbN/WNeTTw5eHEA7hFhaxPmQSY2Cud51LKPPiXY+nUi+QrXy0d7Hi2YUs65B/tVOpgdB04t89/1O/w1cDnyilFU='
    }
    

我們把這段程式搬出去,變成這樣:

  # Line Bot API 物件初始化
  def line
    client = Line::Bot::Client.new { |config|
      config.channel_secret = '9160ce4f0be51cc72c3c8a14119f567a'
      config.channel_token = '2ncMtCFECjdTVmopb/QSD1PhqM6ECR4xEqC9uwIzELIsQb+I4wa/s3pZ4BH8hCWeqfkpVGVig/mIPDsMjVcyVbN/WNeTTw5eHEA7hFhaxPmQSY2Cud51LKPPiXY+nUi+QrXy0d7Hi2YUs65B/tVOpgdB04t89/1O/w1cDnyilFU='
    }
  end

定義一個方法叫作 line,他會回傳一個 client。這裡可以省略區域變數 client 不寫。

  # Line Bot API 物件初始化
  def line
    Line::Bot::Client.new { |config|
      config.channel_secret = '9160ce4f0be51cc72c3c8a14119f567a'
      config.channel_token = '2ncMtCFECjdTVmopb/QSD1PhqM6ECR4xEqC9uwIzELIsQb+I4wa/s3pZ4BH8hCWeqfkpVGVig/mIPDsMjVcyVbN/WNeTTw5eHEA7hFhaxPmQSY2Cud51LKPPiXY+nUi+QrXy0d7Hi2YUs65B/tVOpgdB04t89/1O/w1cDnyilFU='
    }
  end

這麼寫的話,每次呼叫 line 時,就都會去作一次 Line::Bot::Client.new。我們可以把它保存起來,第二次呼叫 line 的時候就把保存起來的部分拿出來用,這樣作可以增加效能。

  # Line Bot API 物件初始化
  def line
    return @line unless @line.nil?
    @line = Line::Bot::Client.new { |config|
      config.channel_secret = '9160ce4f0be51cc72c3c8a14119f567a'
      config.channel_token = '2ncMtCFECjdTVmopb/QSD1PhqM6ECR4xEqC9uwIzELIsQb+I4wa/s3pZ4BH8hCWeqfkpVGVig/mIPDsMjVcyVbN/WNeTTw5eHEA7hFhaxPmQSY2Cud51LKPPiXY+nUi+QrXy0d7Hi2YUs65B/tVOpgdB04t89/1O/w1cDnyilFU='
    }
  end

如果 @line 有值的話,直接回傳 @line,沒有值的話才作 Line::Bot::Client.new 並保存到 @line

這裡用到了 @@ 開頭的變數是實體變數,跟區域變數不同的是,實體變數的記憶比較持久,區域變數只要函數執行完就消失,但實體變數可以持續存活到第二次之後的函數執行,甚至我可以在A函數保存實體變數,在B函數去使用實體變數。

關於實體變數,詳細的教學請參考:為你自己學 Ruby on Rails - 變數、常數、流程控制、迴圈

現在的程式已經足夠完美了,但有更精簡的寫法。

  # Line Bot API 物件初始化
  def line
    @line ||= Line::Bot::Client.new { |config|
      config.channel_secret = '9160ce4f0be51cc72c3c8a14119f567a'
      config.channel_token = '2ncMtCFECjdTVmopb/QSD1PhqM6ECR4xEqC9uwIzELIsQb+I4wa/s3pZ4BH8hCWeqfkpVGVig/mIPDsMjVcyVbN/WNeTTw5eHEA7hFhaxPmQSY2Cud51LKPPiXY+nUi+QrXy0d7Hi2YUs65B/tVOpgdB04t89/1O/w1cDnyilFU='
    }
  end

|| 是或的意思,這是一個很特殊的寫法,跟原本的程式碼效果幾乎相同,我就不多作解釋。沒學會 ||= 也沒關係,這就是工程師der浪漫。

目前的完整程式碼如下:

require 'line/bot'
class KamigoController < ApplicationController
  protect_from_forgery with: :null_session

  def webhook    
    # 取得 reply token
    reply_token = params['events'][0]['replyToken']
    
    # 設定回覆訊息
    message = {
      type: 'text',
      text: '移出 client'
    }

    # 傳送訊息
    response = line.reply_message(reply_token, message)
      
    # 回應 200
    head :ok
  end 
  
  # Line Bot API 物件初始化
  def line
    @line ||= Line::Bot::Client.new { |config|
      config.channel_secret = '9160ce4f0be51cc72c3c8a14119f567a'
      config.channel_token = '2ncMtCFECjdTVmopb/QSD1PhqM6ECR4xEqC9uwIzELIsQb+I4wa/s3pZ4BH8hCWeqfkpVGVig/mIPDsMjVcyVbN/WNeTTw5eHEA7hFhaxPmQSY2Cud51LKPPiXY+nUi+QrXy0d7Hi2YUs65B/tVOpgdB04t89/1O/w1cDnyilFU='
    }
  end
  
  ...下略
end

改到這邊可以上傳程式碼測試一下,如果你不測也沒關係,因為我們還要繼續改。

移出 reply token

我們作一個函數,讓他自己去抓 reply token,我們關心的是要發什麼話,不關心 reply_token,所以我希望我們的主程式能變成這樣。

  def webhook   
    # 設定回覆訊息
    message = {
      type: 'text',
      text: '移出 reply_token'
    } 

    # 傳送訊息
    response = reply_to_line(message)
      
    # 回應 200
    head :ok
  end 

所以我們要實作函數 reply_to_line,他是一個傳入 message 後,透過 line api 傳送訊息出去,並傳回 HTTP response 的函數。

  # 傳送訊息到 line
  def reply_to_line(message)
    # 取得 reply token
    reply_token = params['events'][0]['replyToken']
    
    # 傳送訊息
    response = line.reply_message(reply_token, message)
  end

可以再精簡為:

  # 傳送訊息到 line
  def reply_to_line(message)
    # 取得 reply token
    reply_token = params['events'][0]['replyToken']
    
    # 傳送訊息
    line.reply_message(reply_token, message)
  end

因為一個函數的傳回值是最後一行的執行結果。這就是工程師der浪漫。

其實我們大部分時間在作的事情都是搬移程式,其實寫程式就是一種整理的藝術。

你可以想像成我們東西一開始全都放在客廳。東西越來越多之後,客廳就會開始變亂。要整理客廳的方法就是買幾個櫃子後把東西放進櫃子。函數就是我們的櫃子。

目前的完整程式碼如下:

require 'line/bot'
class KamigoController < ApplicationController
  protect_from_forgery with: :null_session

  def webhook   
    # 設定回覆訊息
    message = {
      type: 'text',
      text: '移出 reply_token'
    } 

    # 傳送訊息
    response = reply_to_line(message)
      
    # 回應 200
    head :ok
  end 

  # 傳送訊息到 line
  def reply_to_line(message)
    # 取得 reply token
    reply_token = params['events'][0]['replyToken']
    
    # 傳送訊息
    line.reply_message(reply_token, message)
  end

  # Line Bot API 物件初始化
  def line
    @line ||= Line::Bot::Client.new { |config|
      config.channel_secret = '9160ce4f0be51cc72c3c8a14119f567a'
      config.channel_token = '2ncMtCFECjdTVmopb/QSD1PhqM6ECR4xEqC9uwIzELIsQb+I4wa/s3pZ4BH8hCWeqfkpVGVig/mIPDsMjVcyVbN/WNeTTw5eHEA7hFhaxPmQSY2Cud51LKPPiXY+nUi+QrXy0d7Hi2YUs65B/tVOpgdB04t89/1O/w1cDnyilFU='
    }
  end

  ...下略

end

移出 message

這是現在的主程式:

  def webhook   
    # 設定回覆訊息
    message = {
      type: 'text',
      text: '移出 reply_token'
    } 

    # 傳送訊息
    response = reply_to_line(message)
      
    # 回應 200
    head :ok
  end 

我不希望在主程式看到這些:

{
  type: 'text',
  text: 'ㄅㄌㄅㄌㄅㄌ'
} 

因為我們只在乎 'ㄅㄌㄅㄌㄅㄌ' 的部分,所以剩餘的部分都要盡量外移。這就像你不會想把垃圾放在桌上一樣,找個垃圾桶放垃圾就對了。

設定目標:

  def webhook   
    # 設定回覆訊息
    reply_text = '移出 message'

    # 傳送訊息
    response = reply_to_line(reply_text)
      
    # 回應 200
    head :ok
  end 

這就是我們所希望的樣子,因此我們要修改 reply_to_line 這個函數。

  # 傳送訊息到 line
  def reply_to_line(reply_text)
    # 取得 reply token
    reply_token = params['events'][0]['replyToken']
    
    # 設定回覆訊息
    message = {
      type: 'text',
      text: reply_text
    } 

    # 傳送訊息
    line.reply_message(reply_token, message)
  end

其實就是把一開始的程式整個全搬到 reply_to_line

目前的完整程式碼如下:

require 'line/bot'
class KamigoController < ApplicationController
  protect_from_forgery with: :null_session

  def webhook
    # 設定回覆文字
    reply_text = '移出 message'
    
    # 傳送訊息到 line
    response = reply_to_line(reply_text)
    
    # 回應 200
    head :ok
  end 

  # 傳送訊息到 line
  def reply_to_line(reply_text)
    # 取得 reply token
    reply_token = params['events'][0]['replyToken']
    
    # 設定回覆訊息
    message = {
      type: 'text',
      text: reply_text
    } 

    # 傳送訊息
    line.reply_message(reply_token, message)
  end

  # Line Bot API 物件初始化
  def line
    @line ||= Line::Bot::Client.new { |config|
      config.channel_secret = '9160ce4f0be51cc72c3c8a14119f567a'
      config.channel_token = '2ncMtCFECjdTVmopb/QSD1PhqM6ECR4xEqC9uwIzELIsQb+I4wa/s3pZ4BH8hCWeqfkpVGVig/mIPDsMjVcyVbN/WNeTTw5eHEA7hFhaxPmQSY2Cud51LKPPiXY+nUi+QrXy0d7Hi2YUs65B/tVOpgdB04t89/1O/w1cDnyilFU='
    }
  end

  ...下略

end

現在的主程式已經比一開始乾淨許多,這時我們再來加功能,應該就會比較容易看出我們在加什麼功能。我們要加的功能是關鍵字回覆。

關鍵字回覆

我們希望主程式可以變成這樣:

  def webhook
    # 設定回覆文字
    reply_text = keyword_reply(received_text)

    # 傳送訊息到 line
    response = reply_to_line(reply_text)
    
    # 回應 200
    head :ok
  end 

所以我們需要兩個函數,一個是 received_text:傳回對方說的話,另一個函數是 keyword_reply:傳入對方說的話,傳回卡米狗應該說的話。

這種思考邏輯是先決定程式的大架構,再來描述細節。這就像在畫圖的時候,你會先打個草稿,草稿看起來OK了再去畫細節,這樣可以確保你不會太專注於細節而失去了整體比例。

  # 取得對方說的話
  def received_text
    params['events'][0]['message']['text']
  end

  # 關鍵字回覆
  def keyword_reply(received_text)
    received_text
  end

現在這樣就表示你說什麼,卡米狗就會跟著說什麼。

目前完整的程式碼如下:

require 'line/bot'
class KamigoController < ApplicationController
  protect_from_forgery with: :null_session

  def webhook
    # 設定回覆文字
    reply_text = keyword_reply(received_text)

    # 傳送訊息到 line
    response = reply_to_line(reply_text)
    
    # 回應 200
    head :ok
  end 

  # 取得對方說的話
  def received_text
    params['events'][0]['message']['text']
  end

  # 關鍵字回覆
  def keyword_reply(received_text)
    received_text
  end

  ...下略
end

這程式碼可以運作,你可以上傳程式碼玩玩看。

這兩個函數現在這樣都還算未完成,他們都有一些缺陷。

先講關鍵字回覆。這裡應該要作成看見A回答B,而不是看見A回答A,我們還缺一個學習紀錄表讓卡米狗查。

received_text 的問題是,如果 Line 傳來的通知並不是訊息通知,而是比方說有人加你好友,或邀請你進入群組,或傳送貼圖、圖片、聲音、檔案都可能會導致我們的程式直接掛掉,因為 params['events'][0]['message']['text'] 的值是空值,而我們沒有說當是空值的時候應該怎麼作。

處理 received_text 的空值問題

根據 Line Messaging API 的文件,當有人傳訊息來時,我們才會收到 message 這個 hash,也就是說,下面這行不一定有值。

params['events'][0]['message']

我們應該在他有值的時候才去取 ['text']

  # 取得對方說的話
  def received_text
    message = params['events'][0]['message']
    if message.nil?
      nil
    else
      message['text']
    end
  end

這是我們第一次用到了 if ,當 message.nil? 是空值的時候,我們就會傳回 nil。不是空值的話,就傳回 message['text']

加入一點工程師的浪漫就會變成這樣:

  # 取得對方說的話
  def received_text
    message = params['events'][0]['message']
    message['text'] unless message.nil?
  end

有的時候不用太堅持什麼浪漫,因為這純粹只是工程師的自爽行為。

關鍵字回覆的學習紀錄表

  # 關鍵字回覆
  def keyword_reply(received_text)
    # 學習紀錄表
    keyword_mapping = {
      'QQ' => '神曲支援:https://www.youtube.com/watch?v=T0LfHEwEXXw&feature=youtu.be&t=1m13s',
      '我難過' => '神曲支援:https://www.youtube.com/watch?v=T0LfHEwEXXw&feature=youtu.be&t=1m13s'
    }
    
    # 查表
    keyword_mapping[received_text]
  end

在這裡定義了學習紀錄表 keyword_mapping 之後就作查表。當查表查不到內容的時候,就會傳回 nil。

這表示當查不到內容時,卡米狗應該要不回應,這需要修改其他函數。

  # 傳送訊息到 line
  def reply_to_line(reply_text)
    return nil if reply_text.nil?
    
    # 取得 reply token
    reply_token = params['events'][0]['replyToken']
    
    # 設定回覆訊息
    message = {
      type: 'text',
      text: reply_text
    } 

    # 傳送訊息
    line.reply_message(reply_token, message)
  end

這裡加一行 return nil if reply_text.nil?,當傳入值為空時表示不回應,後面的程式碼就不用作了。

目前完整的程式碼如下:

require 'line/bot'
class KamigoController < ApplicationController
  protect_from_forgery with: :null_session

  def webhook
    # 設定回覆文字
    reply_text = keyword_reply(received_text)

    # 傳送訊息到 line
    response = reply_to_line(reply_text)
    
    # 回應 200
    head :ok
  end 

  # 取得對方說的話
  def received_text
    message = params['events'][0]['message']
    message['text'] unless message.nil?
  end

  # 關鍵字回覆
  def keyword_reply(received_text)
    # 學習紀錄表
    keyword_mapping = {
      'QQ' => '神曲支援:https://www.youtube.com/watch?v=T0LfHEwEXXw&feature=youtu.be&t=1m13s',
      '我難過' => '神曲支援:https://www.youtube.com/watch?v=T0LfHEwEXXw&feature=youtu.be&t=1m13s'
    }
    
    # 查表
    keyword_mapping[received_text]
  end

  # 傳送訊息到 line
  def reply_to_line(reply_text)
    return nil if reply_text.nil?
    
    # 取得 reply token
    reply_token = params['events'][0]['replyToken']
    
    # 設定回覆訊息
    message = {
      type: 'text',
      text: reply_text
    } 

    # 傳送訊息
    line.reply_message(reply_token, message)
  end

  # Line Bot API 物件初始化
  def line
    @line ||= Line::Bot::Client.new { |config|
      config.channel_secret = '9160ce4f0be51cc72c3c8a14119f567a'
      config.channel_token = '2ncMtCFECjdTVmopb/QSD1PhqM6ECR4xEqC9uwIzELIsQb+I4wa/s3pZ4BH8hCWeqfkpVGVig/mIPDsMjVcyVbN/WNeTTw5eHEA7hFhaxPmQSY2Cud51LKPPiXY+nUi+QrXy0d7Hi2YUs65B/tVOpgdB04t89/1O/w1cDnyilFU='
    }
  end


  def eat
    render plain: "吃土啦"
  end 

  def request_headers
    render plain: request.headers.to_h.reject{ |key, value|
      key.include? '.'
    }.map{ |key, value|
      "#{key}: #{value}"
    }.sort.join("\n")
  end

  def response_headers
    response.headers['5566'] = 'QQ'
    render plain: response.headers.to_h.map{ |key, value|
      "#{key}: #{value}"
    }.sort.join("\n")
  end

  def request_body
    render plain: request.body
  end

  def show_response_body
    puts "===這是設定前的response.body:#{response.body}==="
    render plain: "虎哇花哈哈哈"
    puts "===這是設定後的response.body:#{response.body}==="
  end

  def sent_request
    uri = URI('http://localhost:3000/kamigo/eat')
    http = Net::HTTP.new(uri.host, uri.port)
    http_request = Net::HTTP::Get.new(uri)
    http_response = http.request(http_request)

    render plain: JSON.pretty_generate({
      request_class: request.class,
      response_class: response.class,
      http_request_class: http_request.class,
      http_response_class: http_response.class
    })
  end

  def translate_to_korean(message)
    "#{message}油~"
  end

end

用起來的效果是這樣:

那個「讓我想想...」是我們在第三天:作一隻最簡單的 Line 聊天機器人從 Line 後台作的設定,如果你不喜歡可以去後台把它關掉,它在這裡:

今天就講到這,明天講怎麼教卡米狗說話。


上一篇
第二十一天:讓 Line Bot 回覆訊息
下一篇
第二十三天:認識資料庫
系列文
只要有心,人人都可以做卡米狗33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
0
luke90329
iT邦新手 5 級 ‧ 2018-01-11 00:45:51

卡卡米大大你好
我最近都有在看你的系列文 剛剛都進行的很順利 但直到最後面的程式碼部屬crash了
https://ithelp.ithome.com.tw/upload/images/20180111/20107961pbwj4kF5Wg.png
https://ithelp.ithome.com.tw/upload/images/20180111/20107961dDpQNeTLAz.png
不知道是哪邊出了問題 還請多指教 感謝

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

他說你要在 Gemfile 裡面加 gem 'pg'

luke90329 iT邦新手 5 級 ‧ 2018-01-11 17:45:45 檢舉

https://ithelp.ithome.com.tw/upload/images/20180111/20107961rX2Khsfk4k.png
這是detabase的
今天一直想說會不會是因為昨天只打bundle沒打到install才會這樣 可是還是crash了

luke90329 iT邦新手 5 級 ‧ 2018-01-11 19:35:30 檢舉

上國外論壇爬文 終於找到辦法解決 就是把pg降版
gem 'pg', '~> 0.20'
可是不知道這個版本會不會對後續造成甚麼影響

XD 第23天說要改用 sqlite3 了

luke90329 iT邦新手 5 級 ‧ 2018-01-11 21:43:27 檢舉

還好就是一樣在部屬環境上使用0.20 目前23天弄完部屬是沒錯誤

/images/emoticon/emoticon12.gif

0
curry_sun
iT邦新手 5 級 ‧ 2018-01-27 20:43:00
# 取得對方說的話
  def received_text
    message = params['events'][0]['message']
    if message.nil?
      nil
    else
      message['text']
    end
  end

這段程式碼如果沒有加入工程師的浪漫 XD
是不是要變成底下呀?

# 取得對方說的話
  def received_text
    message = params['events'][0]['message']
    if message.nil?
      return nil
    else
      message
    end
  end

在第一次if判定中若為nil的話就直接不做底下並且回傳nil ~
然後message['text']會把回傳訊息設定成nil,超囧
我找錯找好久 QQ,我的都是邏輯錯誤XD

最後一行的 return 可以省略,所以 nil 前面可以不加 return,如果你覺得加了 return 對你來說比較好閱讀,那你就加,也是 OK 的

0
teemok
iT邦新手 5 級 ‧ 2018-06-25 22:23:16
  # 關鍵字回覆
  def keyword_replya(received_text)
    # 學習紀錄表
    i = rand(3)
    if i = 1
      message = {
        type: 'text',
        text: "壞掉拉"
      }
    elsif i = 2
      message = {
        type: 'text',
        text: "不要拉"
      }
    elsif i = 3
      message = {
        type: 'text',
        text: "哪裡錯R"
      }
    end

    keyword_mapping = {
      'QQ' => message,
      '我難過' => '神曲支援:https://www.youtube.com/watch?v=T0LfHEwEXXw&feature=youtu.be&t=1m13s'
    }
    
    # 查表
    keyword_mapping[received_text]
  end

https://i.imgur.com/4983pHN.jpg

請問卡米大大 為什麼這樣子打 QQ 都會沒反應

附上log

0
such0305
iT邦新手 5 級 ‧ 2018-07-08 20:08:08

卡米大,我照著上面的步驟跑(也執行23天的更改了),結果cmd印出了這些錯誤,請問該怎麼解決QAQ
目前機器人也無法做出回應
https://ithelp.ithome.com.tw/upload/images/20180708/20109721Tu0l99hihI.jpg

這些 WARNING 跟機器人無法回應應該是沒關係,我的也有這些,這些是可以解決的,但是過程很複雜,而且不影響機器人功能,所以我就沒有提到。

such0305 iT邦新手 5 級 ‧ 2018-07-09 21:54:41 檢舉

重新審過一遍,發現是line secret打錯XDD
謝謝卡米大~~~~ 可以繼續往下啦

good~

0
40661493
iT邦新手 5 級 ‧ 2018-10-28 17:34:00

請問這樣要怎麼改?https://ithelp.ithome.com.tw/upload/images/20181028/20112757t2vIcXQbRP.png

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

請問你進行了什麼操作之後看到這個錯誤

40661493 iT邦新手 5 級 ‧ 2018-10-28 21:23:00 檢舉

因為bot沒回我,所以我從新回頭做,結果發現代碼顯示500https://ithelp.ithome.com.tw/upload/images/20181028/20112757sBZVKnyLNg.pnghttps://ithelp.ithome.com.tw/upload/images/20181028/20112757fB3lvNvW5v.png

40661493 iT邦新手 5 級 ‧ 2018-10-28 21:29:58 檢舉

原本在21天都正常,到第22天改完程式碼就不行了

當你在 postman 傳遞訊息給你的開發環境時,你傳遞的內容是否跟 line 傳遞給 heroku 的內容一致。

你可以透過 heroku logs -t 來觀察正式環境上的錯誤訊息。

40661493 iT邦新手 5 級 ‧ 2018-10-28 22:00:32 檢舉

錯誤代碼是143,又不一樣了https://ithelp.ithome.com.tw/upload/images/20181028/20112757MZ9PxNxlNb.png

看起來你的 heroku 上是正常運作的

40661493 iT邦新手 5 級 ‧ 2018-11-08 20:01:11 檢舉

但沒給我回應?

40661493 iT邦新手 5 級 ‧ 2018-11-08 20:01:12 檢舉

但沒給我回應?

40661493 iT邦新手 5 級 ‧ 2018-11-08 21:09:02 檢舉

剛又回去重做21天,又不行了,他一直說我方法錯誤,我不知道如何解決,求解,謝謝!!!https://ithelp.ithome.com.tw/upload/images/20181108/20112757p2ttZxlBZw.pnghttps://ithelp.ithome.com.tw/upload/images/20181108/20112757m0qHPE5rgr.pnghttps://ithelp.ithome.com.tw/upload/images/20181108/20112757a8q045YPPi.png

40661493 iT邦新手 5 級 ‧ 2018-11-08 21:10:28 檢舉

不小心多傳了一張一樣的,抱歉

0
freyr949487
iT邦新手 5 級 ‧ 2018-11-18 09:08:16

錯誤500
heroku logs是正常的
line機器人無法回話

https://ithelp.ithome.com.tw/upload/images/20181118/20110243tIuWz6khxb.pnghttps://ithelp.ithome.com.tw/upload/images/20181118/20110243aq2jnQBlah.pnghttps://ithelp.ithome.com.tw/upload/images/20181118/20110243Wqvyu21gvu.pnghttps://ithelp.ithome.com.tw/upload/images/20181118/20110243VOeirIHZNB.png

如果你想要在 postman 測試你的 server ,那麼就要傳遞與 line 相同格式的內容給你的 server

能夠說得再詳細一點?鄙人不才 真的很想解決

  1. 你在 line 上面打字,然後看一下 heroku log,看 line 傳給你什麼東西。

  2. 然後你先試著在 postman 傳遞相同的東西到你的 heroku server

先做到這點

0
acegen
iT邦新手 5 級 ‧ 2018-12-06 19:30:53

請問卡米大,如果我要讓他做
回覆訊息的條件為「只要字句中有包含,就回覆」
EX: 關鍵字:女朋友,回覆'哈哈' 使用者輸入:我沒有女朋友...
LINE_BOT:'哈哈'
類似這樣的指令,我原本想如下
if received_text.(包含..好像不是include) = '關鍵字'
return '哈哈'
可是無法做出,請問有什麼想法或其他的方式嗎?
目前的關鍵字回覆都是 keyword = 'keyword'(100%一樣)

請參考:https://stackoverflow.com/questions/5522274/how-do-i-do-a-like-query-in-activerecord

acegen iT邦新手 5 級 ‧ 2018-12-18 10:19:41 檢舉

好的!謝謝卡米大!

acegen iT邦新手 5 級 ‧ 2018-12-21 21:56:11 檢舉

感謝卡米大!!後來我是用
return nil unless received_text.include? '(你要的條件)'
來觸發,這樣只要收到的訊息有包含後面的單字即可回復,可是若要再新增其他的條件,好像無法在後面加上
|| received_text.include? '(你要的)'
整串變為
return nil unless received_text.include? 'a' || received_text.include? 'b'

另外疑問, return nil unless received.text.include?'a' 分解是否
unless received.include? 'a'
reply_token = params['events'][0]['replyToken']
message = {
type: 'text',
text: '找我啊,不能嗎QQ'
}
line.reply_message(reply_token, message)
else
nil
end

(我會縮起來,可是發現好像拉長就無法QQ)

我要留言

立即登入留言