使用 API 订阅 GitHub 的新消息通知 Notifications

本帖算是 尝试用浏览器查看论坛 RSS 订阅 的延续。在那个帖子中我介绍了 RSSHub,里面也提供了订阅 GitHub Notifications 的 feed。但是,由于获取数据需要使用 GitHub Access Token,可能是出于安全考虑,因而只有本地部署 RSSHub 的选项。这样一来呢,每次开机都必须要自启动 Docker。像我这样 GitHub 没什么新通知也根本不用 Docker 的人,也不太可能为了接 RSS 安个软件。此外,GitHub 也有邮件通知的设置,但有时也不是每个通知都想要邮件。这时,就可以用到类似本帖的订阅方式。

虽然我觉得有这个需求的人都能自己写,不过写都写了就发一下吧。这里用 DataviewJS 实现。

DataviewJS 代码
const token = '你的 Token'
const conf = {
  method: 'GET',
  headers: {
    'Accept': 'application/vnd.github+json',
    'Authorization': `Bearer ${token}`,
  },
}
const fetchUrl = async (url, conf)=> {
  try {
    const res = await fetch(url, conf)
    if (!res.ok) throw new Error(res.status)
    return await res.json()
  } catch (err) {
    console.error(err.message)
    throw err // 重新抛出错误以便处理
  }
}
const dateDiff = (t1, t2)=> {
  if (t1 > t2) return;
  else {
    const minutes = (t2 - t1) / 6e4
    const hours = minutes / 60
    const days = hours / 24
    const weeks = days / 7
    if (weeks > 4) return '很久';
    else if (weeks >= 1) return `${Math.round(weeks)} 周前`;
    else if (days >= 1) return `${Math.round(days)} 天前`;
    else if (hours >= 1) return `${Math.round(hours)} 时前`;
    else return `${Math.round(minutes)} 分前`
  }
}
const pickLatest = async ({subject: {url}}, conf)=> {
  const comments = await fetchUrl(`${url}/comments`, conf)
  // Original Post is not considered as a comment.
  return comments[0] ? comments.pop() : await fetchUrl(url, conf)
}
const trimTrailing = (arr)=> {
  let index = arr.length - 1
  while (index > 0 && arr[index] === '') index--
  return arr.slice(0, index + 1)
}
const formPost = ({body, html_url, user})=> {
  const lines = trimTrailing(body.split('\r\n'))
  const _body = lines.length > 10
    ? lines.slice(0, 10).join('\n') + '-<more>'
    : lines.join('\n')
  return {
    body: '````markdown\n' + _body + '\n````', html_url,
    user: `![|20](<${user.avatar_url}>) ${user.login}`,
  }
}
const curr = new Date()
const liveUrl = `https://api.github.com/notifications?${curr.getTime()}`
const threads = await fetchUrl(liveUrl, conf), data = []
for (const thread of threads) {
  const { last_read_at, updated_at, subject: {title} } = thread
  const latest = formPost(await pickLatest(thread, conf))
  const t1 = new Date(last_read_at), t2 = new Date(updated_at)
  const diff = dateDiff(t2, curr)
  const icon = '<font color="#1f6feb">☼</font>'
  const link = `[${(t1 > t2) ? icon : diff}](<${latest.html_url}>)`
  data.push(`${latest.user} ${link} ${title}\n\n${latest.body}`)
}
dv.paragraph(data.join('\n\n')||'🎉 No further')
申请 Token 大致步骤

地址:https://github.com/settings/tokens,或点击头像 - Settings - 左侧滑到底部 Developer settings - Personal access tokens - Tokens (classic)。

Generate new token 继续设置:

Select scopes 向下滑,无其他需求只勾选 notifications 即可。

image

效果,无新消息时:image

GitHub 的 API 只会获取到未读状态的信息。这里我手动将状态设置为未读来进行测试:

如何设置为未读

imageimage

1 个赞