Skip to content
Latchkey

Suspicious Comment Detection workflow (chainstacklabs/pumpfun-bonkfun-bot)

The Suspicious Comment Detection workflow from chainstacklabs/pumpfun-bonkfun-bot, explained and optimized by Latchkey.

A

CI health: A - excellent

Point runs-on at Latchkey and get job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: chainstacklabs/pumpfun-bonkfun-bot.github/workflows/spam-detection.ymlLicense Apache-2.0View source

What it does

This is the Suspicious Comment Detection workflow from the chainstacklabs/pumpfun-bonkfun-bot repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.

Below, Latchkey shows a faster, safer version produced by its optimization engine.

The workflow

workflow (.yml)
name: Suspicious Comment Detection

on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]

jobs:
  check_comment:
    runs-on: ubuntu-latest
    steps:
      - name: Check for suspicious patterns
        uses: actions/github-script@v6
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            try {
              const comment = context.payload.comment;
              const body = comment.body.toLowerCase();
              const author = comment.user.login;
              
              // Suspicious patterns
              const suspiciousPatterns = [
                'support team',
                'customer service',
                'telegram',
                'whatsapp',
                'contact us',
                'click here',
                'support group',
                't.me/',
                'wa.me/',
                'support chat',
                'live chat',
                'support ticket',
                'ticket id',
                'live support',
                'support line',
                'support agent',
                'support network',
                'dedicated support',
                'personalized assistance',
                'opened for you',
                'kindly talk to',
                'we apologize',
                'live chat with an agent',
                'chat button',
                'dapp portal',
                'decentralized dapp',
                'access the portal',
                'report your request',
                'start a conversation',
                'click the chat',
                'for assistance',
                'reach out to',
                'through the chat',
                'portal',
                'help center',
                'ticket',
                'this will be review',
                'bringing this to our notice',
                'initiate a chat',
                'regards',
                'hello @',
                'thanks for bringing',
              ];
              
              // Add pattern weight scoring
              const patternWeights = {
                'ticket id': 2,
                'support team': 2,
                'live support': 2,
                'help center': 2,
                // Regular patterns have weight of 1
              };
              
              // Calculate spam score
              let spamScore = 0;
              const foundPatterns = suspiciousPatterns.filter(pattern => {
                if (body.includes(pattern)) {
                  spamScore += patternWeights[pattern] || 1;
                  return true;
                }
                return false;
              });
              
              // Check for external links (excluding common legitimate domains)
              const hasExternalLinks = body.includes('http') || body.includes('www');
              const hasGithubLinks = body.includes('github.com');
              const suspiciousLinks = hasExternalLinks && !hasGithubLinks;
              
              // Trigger on either multiple patterns or high spam score
              if (foundPatterns.length > 2 || spamScore >= 3) {
                try {
                  // Create a warning comment
                  await github.rest.issues.createComment({
                    owner: context.repo.owner,
                    repo: context.repo.repo,
                    issue_number: context.payload.issue ? context.payload.issue.number : context.payload.pull_request.number,
                    body: warningMessage
                  });
                } catch (e) {
                  console.log('Failed to create comment:', e);
                }
                
                try {
                  // Add 'potential-scam' label
                  await github.rest.issues.addLabels({
                    owner: context.repo.owner,
                    repo: context.repo.repo,
                    issue_number: context.payload.issue ? context.payload.issue.number : context.payload.pull_request.number,
                    labels: ['potential-scam']
                  });
                } catch (e) {
                  console.log('Failed to add label:', e);
                }
              }
            } catch (e) {
              console.log('Workflow error:', e);
              // Still mark as failure but with more context
              core.setFailed(`Workflow failed: ${e.message}`);
            }

The same workflow, on Latchkey

Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.

name: Suspicious Comment Detection
 
on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]
 
jobs:
  check_comment:
    timeout-minutes: 30
    runs-on: latchkey-small
    steps:
      - name: Check for suspicious patterns
        uses: actions/github-script@v6
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            try {
              const comment = context.payload.comment;
              const body = comment.body.toLowerCase();
              const author = comment.user.login;
              
              // Suspicious patterns
              const suspiciousPatterns = [
                'support team',
                'customer service',
                'telegram',
                'whatsapp',
                'contact us',
                'click here',
                'support group',
                't.me/',
                'wa.me/',
                'support chat',
                'live chat',
                'support ticket',
                'ticket id',
                'live support',
                'support line',
                'support agent',
                'support network',
                'dedicated support',
                'personalized assistance',
                'opened for you',
                'kindly talk to',
                'we apologize',
                'live chat with an agent',
                'chat button',
                'dapp portal',
                'decentralized dapp',
                'access the portal',
                'report your request',
                'start a conversation',
                'click the chat',
                'for assistance',
                'reach out to',
                'through the chat',
                'portal',
                'help center',
                'ticket',
                'this will be review',
                'bringing this to our notice',
                'initiate a chat',
                'regards',
                'hello @',
                'thanks for bringing',
              ];
              
              // Add pattern weight scoring
              const patternWeights = {
                'ticket id': 2,
                'support team': 2,
                'live support': 2,
                'help center': 2,
                // Regular patterns have weight of 1
              };
              
              // Calculate spam score
              let spamScore = 0;
              const foundPatterns = suspiciousPatterns.filter(pattern => {
                if (body.includes(pattern)) {
                  spamScore += patternWeights[pattern] || 1;
                  return true;
                }
                return false;
              });
              
              // Check for external links (excluding common legitimate domains)
              const hasExternalLinks = body.includes('http') || body.includes('www');
              const hasGithubLinks = body.includes('github.com');
              const suspiciousLinks = hasExternalLinks && !hasGithubLinks;
              
              // Trigger on either multiple patterns or high spam score
              if (foundPatterns.length > 2 || spamScore >= 3) {
                try {
                  // Create a warning comment
                  await github.rest.issues.createComment({
                    owner: context.repo.owner,
                    repo: context.repo.repo,
                    issue_number: context.payload.issue ? context.payload.issue.number : context.payload.pull_request.number,
                    body: warningMessage
                  });
                } catch (e) {
                  console.log('Failed to create comment:', e);
                }
                
                try {
                  // Add 'potential-scam' label
                  await github.rest.issues.addLabels({
                    owner: context.repo.owner,
                    repo: context.repo.repo,
                    issue_number: context.payload.issue ? context.payload.issue.number : context.payload.pull_request.number,
                    labels: ['potential-scam']
                  });
                } catch (e) {
                  console.log('Failed to add label:', e);
                }
              }
            } catch (e) {
              console.log('Workflow error:', e);
              // Still mark as failure but with more context
              core.setFailed(`Workflow failed: ${e.message}`);
            }
 
 

What changed

This workflow runs 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow