[问题] rss新增订阅的内容不会翻译 #145
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Issue Guard | |
| on: | |
| issues: | |
| types: [opened] | |
| issue_comment: | |
| types: [created] | |
| pull_request: | |
| types: [opened] | |
| 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 | |
| # 两层防护: | |
| # 1) 账号 < 7 天 → 直接删除/关闭 | |
| # 2) 账号 >= 7 天 + AI 判定为垃圾 → 也删除/关闭 | |
| - name: Spam defense | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const MIN_ACCOUNT_AGE_DAYS = 7; | |
| const event = context.eventName; | |
| // 解析事件上下文 | |
| let username, authorAssociation, number, nodeId, commentId; | |
| let isIssue = false, isPR = false, isComment = false; | |
| if (event === 'issues') { | |
| const issue = context.payload.issue; | |
| username = issue.user.login; | |
| authorAssociation = issue.author_association; | |
| number = issue.number; | |
| isIssue = true; | |
| } else if (event === 'issue_comment') { | |
| const comment = context.payload.comment; | |
| username = comment.user.login; | |
| authorAssociation = comment.author_association; | |
| number = context.payload.issue.number; | |
| nodeId = comment.node_id; | |
| commentId = comment.id; | |
| isComment = true; | |
| isIssue = true; | |
| } else if (event === 'pull_request') { | |
| const pr = context.payload.pull_request; | |
| username = pr.user.login; | |
| authorAssociation = pr.author_association; | |
| number = pr.number; | |
| isPR = true; | |
| } else if (event === 'pull_request_review_comment') { | |
| const comment = context.payload.comment; | |
| username = comment.user.login; | |
| authorAssociation = comment.author_association; | |
| number = context.payload.pull_request.number; | |
| nodeId = comment.node_id; | |
| commentId = comment.id; | |
| isComment = true; | |
| isPR = true; | |
| } | |
| // 跳过项目成员 | |
| if (['OWNER', 'MEMBER', 'COLLABORATOR'].includes(authorAssociation)) { | |
| core.info(`Skip: ${username} (${authorAssociation})`); | |
| 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 < MIN_ACCOUNT_AGE_DAYS; | |
| // 判断是否需要拦截 | |
| let shouldBlock = false; | |
| let reason = ''; | |
| if (isNewAccount) { | |
| // 第一层:新账号直接拦截 | |
| shouldBlock = true; | |
| reason = `new account (${accountAgeDays}d < ${MIN_ACCOUNT_AGE_DAYS}d)`; | |
| } else { | |
| // 第二层:老账号检查 AI 垃圾判定 | |
| let isSpam = false; | |
| if (isComment) { | |
| const { node } = await github.graphql(` | |
| query($id: ID!) { | |
| node(id: $id) { | |
| ... on IssueComment { isMinimized } | |
| ... on PullRequestReviewComment { isMinimized } | |
| } | |
| } | |
| `, { id: nodeId }); | |
| isSpam = node?.isMinimized === true; | |
| } else { | |
| const { data: labels } = await github.rest.issues.listLabelsOnIssue({ | |
| ...context.repo, | |
| issue_number: number | |
| }); | |
| isSpam = labels.some(l => l.name === 'spam'); | |
| } | |
| if (isSpam) { | |
| shouldBlock = true; | |
| reason = `spam detected (account age: ${accountAgeDays}d)`; | |
| } | |
| } | |
| if (!shouldBlock) { | |
| core.info(`${username} (${accountAgeDays}d): OK`); | |
| return; | |
| } | |
| core.info(`Blocking ${event} #${number} from ${username}: ${reason}`); | |
| // 根据拦截原因生成不同提示 | |
| const notice = isNewAccount | |
| ? [ | |
| `@${username} 你好,感谢你对本项目的关注!`, | |
| '', | |
| '为维护社区环境、防止垃圾信息和自动化 bot 的干扰,', | |
| `本项目要求 GitHub 账号注册满 **${MIN_ACCOUNT_AGE_DAYS} 天**后才能参与互动。`, | |
| '', | |
| `你的账号注册时间为 ${accountAgeDays} 天,暂时无法参与。`, | |
| `请在账号满 ${MIN_ACCOUNT_AGE_DAYS} 天后重新提交,或通过项目 README 中的联系方式反馈。`, | |
| '', | |
| '感谢理解与支持 🙏', | |
| ].join('\n') | |
| : [ | |
| `@${username} 你好,`, | |
| '', | |
| '你的内容已被自动审核系统标记为垃圾信息并移除。', | |
| '', | |
| '**如有误判,还请见谅!** 请通过项目 README 中的联系方式反馈。', | |
| '', | |
| '感谢理解 🙏', | |
| ].join('\n'); | |
| // 执行拦截操作 | |
| if (isComment) { | |
| // 评论:直接删除 | |
| if (isIssue) { | |
| await github.rest.issues.deleteComment({ | |
| ...context.repo, | |
| comment_id: commentId | |
| }); | |
| } else { | |
| await github.rest.pulls.deleteReviewComment({ | |
| ...context.repo, | |
| comment_id: commentId | |
| }); | |
| } | |
| } else if (isIssue) { | |
| // 新建 Issue:评论提示 → 关闭 → 锁定 | |
| await github.rest.issues.createComment({ | |
| ...context.repo, | |
| issue_number: number, | |
| body: notice | |
| }); | |
| await github.rest.issues.update({ | |
| ...context.repo, | |
| issue_number: number, | |
| state: 'closed', | |
| state_reason: 'not_planned' | |
| }); | |
| await github.rest.issues.lock({ | |
| ...context.repo, | |
| issue_number: number, | |
| lock_reason: 'spam' | |
| }); | |
| } else if (isPR) { | |
| // 新建 PR:评论提示 → 关闭 | |
| await github.rest.issues.createComment({ | |
| ...context.repo, | |
| issue_number: number, | |
| body: notice | |
| }); | |
| await github.rest.pulls.update({ | |
| ...context.repo, | |
| pull_number: number, | |
| state: 'closed' | |
| }); | |
| } |