daab 仕様

daab は GitHub社の Hubot を拡張したものです。 基本的なスクリプトの書き方は公式ドキュメントを参考にしてください。 以下では、direct 用に Hubot を拡張した点について記述しています。


メッセージの送信

以下のコードブロックの内側についてのものとします。

module.exports = (robot) ->
    robot.respond /.../i, (res) ->
        # here

上記のコードブロック外から送信するときは、以下のようにします。idの部分は後述の「トークルームの識別」を参照してください。

module.exports = (robot) ->
    robot.send room:"...id...", "...message..."

テキスト (Hubot)

res.send "This message is text."

もしくは、以下も同等です。

res.send
    text: "This message is text."

スタンプ

res.send
    stamp_set: "3"
    stamp_index: "1152921507291203198"
    text: "おはよう"  # (Option) テキスト付きスタンプの場合のみ

※ stamp_set と stamp_index は、ブラウザの「要素の検証」等で確認してください。

<img src="./images/stamp/3/1152921507291203198.png">

Yes/No スタンプ

res.send
    question: "質問内容"

送信したYes/Noスタンプは締め切ることができます。

res.send
    close_yesno: sent.message.id

sent.message.id については「メッセージの送信完了」を参照してください。

セレクトスタンプ

res.send
    question: "質問内容"
    options: ["選択肢1", "選択肢2", "選択肢3"]

送信したセレクトスタンプは締め切ることができます。

res.send
    close_select: sent.message.id

sent.message.id については「メッセージの送信完了」を参照してください。

タスクスタンプ

res.send
    title: "すること"
    closing_type: 0  # (Option) 誰かが:0, 全員が:1

送信したタスクスタンプは締め切ることができます。

res.send
    close_task: sent.message.id

sent.message.id については「メッセージの送信完了」を参照してください。

ファイル

res.send
    path: "your/file/name.png"
    name: "name.png"    # (Option) アップロード名
    type: "image/png"   # (Option) MIME
    text: "send file"   # (Option) ファイルと同時に送信するテキスト

※ 複数ファイルを送信するときは、path や name に配列を渡してください。

res.send
    path: ["your/file1.png", "your/file2.png"]
    name: ["name1.png", "name2.png"]   # (Option)

メッセージの受信

以下のコードブロックの内側についてのものとします。

module.exports = (robot) ->
    # here

テキスト (Hubot)

robot.respond /(.*)/, (res) ->
    res.send "Your message is #{res.match[1]}"

※ メッセージ本文は res.message.text で参照できます。

スタンプ

robot.respond "stamp", (res) ->
    res.send "#{res.json.stamp_set} - #{res.json.stamp_index}"

Yes/No スタンプ

robot.respond "yesno", (res) ->
    if not res.json.response?
        res.send "Your question is #{res.json.question}."
    else
        res.send "Your answer is #{res.json.response}."

受信したYes/Noスタンプに返信できます。

robot.respond "yesno", (res) ->
    res.send
        in_reply_to: res.message.id
        response: true

セレクトスタンプ

robot.respond "select", (res) ->
    if not res.json.response?
        res.send "Your question is #{res.json.question}."
    else
        res.send "Your answer is #{res.json.options[res.json.response]}."

受信したセレクトスタンプに返信できます。

robot.respond "select", (res) ->
    res.send
        in_reply_to: res.message.id
        response: 0

タスクスタンプ

robot.respond "task", (res) ->
    if not res.json.done?
        res.send "Your task is #{res.json.title}."
    else
        res.send "Your task is #{if res.json.done then 'done' else 'undone'}."

受信したタスクスタンプに返信できます。

robot.respond "task", (res) ->
    res.send
        in_reply_to: res.message.id
        done: true

ファイル

onfile = (res, file) ->
  res.send "File received.
    name: #{file.name}
    type: #{file.content_type}
    size: #{file.content_size}bytes"
  res.download file, (path) ->
    res.send "downloaded to #{path}"

# ファイルが1つだけの場合
robot.respond "file", (res) ->
  onfile(res, res.json)

# ファイルが複数の場合
robot.respond "files", (res) ->
  for file in res.json.files
    onfile(res, file)
  res.send "with text: #{res.json.text}" if res.json.text

位置情報

robot.respond "map", (res) ->
    res.send "Your location is #{res.json.place} at #{res.json.lat}, #{res.json.lng}"

トークルーム情報

以下のコードブロックの内側についてのものとします。

module.exports = (robot) ->
    robot.respond /room/i, (res) ->
        # here

トークルームの識別 (Hubot)

res.send "This room id is " + res.message.room

※ direct特有のトークルーム情報は以下のようにして取得できます。

console.log res.message.rooms[res.message.room]

トークルームの種類

res.send "This room type is " + ["unknown", "pair", "group"][res.message.roomType]

トークルーム名

if res.message.roomType == 2  # Group talk
    res.send "Group name is #{res.message.roomTopic}"

