Skip to content

Commit 52f77f9

Browse files
committed
feat: add verified date function and clean up
1 parent a21e836 commit 52f77f9

File tree

2 files changed

+94
-14
lines changed

2 files changed

+94
-14
lines changed

app/rules/icebreaker.ts

Lines changed: 91 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ async function hasIcebreakerLinkedAccount({ user: member, rule }: CheckFunctionA
252252
};
253253
}
254254

255-
async function hasGreaterThanVerifiedTwitterFollowers({ user: member, rule }: CheckFunctionArgs) {
255+
async function hasVerifiedTwitterFollowersGreaterThan({ user: member, rule }: CheckFunctionArgs) {
256256
const { threshold } = rule.args as { threshold: string };
257257

258258
if (!threshold || isNaN(+threshold)) {
@@ -271,14 +271,14 @@ async function hasGreaterThanVerifiedTwitterFollowers({ user: member, rule }: Ch
271271
message: `@${member.username} not found in Icebreaker`,
272272
};
273273
}
274-
// get twitter followers for user verified twitter account
274+
275275
const verifiedTwitterAccount = user.channels?.find(
276276
(channel) => channel.type === "twitter" && channel.isVerified
277277
)?.value;
278278

279279
const metadata = verifiedTwitterAccount ? await getTwitterMetadata(verifiedTwitterAccount) : undefined;
280280

281-
const followerCount = metadata && extractTwitterFollowerCount(metadata);
281+
const followerCount = extractTwitterFollowerCount(metadata);
282282

283283
const userHasGreaterThanThreshold = !!followerCount && followerCount > thresholdNumber;
284284

@@ -292,6 +292,56 @@ async function hasGreaterThanVerifiedTwitterFollowers({ user: member, rule }: Ch
292292
};
293293
}
294294

295+
async function hasVerifiedTwitterCreatedBefore({ user: member, rule }: CheckFunctionArgs) {
296+
const { threshold } = rule.args as { threshold: string };
297+
298+
const isValidDateFormat = (dateString: string) => {
299+
const regex = /^\d{4}-\d{2}-\d{2}$/;
300+
if (!regex.test(dateString)) return false;
301+
302+
const date = new Date(dateString);
303+
return dateString === date.toISOString().split("T")[0];
304+
};
305+
306+
// Check if threshold can be parsed as a valid date
307+
if (!threshold || !isValidDateFormat(threshold)) {
308+
return {
309+
result: false,
310+
message: "Invalid threshold value. Please provide a valid date.",
311+
};
312+
}
313+
314+
const thresholdDate = new Date(threshold);
315+
316+
const user = await getIcebreakerbyFid(member.fid);
317+
318+
if (!user) {
319+
return {
320+
result: false,
321+
message: `@${member.username} not found in Icebreaker`,
322+
};
323+
}
324+
325+
const verifiedTwitterAccount = user.channels?.find(
326+
(channel) => channel.type === "twitter" && channel.isVerified
327+
)?.value;
328+
329+
const metadata = verifiedTwitterAccount ? await getTwitterMetadata(verifiedTwitterAccount) : undefined;
330+
331+
const createdAt = extractTwitterCreatedAt(metadata);
332+
333+
const userHasGreaterThanThreshold = !!createdAt && createdAt < thresholdDate;
334+
335+
return {
336+
result: userHasGreaterThanThreshold,
337+
message: createdAt
338+
? `@${member.username} created Twitter account on ${createdAt.toDateString()}`
339+
: metadata
340+
? `Unable to retrieve created date for @${member.username}`
341+
: `Unable to find a verified Twitter account for @${member.username}`,
342+
};
343+
}
344+
295345
async function hasPOAP({ user: member, rule }: CheckFunctionArgs) {
296346
const { eventId } = rule.args as { eventId: string };
297347

@@ -344,9 +394,10 @@ type RuleName =
344394
| "hasIcebreakerQBuilder"
345395
| "hasIcebreakerVerified"
346396
| "hasIcebreakerLinkedAccount"
347-
| "hasPOAP"
348397
| "hasGuildRole"
349-
| "hasGreaterThanVerifiedTwitterFollowers";
398+
| "hasPOAP"
399+
| "hasVerifiedTwitterCreatedBefore"
400+
| "hasVerifiedTwitterFollowersGreaterThan";
350401

351402
const author = "Icebreaker";
352403
const authorUrl = "https://icebreaker.xyz";
@@ -458,29 +509,56 @@ export const iceBreakerRulesDefinitions: Record<RuleName, RuleDefinition> = {
458509
},
459510
},
460511

461-
hasGreaterThanVerifiedTwitterFollowers: {
462-
name: "hasGreaterThanVerifiedTwitterFollowers",
463-
allowMultiple: true,
512+
hasVerifiedTwitterFollowersGreaterThan: {
513+
name: "hasVerifiedTwitterFollowersGreaterThan",
514+
allowMultiple: false,
464515
author,
465516
authorUrl,
466517
authorIcon,
467518
category: "all",
468-
friendlyName: "Icebreaker: Has Greater Than X Verified Twitter Followers",
519+
friendlyName: "Icebreaker: Has verified Twitter account with greater than X followers",
469520
checkType: "user",
470521
description: "Check if the user has more than a certain number of followers on their verified Twitter account",
471522
hidden: false,
472523
invertable: true,
473524
args: {
474525
threshold: {
475526
type: "string",
476-
friendlyName: "Follower Threshold",
527+
pattern: "^[0-9]*$",
528+
defaultValue: "1000",
529+
friendlyName: "Follower minimum",
477530
description: "The minimum number of followers required",
478531
placeholder: "Enter a number...",
479532
required: true,
480533
},
481534
},
482535
},
483536

537+
hasVerifiedTwitterCreatedBefore: {
538+
name: "hasVerifiedTwitterCreatedBefore",
539+
allowMultiple: false,
540+
author,
541+
authorUrl,
542+
authorIcon,
543+
category: "all",
544+
friendlyName: "Icebreaker: Has verified Twitter account created before a date",
545+
checkType: "user",
546+
description: "Check if the user has a verified Twitter account created before a given date",
547+
hidden: false,
548+
invertable: true,
549+
args: {
550+
threshold: {
551+
type: "string",
552+
pattern: "^d{4}-d{2}-d{2}$",
553+
defaultValue: "2021-01-01",
554+
friendlyName: "Created before",
555+
description: "The latest creation date of the Twitter account",
556+
placeholder: "Enter a date in YYYY-MM-DD format...",
557+
required: true,
558+
},
559+
},
560+
},
561+
484562
hasPOAP: {
485563
name: "hasPOAP",
486564
allowMultiple: true,
@@ -543,7 +621,8 @@ export const iceBreakerRulesFunction: Record<RuleName, CheckFunction> = {
543621
hasIcebreakerVerified: hasIcebreakerVerified,
544622
hasIcebreakerCredential: hasIcebreakerCredential,
545623
hasIcebreakerLinkedAccount: hasIcebreakerLinkedAccount,
546-
hasPOAP: hasPOAP,
547624
hasGuildRole: hasGuildRole,
548-
hasGreaterThanVerifiedTwitterFollowers: hasGreaterThanVerifiedTwitterFollowers,
625+
hasPOAP: hasPOAP,
626+
hasVerifiedTwitterCreatedBefore: hasVerifiedTwitterCreatedBefore,
627+
hasVerifiedTwitterFollowersGreaterThan: hasVerifiedTwitterFollowersGreaterThan,
549628
} as const;

app/rules/rules.type.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@ export const ruleNames = [
3333
"hasIcebreakerVerified",
3434
"hasIcebreakerCredential",
3535
"hasIcebreakerLinkedAccount",
36-
"hasGreaterThanVerifiedTwitterFollowers",
37-
"hasPOAP",
3836
"hasGuildRole",
37+
"hasPOAP",
38+
"hasVerifiedTwitterCreatedBefore",
39+
"hasVerifiedTwitterFollowersGreaterThan",
3940
"membershipFeeRequired",
4041
] as const;
4142

0 commit comments

Comments
 (0)