Skip to content

Commit af577c1

Browse files
committed
add spam filtering
1 parent de53b25 commit af577c1

File tree

4 files changed

+77
-1
lines changed

4 files changed

+77
-1
lines changed

functions/src/github.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,20 @@ export class GitHubClient {
127127
});
128128
}
129129

130+
/**
131+
* Closes an issue on a github repo and erases its content.
132+
*/
133+
wipeIssue(org: string, name: string, issue_number: number): Promise<any> {
134+
return this.api.issues.update({
135+
owner: org,
136+
repo: name,
137+
issue_number,
138+
state: "closed",
139+
title: "Spam",
140+
body: "This issue was filtered as spam."
141+
});
142+
}
143+
130144
/**
131145
* Get all comments on a GitHUb issue.
132146
*/

functions/src/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,13 @@ async function executeAction(action: types.Action): Promise<any> {
379379
closeAction.name,
380380
closeAction.number
381381
);
382+
} else if (action.type == types.ActionType.GITHUB_SPAM) {
383+
const wipeAction = action as types.GitHubSpamAction;
384+
actionPromise = gh_client.wipeIssue(
385+
wipeAction.org,
386+
wipeAction.name,
387+
wipeAction.number
388+
);
382389
} else if (action.type == types.ActionType.GITHUB_LOCK) {
383390
const lockAction = action as types.GitHubLockAction;
384391
actionPromise = gh_client.lockIssue(

functions/src/issues.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,49 @@ export class IssueHandler {
241241
actions.push(...this.markNeedsTriage(repo, issue));
242242
}
243243

244+
// Filter spam from b/378634578. This can be removed in the future.
245+
const spamWords = [
246+
'pemain',
247+
'wallet wallet', // seems to be in most crypto issues
248+
'minecraft',
249+
'paybis',
250+
'blockchain',
251+
'official contact number',
252+
'phantom wallet',
253+
'defi wallet',
254+
'dogecoin',
255+
'crypto.com',
256+
'moonpay',
257+
'coinmama',
258+
'daftar',
259+
['wallet', 'support'],
260+
];
261+
const issueContent = ` ${issue.title} ${issue.body || ''} `.toLowerCase();
262+
// Scope spam filtering to affected repos only.
263+
const isAffectedRepo = org == "firebase" && (
264+
name == "flutterfire" ||
265+
name == "quickstart-android" ||
266+
name == "quickstart-ios"
267+
);
268+
const isSpam = isAffectedRepo && spamWords.find((wordOrArray) => {
269+
if (Array.isArray(wordOrArray)) {
270+
return wordOrArray.every((word) => issueContent.includes(word));
271+
} else {
272+
const wordWithSpace = ` ${wordOrArray} `;
273+
return issueContent.includes(wordWithSpace);
274+
}
275+
});
276+
277+
if (isSpam) {
278+
// Discard other actions and wipe the issue.
279+
const reason = `Issue is believed to be spam: ${issue.title}`
280+
return [
281+
new types.GitHubSpamAction(
282+
org, name, issue.number, reason
283+
)
284+
];
285+
}
286+
244287
// Check if it matches the template. This feature is implicitly enabled by
245288
// the template having "matchable" structure so there is no need to check
246289
// the repo's configuration.

functions/src/types.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export enum ActionType {
1212
GITHUB_CLOSE = "GITHUB_CLOSE",
1313
GITHUB_LOCK = "GITHUB_LOCK",
1414
GITHUB_NO_OP = "GITHUB_NO_OP",
15+
GITHUB_SPAM = "GITHUB_SPAM",
1516
EMAIL_SEND = "EMAIL_SEND"
1617
}
1718

@@ -21,7 +22,8 @@ export const GITHUB_ISSUE_ACTIONS = [
2122
ActionType.GITHUB_REMOVE_LABEL,
2223
ActionType.GITHUB_CLOSE,
2324
ActionType.GITHUB_LOCK,
24-
ActionType.GITHUB_NO_OP
25+
ActionType.GITHUB_NO_OP,
26+
ActionType.GITHUB_SPAM
2527
];
2628

2729
export class Action {
@@ -149,6 +151,16 @@ export class GitHubCloseAction extends GitHubIssueAction {
149151
}
150152
}
151153

154+
export class GitHubSpamAction extends GitHubIssueAction {
155+
constructor(org: string, name: string, number: number, reason?: string) {
156+
super(ActionType.GITHUB_SPAM, org, name, number);
157+
158+
if (reason) {
159+
this.reason = reason;
160+
}
161+
}
162+
}
163+
152164
export class GitHubLockAction extends GitHubIssueAction {
153165
constructor(org: string, name: string, number: number, reason?: string) {
154166
super(ActionType.GITHUB_LOCK, org, name, number);

0 commit comments

Comments
 (0)