Skip to content
This repository has been archived by the owner on Aug 3, 2020. It is now read-only.

Latest commit

 

History

History
160 lines (122 loc) · 6.61 KB

features.md

File metadata and controls

160 lines (122 loc) · 6.61 KB

SDK 介紹

核心概念

CQWebSocket SDK 是基於 CQHTTP API 插件之 WebSocket 通訊,底層封裝了兩個 socket,分別為 /api/event (詳細功能描述可見 coolq-http-api/websocket)。

CQWebSocket SDK 使開發者能夠更專心於機器人應用的開發,SDK 為開發者提供底層連線的維護、斷線重連等功能,並第一手先處理了上報事件,依照不同事件類型,將事件文本分發至各事件監聽器處理。

自動獲取機器人QQ號

若機器人配置 enableAPI 為 true, 且沒有通過 qq 項配置機器人ID的話, 連線建立成功後會主動發送 API 請求向 CQHTTP API 取得酷Q正登錄的QQ號作為機器人QQ號。

此操作為異步操作, 在API響應之前, @.me 事件均不會發布。

除非真的有人QQ號是 -1, 哪尼口雷 Σ(*゚д゚ノ)ノ

事件傳播

事件具有向上傳播的機制,一個事件上報之後,該事件之所有親事件也會依序上報。 事件名稱以 . 相互連接,形成具有繼承關係的結構,如 message (任意消息事件) 為 message.group (群消息) 的親事件。 關於事件親子關係的構成,可參考事件樹

舉個例子,群消息有人@某機器人,該機器人則會首先上報 message.group.@.me 事件,該事件之親事件由下而上依序為 message.group.@, message.groupmessage ,則這幾個事件也會依照這個順序上報,這樣稱為一次事件傳播

快速響應

message 及其子事件支援此機制。

message 及其子事件監聽器的第一個參數: CQEvent 類別實例,在這個機制中扮演重要的角色。 透過 CQEvent 實例,所有監聽器皆可在自己的運行期間調用 CQEvent #stopPropagation() 方法聲明自己的處理權,以截獲事件並阻斷後續監聽器的調用,並立即以該事件返回之文字訊息(或透過調用 CQEvent #setMessage(msg) 設定之文字訊息,也可以透過 Promise 對象 resolve 之文字訊息)作為響應,送回至 CQHTTP API 插件端。

由於在一次事件傳播中的所有監聽器都會收到同一個 CQEvent 實例,因此對於響應的決定方式,除了 CQEvent #stopPropagation() 所提供的事件截獲機制之外,也可以採取協議式的方式,就是透過每個監聽器調用 CQEvent #getMessage() CQEvent #setMessage(msg) 協議出一個最終的響應訊息。

範例: 協議式響應

假設機器人具有以下代碼。

// app.js

const { CQWebSocket } = require('cq-websocket')
const bot = CQWebSocket()

const plugins = [
  require('./pluginA'),
  require('./pluginB')
]

plugins.forEach(plugin => {
  bot.on('message.private', plugin)
})
// pluginA.js
module.exports = function (e) {
  if (e.hasMessage()) {
    e.appendMessage(' world!')
  } else {
    e.setMessage('Hello')
  }
}
// pluginB.js
module.exports = function (e) {
  if (e.hasMessage()) {
    e.appendMessage(' CQWebSocket!')
  } else {
    e.setMessage('Hi')
  }
}

此時若機器人收到了一則私人消息,則會響應 "Hello CQWebSocket!"

我們也可以藉此機制,加入消息過濾的功能。 首先在機器人的 app.js 加入以下代碼。

// app.js
const pluginGuard = require('./pluginGuard')

// 於最上層親事件檢查所有響應訊息
bot.on('message', pluginGuard)
// pluginGuard.js
module.exports = function (e) {
  if (e.hasMessage()) {
    e.stopPropagation()

    // 關鍵字過濾
    e.setMessage(
      e.getMessage().replace(//g, '')
    )
  }
}

發送結果追蹤

不論是快速響應或是 API 調用均有此機制。

追蹤快速響應之結果,可通過 CQEvent #onResponse() 設置結果監聽器, 並透過 CQEvent #onError() 處理響應的錯誤。 若沒有 CQEvent #onError() 進行錯誤處理, 發生響應錯誤時會觸發 error 事件

追蹤 API 調用之結果,可以利用 bot(method[, params[, options]]) 返回的 Promise 對象進行追蹤。

消息格式

上報消息

message 事件中,監聽器第三個參數為一個 CQTag 的數組,關於該數組內可能出現的元素,可以參考CQ 碼相關類別

※除了已定義的 CQTag 之外,其餘的內容都會當作 CQText 的字符串處理。

舉例,上報消息中含有一個不在定義中的 CQ 碼 "[CQ:unknown,key=value]",則此 CQ 碼會被 Parser 判定為一個 CQText 實例,等同 new CQText('[CQ:unknown,key=value]')

發送消息

不論是快速響應或是 API 調用發送消息,均可使用以下消息格式。

  1. 字符串格式
  2. 數組格式

其中,數組格式在本 SDK 的擴增下,支持了將本 SDK 的 CQ 碼相關類別直接作為數組的內容。

首先可以先了解一下 CQHTTP API 所提供的消息段對象,此消息段在這邊我們姑且稱之為 CQHTTPMessage

快速響應或是 API 調用發送消息時,可以使用一個含有 CQHTTPMessage CQTag string 的數組作為消息文本。 (CQTag 可參考 CQ 碼相關類別)

舉個快速響應的例子:

bot.on('message', () => {
  return [
    {
      type: 'at',
      data: {
        qq: '123'
      }
    },
    '你好~ ',
    new CQEmoji(129303) // 🤗
  ]
})

每當機器人收到消息時,便會回應 "[CQ:at,qq=123]你好~ 🤗"

延伸閱讀