Software Monkey

发布于 更新于

AI总结: 本文介绍了自动化配置和Webhook的实现,主要通过POST请求发送feed条目信息,并提供了一个示例参数格式。文中还描述了如何在Web端实现Feed分享页的自动订阅功能,包括获取feed ID、判断是否已订阅以及调用订阅接口的步骤。此外,提供了一个Tampermonkey用户脚本的示例,用于从当前页面URL提取ID并进行订阅。 优化建议: 1. 在Webhook接口处理时,建议增加错误处理逻辑,以确保在接收到无效数据时能够给出明确的反馈。 2. 考虑将订阅数量上线的设置提取为可配置参数,以便于后期调整。 3. 在用户脚本中,添加对网络请求的重试机制,以提高稳定性。 4. 增加对API响应的详细日志记录,便于后期调试和问题排查。 5. 提供更详细的用户反馈,例如在订阅成功或失败时,弹出提示通知用户。

自动化配置

Webhook

Image

POST 请求, 会将feed条目信息作为Json参数进行请求, 所以如果要较好处理的话, 可能需要自定义一个webhook接口进行处理

参数格式示例:

{'entry': {'id': 'xxx', 'publishedAt': '2025-02-06T06:31:29.669Z', 'insertedAt': '2025-02-06T06:42:55.467Z', 'feedId': '85248513348230144', 'title': "xxx", 'description': 'xxx', 'content': 'xxx', 'author': None, 'url': 'xxx', 'guid': 'xxx', 'media': [{'url': 'xxx', 'type': 'photo', 'width': 492, 'height': 656}]}, 'feed': {'title': 'xxx', 'description': 'xxx', 'siteUrl': 'https://xxx', 'image': 'https://xxx', 'checkedAt': '2025-02-06T06:42:55.466Z', 'ttl': 30, 'url': 'https://xxxx', 'lastModifiedHeader': 'Thu, 06 Feb 2025 06:42:54 GMT', 'etagHeader': '"ee35-WBbJJibnAIpo+80xxx/iPxbcxxx"', 'errorMessage': None, 'errorAt': None}, 'view': 5}  

Feed分享页自动订阅

因为目前主要在Web端使用, 在分享页订阅时 会提示跳转下载客户端. 所以实现该脚本:
1. 从链接获取feed id
2. 查询feed信息接口 判断是否订阅
3. 调用feed订阅接口 进行订阅, 设定临时分类

有需要再进行优化, 目前订阅数量上线为500条, 超限后可停用脚本

// ==UserScript==  
// @name         Follow分享页 自动订阅  
// @namespace    http://tampermonkey.net/  
// @version      1.0  
// @description  从当前页面 URL 中提取最后一段数字 ID  
// @author       anaer  
// @match        https://app.follow.is/share/feeds/*  
// @grant        GM_addStyle  
// @grant        GM_xmlhttpRequest  
// @grant        unsafeWindow  
// ==/UserScript==  

(function () {  
  "use strict";  

  const xget = (url, type = "json") =>  
    new Promise((success, fail) => {  
      GM_xmlhttpRequest({  
        method: "GET",  
        timeout: 3000,  
        credentials: "include", // 携带浏览器 Cookies  
        url: url,  
        responseType: type,  
        onload: success,  
        onerror: fail,  
        ontimeout: fail,  
      });  
    });  

  const xpost = (url, data = {}) =>  
    new Promise((success, fail) => {  
      GM_xmlhttpRequest({  
        method: "POST",  
        timeout: 3000,  
        credentials: "include", // 携带浏览器 Cookies  
        headers: {  
          "Content-Type": "application/json", // 设置请求头  
        },  
        url: url,  
        data: data,  
        responseType: "json",  
        onload: success,  
        onerror: fail,  
        ontimeout: fail,  
      });  
    });  

  // 获取当前页面的 URL  
  const currentUrl = window.location.href;  

  // 使用正则表达式提取最后一段数字 ID  
  const match = currentUrl.match(/\/(\d+)\/?$/);  

  var id;  
  if (match && match[1]) {  
    id = match[1];  
    console.log("提取的数字 ID:", id);  
  } else {  
    console.log("未找到数字 ID");  
  }  

  let url = "https://api.follow.is/feeds?id=" + id;  
  xget(url)  
    .then((r) => {  
      const ra = r.response;  
      console.log(url, ra);  

      if (ra.data.subscription) {  
        console.log("已订阅");  
      } else {  
        console.log("未订阅");  
        let feed =  
          unsafeWindow.__HYDRATE__["feeds.$get,query:id=" + id]["feed"];  

        var data = JSON.stringify({  
          feedId: feed.id,  
          url: feed.url,  
          view: 0,  
          category: "待定",  
        });  
        xpost("https://api.follow.is/subscriptions", data)  
          .then((r) => {  
            const ra = r.response;  
            console.log("订阅成功", data, ra);  
          })  
          .catch((e) => {  
            console.log("订阅失败");  
          });  
      }  
    })  
    .catch((e) => {  
      console.log(url, "获取feed信息异常");  
    });  
})();