Please add a SEO expert agent #26
  
    
      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: Content Moderation | |
| 'on': | |
| issues: | |
| types: [opened, edited] | |
| issue_comment: | |
| types: [created, edited] | |
| pull_request: | |
| types: [opened, edited] | |
| pull_request_review_comment: | |
| types: [created, edited] | |
| jobs: | |
| moderate-content: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| issues: write | |
| pull-requests: write | |
| contents: read | |
| steps: | |
| - name: Check for inappropriate content | |
| id: content-check | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| // Define inappropriate content patterns | |
| const hateWords = [ | |
| // Racial slurs (censored for detection) | |
| 'n[i1]gg[e3]r', 'n[i1]gg[a4]', 'ch[i1]nk', 'sp[i1]c', | |
| 'k[i1]k[e3]', 'w[e3]tb[a4]ck', 'b[e3][a4]n[e3]r', | |
| 'g[o0][o0]k', 'r[a4]gh[e3][a4]d', | |
| // Homophobic/transphobic slurs | |
| 'f[a4]gg[o0]t', 'tr[a4]nn[y1]', 'd[y1]k[e3]', | |
| // Religious/ethnic slurs | |
| 'j[e3]w', 'r[a4]gh[e3][a4]d', 'c[a4]m[e3]lj[o0]ck[e3]y', | |
| // General offensive terms | |
| 'r[e3]t[a4]rd', 'sp[a4]st[i1]c' | |
| ]; | |
| const profanity = [ | |
| 'f[u*]ck[i1]ng?', 'sh[i1]t', 'b[i1]tch', 'c[u*]nt', | |
| 'p[i1]ss', 'd[a4]mn', 'h[e3]ll', 'cr[a4]p', '[a4]ss', | |
| 'b[a4]st[a4]rd' | |
| ]; | |
| const threats = [ | |
| 'k[i1]ll y[o0]u', 'd[i1][e3]', 'murd[e3]r', | |
| 'h[a4]rm y[o0]u', 'hurt y[o0]u', 'destroy y[o0]u', | |
| 'end y[o0]u' | |
| ]; | |
| // Get content based on event type | |
| let content = ''; | |
| let contentType = ''; | |
| let itemNumber = 0; | |
| if (context.eventName === 'issues') { | |
| content = context.payload.issue.title + ' ' + | |
| context.payload.issue.body; | |
| contentType = 'issue'; | |
| itemNumber = context.payload.issue.number; | |
| } else if (context.eventName === 'issue_comment') { | |
| content = context.payload.comment.body; | |
| contentType = 'issue comment'; | |
| itemNumber = context.payload.issue.number; | |
| } else if (context.eventName === 'pull_request') { | |
| content = context.payload.pull_request.title + ' ' + | |
| context.payload.pull_request.body; | |
| contentType = 'pull request'; | |
| itemNumber = context.payload.pull_request.number; | |
| } else if (context.eventName === | |
| 'pull_request_review_comment') { | |
| content = context.payload.comment.body; | |
| contentType = 'PR comment'; | |
| itemNumber = context.payload.pull_request.number; | |
| } | |
| if (!content) return; | |
| const normalizedContent = content.toLowerCase() | |
| .replace(/[^a-z0-9\s]/g, '') | |
| .replace(/\s+/g, ' '); | |
| // Check for violations | |
| let violation = null; | |
| let severity = 'low'; | |
| // Check hate speech (highest severity) | |
| for (const word of hateWords) { | |
| const regex = new RegExp(word, 'i'); | |
| if (regex.test(normalizedContent)) { | |
| violation = 'hate speech'; | |
| severity = 'critical'; | |
| break; | |
| } | |
| } | |
| // Check threats (high severity) | |
| if (!violation) { | |
| for (const threat of threats) { | |
| const regex = new RegExp(threat, 'i'); | |
| if (regex.test(normalizedContent)) { | |
| violation = 'threats'; | |
| severity = 'high'; | |
| break; | |
| } | |
| } | |
| } | |
| // Check excessive profanity (medium severity) | |
| if (!violation) { | |
| let profanityCount = 0; | |
| for (const word of profanity) { | |
| const regex = new RegExp(word, 'gi'); | |
| const matches = normalizedContent.match(regex); | |
| if (matches) profanityCount += matches.length; | |
| } | |
| if (profanityCount >= 3) { | |
| violation = 'excessive profanity'; | |
| severity = 'medium'; | |
| } | |
| } | |
| // Set outputs | |
| core.setOutput('violation', violation || 'none'); | |
| core.setOutput('severity', severity); | |
| core.setOutput('content-type', contentType); | |
| core.setOutput('item-number', itemNumber); | |
| if (violation) { | |
| console.log( | |
| `⚠️ Detected ${violation} (${severity} severity) ` + | |
| `in ${contentType} #${itemNumber}` | |
| ); | |
| } | |
| - name: Handle critical violations | |
| if: >- | |
| steps.content-check.outputs.violation != 'none' && | |
| steps.content-check.outputs.severity == 'critical' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const itemNumber = | |
| ${{ steps.content-check.outputs.item-number }}; | |
| const contentType = | |
| '${{ steps.content-check.outputs.content-type }}'; | |
| const violation = | |
| '${{ steps.content-check.outputs.violation }}'; | |
| if (contentType === 'issue') { | |
| // Close and lock the issue immediately | |
| await github.rest.issues.update({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: itemNumber, | |
| state: 'closed' | |
| }); | |
| await github.rest.issues.lock({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: itemNumber, | |
| lock_reason: 'off-topic' | |
| }); | |
| // Add moderation comment | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: itemNumber, | |
| body: '🚫 **This issue has been automatically closed ' + | |
| 'and locked due to a Code of Conduct violation.**' + | |
| `\n\n**Violation**: ${violation}\n\n` + | |
| '**This action was taken because the content ' + | |
| 'violates our community standards. Repeated ' + | |
| 'violations may result in being blocked from ' + | |
| 'this repository.**\n\n📖 Please review our ' + | |
| '[Code of Conduct](.github/CODE_OF_CONDUCT.md) ' + | |
| 'and [Contributing Guidelines]' + | |
| '(.github/CONTRIBUTING.md).' | |
| }); | |
| } | |
| - name: Handle high severity violations | |
| if: >- | |
| steps.content-check.outputs.violation != 'none' && | |
| steps.content-check.outputs.severity == 'high' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const itemNumber = | |
| ${{ steps.content-check.outputs.item-number }}; | |
| const contentType = | |
| '${{ steps.content-check.outputs.content-type }}'; | |
| if (contentType === 'issue') { | |
| // Add warning label and comment | |
| await github.rest.issues.addLabels({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: itemNumber, | |
| labels: ['moderation-review'] | |
| }); | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: itemNumber, | |
| body: `⚠️ **Content Warning**: This ${contentType} ` + | |
| 'has been flagged for moderation review due to ' + | |
| 'potentially inappropriate content.\n\nPlease ' + | |
| 'ensure all content follows our ' + | |
| '[Code of Conduct](.github/CODE_OF_CONDUCT.md). ' + | |
| 'A maintainer will review this shortly.' | |
| }); | |
| } | |
| - name: Notify maintainers | |
| if: steps.content-check.outputs.violation != 'none' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const violation = | |
| '${{ steps.content-check.outputs.violation }}'; | |
| const severity = | |
| '${{ steps.content-check.outputs.severity }}'; | |
| const contentType = | |
| '${{ steps.content-check.outputs.content-type }}'; | |
| const itemNumber = | |
| ${{ steps.content-check.outputs.item-number }}; | |
| // Create a moderation alert issue | |
| await github.rest.issues.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| title: `[MODERATION ALERT] ${violation} detected in ` + | |
| `${contentType} #${itemNumber}`, | |
| body: '🚨 **Automated Moderation Alert**\n\n' + | |
| '**Details:**\n' + | |
| `- **Type**: ${violation} (${severity} severity)\n` + | |
| `- **Location**: ${contentType} #${itemNumber}\n` + | |
| '- **Action taken**: ' + | |
| (severity === 'critical' ? | |
| 'Automatically closed and locked' : | |
| 'Flagged for review') + | |
| '\n\n**Next steps:**\n' + | |
| '- [ ] Review the flagged content\n' + | |
| '- [ ] Take additional action if needed\n' + | |
| '- [ ] Consider blocking repeat offenders\n\n' + | |
| '**Links:**\n' + | |
| `- [View ${contentType} #${itemNumber}]` + | |
| `(https://github.com/${context.repo.owner}/` + | |
| `${context.repo.repo}/` + | |
| (contentType === 'issue' ? 'issues' : 'pull') + | |
| `/${itemNumber})\n\n` + | |
| 'This alert was generated automatically by the ' + | |
| 'content moderation system.', | |
| labels: ['moderation', 'automated-alert'] | |
| }); | |
| console.log( | |
| `📧 Created moderation alert for ${violation} ` + | |
| `in ${contentType} #${itemNumber}` | |
| ); |