Suspicious Comment Detection workflow (chainstacklabs/pumpfun-bonkfun-bot)
The Suspicious Comment Detection workflow from chainstacklabs/pumpfun-bonkfun-bot, explained and optimized by Latchkey.
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.
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
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
- Run on Latchkey managed runners with one line (
runs-on), which apply the fixes below automatically and self-heal transient failures. This example useslatchkey-small; pick the runner size that fits the job. - Add a job timeout so a hung step cannot burn hours of runner time.
This workflow runs 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.