Get Contents of URL・Siri捷徑

在眾多「捷徑動作」之中,最為強大的莫屬「取得URL內容」(Get Contents of URL)。這一動作除了可以用來取得網頁內容之外,更好用的地方在於它可以跟網路上的API通訊。

API是Application Programming Interface,意思是「應用程式介面」,但在這裡只要簡單理解成網路上的服務就可以了。網路上的服務比Apple內建的服務要多得多,因此我們可以藉此大大擴展Apple設備的功能。

只要取得API的訪問權限,你就可以從網絡上獲取各種資料,然後照自己的需求運用。

用例一、取得天氣觀測資料

直接看範例吧。介紹API的時候,最常見的用法是取得氣象資料,網路上可以找到各種教學,可見大家普遍認為手機內建的天氣預報不夠準確。不過,比起預報,我更想知道此時此刻附近氣象站實際觀測到的數據。這數據看似隨處可得,打開內建的「天氣」app,不就可以看到大大的字顯示現在的氣溫嗎?

遺憾的是,如果你把那上面的數值跟中央氣象署的資料一比,就會發現有出入。再跟實際情況──我自己放在室外的溫溼度計──比對,會發現中央氣象署的才是準確的,而內建的「天氣」則似乎是把預報的數據直接當作現實呈現,以至於常常有誤差。

所以,如果我們要根據天氣數據來做判斷或自動控制,那最好從中央氣象署取得,不要使用Apple提供的數值。首先到「中央氣象署開放資料平臺」,找到「現在天氣觀測報告」。然後根據網站上的表單,可以得知以下API的用法:

https://opendata.cwa.gov.tw/api/v1/rest/datastore/O-A0003-001?Authorization=<API金鑰>&StationName=臺北

然後用Siri捷徑「取得URL內容」,請看下圖(我把圖中重複的地方用灰底遮蔽,方便閱讀):

利用「取得URL內容」來使用中央氣象署的API

你會得到以JSON格式編排的資料:

 {
  "records": {
    "Station": [
      {
        "GeoInfo": {
          "Coordinates": [
            {
              "CoordinateFormat": "decimal degrees",
              "CoordinateName": "TWD67",
              "StationLatitude": 25.03941,
              "StationLongitude": 121.506676
            },
            {
              "CoordinateFormat": "decimal degrees",
              "CoordinateName": "WGS84",
              "StationLatitude": 25.037659,
              "StationLongitude": 121.514854
            }
          ],
          "CountyCode": "63000",
          "CountyName": "臺北市",
          "StationAltitude": "6.3",
          "TownCode": "63000050",
          "TownName": "中正區"
        },
        "ObsTime": {
          "DateTime": "2024-05-20T17:00:00+08:00"
        },
        "StationId": "466920",
        "StationName": "臺北",
        "WeatherElement": {
          "AirPressure": 1005.5,
          "AirTemperature": 26.2,
          "DailyExtreme": {
            "DailyHigh": {
              "TemperatureInfo": {
                "AirTemperature": 27.9,
                "Occurred_at": {
                  "DateTime": "2024-05-20T09:50:00+08:00"
                }
              }
            },
            "DailyLow": {
              "TemperatureInfo": {
                "AirTemperature": 25.9,
                "Occurred_at": {
                  "DateTime": "2024-05-20T04:53:00+08:00"
                }
              }
            }
          },
          "GustInfo": {
            "Occurred_at": {
              "DateTime": "2024-05-20T16:34:00+08:00",
              "WindDirection": 90
            },
            "PeakGustSpeed": 11.5
          },
          "Max10MinAverage": {
            "Occurred_at": {
              "DateTime": "2024-05-20T16:40:00+08:00",
              "WindDirection": 100
            },
            "WindSpeed": 5
          },
          "Now": {
            "Precipitation": -990
          },
          "RelativeHumidity": 83,
          "SunshineDuration": 0,
          "UVIndex": 1,
          "VisibilityDescription": "11-15",
          "Weather": "陰",
          "WindDirection": 110,
          "WindSpeed": 3.7
        }
      }
    ]
  },
  "result": {
    "fields": [
      // 此處資料用不上,為節省長度省略……
    ],
    "resource_id": "O-A0003-001"
  },
  "success": "true"
}

收到資料後,就用一般習慣的「點記號」來取得資料,以「StationName」為例,由於大多數程式語言是以「0」作為清單的開頭,因此會用以下代碼取得StationName的值:

