Glanceway Glanceway
所有信息源

GitHub Notifications

开发者 v1.0.0

Get GitHub notifications in your menu bar. Supports filtering by repository.

@codytseng #github #notifications #developer

配置项

名称 类型 必填 默认值 描述
GitHub Token GITHUB_TOKEN secret Personal access token from GitHub Settings
Repository REPOSITORY string Optional: Filter by repository (format: owner/repo)

源代码

version: 1.0.0
name: GitHub Notifications
description: |
  Get GitHub notifications in your menu bar.
  Supports filtering by repository.
author: codytseng
author_url: https://github.com/codytseng
category: Developer
tags:
  - github
  - notifications
  - developer

config:
  - key: GITHUB_TOKEN
    name: GitHub Token
    type: secret
    required: true
    description: "Personal access token from GitHub Settings"
  - key: REPOSITORY
    name: Repository
    type: string
    required: false
    description: "Optional: Filter by repository (format: owner/repo)"
module.exports = async (api) => {
  const token = api.config.get("GITHUB_TOKEN");
  const repository = api.config.get("REPOSITORY");

  async function fetchData() {
    const url = repository
      ? `https://api.github.com/repos/${repository}/notifications?per_page=100`
      : "https://api.github.com/notifications?per_page=100";

    const response = await api.fetch(url, {
      headers: { Authorization: `Bearer ${token}` },
    });

    if (!response.ok || !response.json) {
      throw new Error(
        `Failed to fetch GitHub notifications (HTTP ${response.status})`,
      );
    }

    const items = response.json
      .map((item) => {
        const itemUrl = item.subject.url
          ? item.subject.url
              .replace("api.github.com/repos", "github.com")
              .replace("/pulls/", "/pull/")
              .replace("/issues/", "/issues/")
          : null;

        if (!itemUrl) {
          return null;
        }

        return {
          id: item.id,
          title: item.subject.title,
          subtitle: item.repository.full_name,
          url: itemUrl,
          timestamp: item.updated_at,
        };
      })
      .filter(Boolean);

    api.emit(items);
  }

  await fetchData();

  return {
    refresh: fetchData,
  };
};