Tasker配合ntfy接收通知

飞舞的冰龙發表於2024-09-23

ntfy是一個在裝置間傳遞訊息的工具。可以直接使用官方提供的服務,也可以自建。類似的工具還有很多,例如gotify等等。這裡以ntfy為例,其他工具也大多支援GETPUT的方式傳送和接收訊息。

Tasker是一個在安卓裝置上非常流行的自動化工具,可以傳送GET請求與ntfy伺服器通訊來接收訊息。

ntfy傳送和接收訊息

傳送訊息

ntfy支援眾多的傳送訊息方式,這裡以PUT json為例。更多內容參考https://docs.ntfy.sh/publish/

注意URL中不包含topic,而是放在了JSON中。文件中的示例:

fetch('https://ntfy.sh', {
    method: 'POST',
    body: JSON.stringify({
        "topic": "mytopic",
        "message": "Disk space is low at 5.1 GB",
        "title": "Low disk space alert",
        "tags": ["warning","cd"],
        "priority": 4,
        "attach": "https://filesrv.lan/space.jpg",
        "filename": "diskspace.jpg",
        "click": "https://homecamera.lan/xasds1h2xsSsa/",
        "actions": [{ "action": "view", "label": "Admin panel", "url": "https://filesrv.lan/admin" }]
    })
})

接收訊息

這裡和傳送訊息類似。可以使用Javascript中的fetch函式傳送GET請求。返回的資料為JSON格式。

利用Tasker接收訊息

由於涉及到從網路上獲取資訊,所以存在比較高的失敗可能性,因此需要新增大量的錯誤處理邏輯。為了整體流程清晰,強烈建議將邏輯完全寫在一個Javascript指令碼中。

// ntfy的每個訊息都有一個ID。利用這個ID可以只獲取最新的訊息。

let lastNotification;
try {
    lastNotification = global('%NotificationID');
} catch (e) {
    lastNotification = 'notificationID';
    console.log('Run in browser');
}
const ntfyUrl = 'https://ntfy.sh/mytopic/json?poll=1&since=' + lastNotification;

// 日誌輸出。根據情況輸出到瀏覽器控制檯或者手機日誌檔案。
const taskerLog = function (str) {
    const isOnMobile = typeof flash === 'function';
    if (isOnMobile) {
        writeFile('ntfy.log', str + '\n', true);
    } else {
        console.log(str);
    }
}

// fetch notifications from ntfy
const fetchNotifications = function () {
    taskerLog('開始查詢URL: ' + ntfyUrl);
    fetch(ntfyUrl)
        .then(response => {
            taskerLog('Fetch response status:');
            taskerLog(response.status);
            return response.text()
        })
        .then(data => {
            if (data) {
                const lines = data.trim().split('\n');
                lines.forEach(line => {
                    let latestID;
                    let latestTime = 0;
                    try {
                        const notification = JSON.parse(line);
                        const title = notification.title || "New Notification";
                        const message = notification.message || "You have a new notification.";
                        const id = notification.id;
                        const time = notification.time;
                        if (time > latestTime) {
                            latestID = id;
                        }

                        taskerLog(title);
                        taskerLog(message);

                        // 將得到的資訊傳遞給另一個任務“通知欄提醒”。
                        let result = performTask(
                            '通知欄提醒', local('%priority'), title, message
                        );
                        taskerLog(result);

                        setGlobal('%NotificationID', latestID);
                    } catch (e) {
                        throw new Error('Error parsing JSON' + e + 'Line:' + line);
                    }
                })
            } else {
                taskerLog('No new notifications.');
            }
        })
        .then(r => exit())
        .catch(error => {
            taskerLog('Error fetching notifications: ' + error);
        });
    taskerLog('查詢結束');
}

fetchNotifications();

由於Tasker中的Javascript不支援直接傳送通知欄提醒,所以需要另外建立一個Task。利用performTask啟動Task並傳遞相關引數。

“通知欄提醒”這個Task中僅需要包含Notify這一個ActionAction中可以使用%par1%par2這樣的變數獲取前面傳遞的引數。Notify中的具體內容可以根據情況填寫。

相關文章