records.Station[0].StationName

在Siri捷徑,則有兩種方法可以取得,用其中一種即可。

一是直接取用「取得URL內容」。先選擇回傳資料的「類型」為辭典(Dictionary),然後用點記號取得辭典值。不過,Siri捷徑是以「1」作為清單的開頭,因此寫法略有不同:

records.Station.1.StationName
「取得URL內容」:先選擇資料類型,再以「點記號」取得值

另一種方法是使用「取得辭典值」這個動作,這裡因為我們先取得records.Station的值,而且裡面只有一個值,所以後面可以不必考慮清單從0還是1開始計算的問題:

「取得辭典值」

這些數據要怎麼應用就看自己的需求,可以請Siri念出來、像上圖一樣顯示出來,或是做成widget放在桌面。

用例二、使用ChatGPT生成文章大綱

再來看另一個範例。OpenAI的ChatGPT大家都知道,但OpenAI的服務其實不止於ChatGPT的聊天界面,還有語音╱文字互轉、繪圖、判讀圖片等。雖然可以透過ChatGPT的插件使用這些額外的功能,但我並不是很喜歡用聊天界面來處理這些事情。

比方說瀏覽網頁的時候遇到一篇可能感興趣的文章,我會先請ChatGPT整理一份大綱,再藉以判斷要不要細讀。如果透過聊天界面做這件事,我得先在網頁中複製文章全文,貼到ChatGPT,然後再輸入指令要它生成大綱。這在電腦上做還算輕鬆,但在手機上就非常難受了。

再比方說在路上偶然看到一張海報,很喜歡海報的風格但叫不出名字,這時我會拍張照請ChatGPT分析。這早先在聊天界面是做不到的(沒有上傳圖片的功能選項),如今雖然做得到了,但我總會在上傳圖片之前先修改尺寸再加以壓縮,省一些不必要的頻寬。壓縮好圖片之後,再上傳ChatGPT,然後輸入指令請它判讀。這一連串的事情手動做起來相當麻煩,何況是在大街上做。

透過Siri捷徑的「取得URL內容」,上面兩個情境都可以用一個步驟達成。先來看看生成文章大綱要怎麼做。首先到OpenAI的文檔看看API的使用方法:

curl https://api.openai.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-4o",
    "messages": [
      {
        "role": "system",
        "content": "You are a helpful assistant."
      },
      {
        "role": "user",
        "content": "Hello!"
      }
    ]
  }'

OpenAI的API用法顯然比上面氣象數據的例子要複雜一些,這是因為就氣象的例子來說,我們不必提供資料,只有單向的抓取;在這裡,我們則必須傳送指令給GPT-4o,所以才有了從第四行開始的模型與訊息資訊。但在那之前,先來準備要傳給ChatGPT的內容吧。

首先利用網址取得文章的內容,並且轉換成純文字。接下來寫下要給ChatGPT的指令,寫一次之後未來就可以反覆使用:

利用「文字」動作,預先寫下給ChatGPT的指令

接下來就是再次使用「取得URL內容」,這次的寫法比較複雜,請看下圖:

要傳資料給API的時候,必須用POST方法

由於這次我們要傳資料給API,因此傳輸方法要選擇「POST」而不是預設的「GET」。一旦選了「POST」,就會出現分隔的兩個區塊,而下面這個區塊就是你要傳給API的資料。

API回傳的依然是JSON資料,根據文檔,取用方法是:

choices[0].message.content

Siri捷徑則要換成以1為清單開頭的寫法:

choices.1.message.content
Siri捷徑要用以1為清單開頭的寫法

實際使用起來的情形如下影片:

用例三、使用GPT-4o分析圖像風格

讓GPT-4o分析照片的做法跟處理純文字差不多,差別只在多傳了一張圖片過去而已。首先拍一張照,然後先用TinyPNG(我串接了另一個Siri捷徑)進行壓縮。圖片準備好了之後,再跟預先寫好要給GPT-4o的指令一起傳送過去。

直接看實際操作影片吧。

分享Siri捷徑時,注意不要洩漏API金鑰

在使用Siri捷徑串接API時,通常都會需要金鑰。如果沒有處理就把Siri捷徑傳給他人,會連金鑰一起附加過去,必須特別注意。

這時候,最好的方法是利用「設置」功能,讓取得Siri捷徑的使用者自行輸入自己的API金鑰:

【延伸內容】

(本文封面圖片套用Pixelmator Pro的版式生成。)