トークルーム名の変更 (Hubot)

res.topic "BotGroup"

トークルームの参加者情報

text = ""
for user in res.message.roomUsers
    text += "#{user.name} #{user.email} #{user.profile_url}\n\n" 
res.send text

トークルームの一覧

text = ""
for id,talk of res.message.rooms
    text += "name:#{talk.topic} type:#{talk.type} users:#{talk.users}\n\n" 
res.send text

※ res オブジェクトが利用できない場合は、res.message.rooms の代わりに robot.brain.rooms() も利用できます (注:関数呼出しになります)。


連絡先情報の取得

以下のコードブロックの内側についてのものとします。

module.exports = (robot) ->
    robot.respond /users/i, (res) ->
        # here

メッセージ送信者の連絡先 (hubot)

res.send "Sender is #{res.message.user.name}."

連絡先の一覧 (hubot)

users = robot.brain.users()
console.log users   # { id0:user0, id1:user1, ... }

IDによる連絡先の検索 (hubot)

userId = Object.keys(users)[0]
console.log robot.brain.userForId(userId)

名前による連絡先の検索 (hubot)

user = users[userId]
console.log robot.brain.userForName(user.name)

※ その他にも、usersForRawFuzzyName (先頭一致)、usersForFuzzyName (先頭一致、ただし、完全一致を優先) も利用できます。


組織情報の取得

以下のコードブロックの内側についてのものとします。

module.exports = (robot) ->
    robot.respond /domains/i, () ->
        # here

所属する組織の一覧

domains = robot.brain.domains()
console.log domains

アクションスタンプの回答情報

以下のコードブロックの内側についてのものとします。

module.exports = (robot) ->
    robot.respond /answers/i, (res) ->
        res.send
            ...各スタンプの内容...
            onsend: (sent) ->
                setTimeout ->
                    # here
                , 5000

※ 例として、5秒後の回答状況を取得しています。

Yes/No スタンプ

sent.answer (trueUsers, falseUsers) ->
    console.log "YES", trueUsers
    console.log "NO", falseUsers

セレクトスタンプ

sent.answer (optionUsers) ->
    for users,i in optionUsers
        console.log sent.message.content.options[i], users

タスクスタンプ

sent.answer (doneUsers, undoneUsers) ->
    console.log "DONE", doneUsers
    console.log "UNDONE", undoneUsers

イベント

以下のコードブロックの内側についてのものとします。

module.exports = (robot) ->
    # here

ペアトークでのメッセージ受信 (Hubot)

robot.respond /.../, (res) ->
    res.send ""

respond はグループトーク中の「@hubot名 メッセージ」の場合でも呼ばれます。厳密にペアトークのみに対応させたいときはif res.message.roomType == 1 で場合分けしてください。

グループトークでのメッセージ受信 (Hubot)

robot.hear /.../, (res) ->
    res.send ""

トークルーム名の変更 (Hubot)

robot.topic (res) ->
    res.send "Topic is changed: #{res.message.text}"

トークルームへのユーザーの参加 (Hubot)

robot.enter (res) ->
    res.send "Hi! #{res.message.user.name}"

トークルームからのユーザーの退出 (Hubot)

robot.leave (res) ->
    res.send "Good bye! #{res.message.user.name}"

招待による自分自身のトークルームへの参加

robot.join (res) ->
    res.send "Nice to meet you!"

メッセージの送信完了

送信メッセージに onsend を付与することで、そのメッセージの送信完了後に処理を行うことができるようになります。

res.send
    text: "Now sending..."
    onsend: (sent) ->
        res.send "completed. messageId: #{sent.message.id}"

メッセージの未読・既読

送信メッセージに onread を付与することで、そのメッセージの未読・既読情報を取得できるようになります。

robot.respond /read after/, (res) ->
    res.send
        text: "Read thie message, please!"
        onread: () -> true
        onsend: (sent) ->
            setTimeout ->
                text = []
                text.push "#{user.name} read after 5sec." for user in sent.readUsers
                text.push "#{user.name} did't read after 5sec." for user in sent.unreadUsers
                res.send text.join("\n")
            , 5000

未読・既読の変更を監視したい場合は、以下のようにします。 (24時間たっても変更がなければ監視は終了します。)

robot.respond /read now/, (res) ->
    res.send
        text: "Read thie message, please!"
        onread: (readNowUsers, readUsers, unreadUsers) ->
            text = []
            text.push "#{user.name} read now." for user in readNowUsers
            res.send text.join("\n")

その他

トークルームからの退出

res.leave()

指定したユーザをトークルームから退出

    robot.hear /banned word/, (res) ->
      res.leave res.message.user

一斉連絡の送信

# メッセージを受けとった組織に送信
res.announce "THIS IS AN ANNOUNCEMENT!"

# 任意の組織に送信 (domain = { id: domain.id })
robot.announce domain, "ANNOUNCEMENT!"

※ アカウントに管理者権限が必要です。