name: Issue Guard on: issues: types: [opened] issue_comment: types: [created] pull_request_review_comment: types: [created] jobs: moderate: runs-on: ubuntu-latest permissions: issues: write pull-requests: write models: read contents: read steps: - uses: actions/checkout@v4 # AI 内容审核(垃圾检测 + 链接检测 + AI 生成检测) - uses: github/ai-moderator@v1 with: token: ${{ secrets.GITHUB_TOKEN }} spam-label: 'spam' ai-label: 'ai-generated' minimize-detected-comments: true enable-spam-detection: true enable-link-spam-detection: true enable-ai-detection: true # 账号年龄检查(仅针对新建 Issue) - name: Account age check if: github.event_name == 'issues' uses: actions/github-script@v7 with: script: | const issue = context.payload.issue; const username = issue.user.login; // 跳过项目成员 if (['OWNER', 'MEMBER', 'COLLABORATOR'].includes(issue.author_association)) { core.info(`Skip check for ${username} (${issue.author_association})`); return; } // 获取用户信息 const { data: user } = await github.rest.users.getByUsername({ username }); const accountAgeDays = Math.floor((Date.now() - new Date(user.created_at)) / 86400000); const isNewAccount = accountAgeDays < 30; if (!isNewAccount) { core.info(`${username} account age: ${accountAgeDays} days, OK`); return; } // 检查 AI moderator 是否已打 spam 标签 const { data: labels } = await github.rest.issues.listLabelsOnIssue({ ...context.repo, issue_number: issue.number }); const hasSpamLabel = labels.some(l => l.name === 'spam'); // 两个条件都满足:新账号 + AI 判定为垃圾 → 关闭 + 锁定 if (isNewAccount && hasSpamLabel) { await github.rest.issues.createComment({ ...context.repo, issue_number: issue.number, body: [ '👋 你好,感谢你对本项目的关注!', '', '为维护社区环境、防止垃圾信息和自动化 bot 的干扰,我们对 Issue 进行了自动审核。', '很遗憾,你的 Issue 未能通过审核(账号注册时间较短且内容触发了自动检测)。', '', '**如有误判,还请见谅!** 你可以在账号满 30 天后重新提交,或通过项目 README 中的联系方式反馈。', '', '感谢理解与支持 🙏', ].join('\n') }); await github.rest.issues.update({ ...context.repo, issue_number: issue.number, state: 'closed', state_reason: 'not_planned' }); await github.rest.issues.lock({ ...context.repo, issue_number: issue.number, lock_reason: 'spam' }); core.info(`Issue #${issue.number} closed: new account (${accountAgeDays}d) + spam detected`); }