用 Node.js 把玩一番 Alfred Workflow

牧云云發表於2019-02-16

本文首發在個人部落格:muyunyun.cn/posts/4c23b…

外掛地址(整合Github、掘金、知乎、淘寶等搜尋)

作為 Mac 上常年位居神器榜第一位的軟體來說,Alfred 給我們帶來的便利是不言而喻的,其中 workflow(工作流) 功不可沒,在它上面可以輕鬆地查詢任何 api;可以快速在豆瓣上搜到自己喜歡的電影、圖書、音樂;可以快速把圖片上傳到圖床 等等。

一些安利

附上一張個人裝著的外掛的截圖。Caffeinate 外掛能在指定時間使電腦不黑屏;在 Dash 外掛上能輕鬆查任何文件;Youdao Translate 外掛比系統自帶的翻譯方便許多。外掛也是因人而異,大家可以在 Workflow List 上逛逛,各取所需。

在用了別人的外掛感覺高大上後,便萌發了也寫一個外掛的想法,計劃把自己常逛的網站集合成一個外掛,使用特定的縮略詞便可快速進行搜尋資料,又看了官方稱可以使用 bash, zsh, PHP, Ruby, Python, Perl, Apple Script 開發 Alfred Workflow。於是我選擇了 Node.js 作為開發語言,開發了一款 commonSearch, 開發完效果如下(整合了Github、掘金、知乎、淘寶等搜尋)。

開發階段

在開發前,得先對一些特定的操作步驟和知識點有一定的認知,這樣開發時就基本上沒有大礙了。

前置步驟

可以先參考 如何去寫一個第三方的 workflow 的開始部分, 完成基本工作流的搭建,如下圖是我搭建好的基本工作流連線。

在 Script 中,可以看到 /usr/local/bin/node common_search.js 相當於就是在呼叫該外掛的時候起了一個 node 服務,後面的 1 是為了區分當前呼叫的是哪個搜尋手動傳入 common_search.js 的,{query} 則是使用者查詢的名稱。

使用 Node.js 呼叫 JSON API

最初開發參考了 知乎搜尋 這個專案,它是基於 cheerio 這個模組對請求到的網頁資料進行分析爬取,但是引入了 cheerio 後,外掛體積多了 2M 多,這對於一個外掛來說太不友好了,所以這可能是 python 之類的語言更適合開發類似外掛的原因吧(猜想:python 不需要引人第三方庫就能進行爬蟲),於是我開始選擇提供 JSON API 的介面,比如找尋掘金返回資料的介面。首先開啟 chrome 控制檯,這可能對前端工程師比較熟悉了。

從而找到了掘金返回搜尋資料的介面是 https://search-merger-ms.juejin.im/v1/search?query={query}&page=0&raw_result=false&src=web

接著愉快地使用 node 提供的 https 模組,這裡有一個注意點,http.get() 回撥中的 res 引數不是正文,而是 http.ClientResponse 物件,所以我們需要組裝內容。

var options = {
    host: 'search-merger-ms.juejin.im',
    path: '/v1/search?query=' + encodeURI(keyword) + '&page=0&raw_result=false&src=web'
  }
  https.get(options, function (res) {
    res.on('data', (chunk) => {
      var content += chunk
    }).on('end', function () {
      var jsonContent = JSON.parse(content) && JSON.parse(content).d
      var result_array = []
      for (var i = 0; i < jsonContent.length; i++) {
        if (jsonContent[i].user.jobTitle === '') {
          result_array.push({
            title:
            subtitle:
            arg:
            icon: {
              path: join(__dirname, 'xx.png'),
            },
            mods: {
              cmd: {}
            }
          })
        }
      }
      content = ''
      console.log(JSON.stringify({
        items: result_array
      }))
    })
  })複製程式碼

這種方法應該是最直接的呼叫 JSON API 的方案了,當然也可以引人第三方模組 request 後解析 JSON,示例如下:

var request = require('request')

var url = 'search-merger-ms.juejin.im/v1/search?query=' + encodeURI(keyword) + '&page=0&raw_result=false&src=web'

request.get({
    url: url,
    json: true,
    headers: {'User-Agent': 'request'}
  }, (err, res, data) => {
    if (err) {
      console.log('Error:', err);
    } else if (res.statusCode !== 200) {
      console.log('Status:', res.statusCode);
    } else {
      // data is already parsed as JSON:
      console.log(data.html_url);
    }
});複製程式碼

還有一點要注意的是返回值的欄位是固定的,具體可以參考它的官方解釋,琢磨了好久才把 JS 中的 Icon 自定義的格式找出來。

title: 主標題
subtitle: 內容行
arg: 跳轉連結
icons: 圖示
mods:定製鍵盤按鍵的方法複製程式碼

對於 Github、掘金、知乎、淘寶的搜尋都是基於以上思路進行開發的,就是對於具體返回的 JSON 資料進行了不同處理,雖然粗糙,但也算完成了第一個 Alfred Workflow 外掛的開發。

尾聲

本文的知識點寫的不是特別豐滿,一是就是對開發這個外掛的小結,另外就是拋磚引玉了,能讓更多的小夥伴瞭解開發一個外掛並不是難事,同時讓更多的朋友開發出更多有意義,有趣的 alfred-workflow 外掛也算是本文分享的一個初衷了。

相關文章