關於 bot 的設計想法,主要來自灣區日報的文章。 我想,因爲 Slack 超過上限需要收費否則看不到內容,telegram 在目前可見得未來運作的還不錯,加上精良的 bot API,所以我決定採用 telegram 來寫 bot

設定

先從 botFather 那邊取得 telegram bot token。我選擇 R package telegram,這是一個很方便的工具,只要把我的 id 跟 bot token 填入執行時路徑目錄下的 .Renviron 即可。基本程式碼如下:

library('telegram')
bot <- TGBot$new(token = bot_token('RBot'))
bot$set_default_chat_id(user_id('me'))

命令

命令需要使用 /setcommands 來設定。我的 bot 的第一個任務是協助我整理文章,在試驗期間,我暫時訂了四個指令

  1. /feedadd:添加 feed,需要提供 nick。
  2. /feeddel:刪除 feed。
  3. /feedlist:列出 feed list 的所有內容,目前只返回代稱,將來要返回 HTML 表格。
  4. /feedfetch:尚未完成實際功能,可能是幫我取得最新摘要或回傳可點選的標題。
feedadd <- function(nick, url){
  feed[[nick]] <- url
  return('received')
}

feedlist <- function(){
  return(names(feed))
}

feeddel <- function(nick){
  feed[[nick]] <- NULL
  return('deleted')
}

feedfetch <- function(nick){
  return('not implemented')
}

消息處理

使用 bot$getUpdates() 取得最近的 100 條訊息。這樣,問題就來了,我們要如何區分上次已經處理過的訊息呢?返回的 JSON 會被轉換成一個表格。表格的第一個 column 是 update_id,它是唯一的。我們可以通過比較這個值跟之前已知的 ID 來區分新舊訊息。

result <- bot$getUpdates()
message.update_id <- result$update_id
message.new_id <- setdiff(message.update_id, history)
message.text <- result[message.update_id %in% message.new_id,][[2]][[5]]

首先取得表格。將 update_id 取出爲 vector。接著,跟舊的訊息的 update_id 做比較,瞭解哪些是新的(使用 setdiff 取得新列表,再把這個列表用 %in% 產生布林序列的方式送回原本表格,取出訊息。

處理訊息

所有 command 都是由 / 開頭(如同 IRC),所以,我把有此特徵的訊息按空白分割,再用 switch 依照結果送到不同的函數去(函數見上面「命令」段落)

sapply(message.text, function(text){
  vec <- strsplit(text, " ")[[1]]
  if (substring(vec[1], 1, 1) == '/'){
    bot$sendMessage(switch(substring(vec[1], 2),
                           feedadd = feedadd(vec[2], vec[3]),
                           feeddel = feeddel(vec[2]),
                           feedlist = feedlist(), 
                           feedfetch = feedfetch(vec[2]))) 
  }
})

保存

對於存放過去訊息的 history 跟存放鏈接的 feed,我們使用 saveload 來存取。我把這個 bot 設定爲批次執行,所以,它使用 cron 大約十五分鐘運行一次。

擴展計劃

  1. 我想弄一個類灣區日報的,放射、腦神經造影相關題材的網站。所以,灣區日報的簡評、生成功能我會實現。
  2. 把這個改造成一個小函數,可以嵌入 hazalyst 程式中,告訴我哪裏出錯了!
  3. 主動推送,如同我在《RE:訊息流》中說要設計的各頻道匯報!
  4. 暫時還沒想到,也許拿來:
    1. 記賬
    2. 安排行事曆(GTD)
    3. 控制下載(添加 torrent)
    4. R 指令搜索、Stack Overflow 搜索
    5. pocket 機器人
    6. 鏈接 IFTTT
    7. 查火車、公車時刻表(telegram 可以發送 GPS 位置)