Skip to content

Commit

Permalink
fmt
Browse files Browse the repository at this point in the history
  • Loading branch information
elliotBraem committed Dec 12, 2024
1 parent 1bcfc41 commit e8ee9f5
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 63 deletions.
22 changes: 12 additions & 10 deletions src/config/config.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import { AppConfig } from '../types';
import { AppConfig } from "../types";

const config: AppConfig = {
twitter: {
apiKey: process.env.TWITTER_API_KEY || '',
apiSecret: process.env.TWITTER_API_SECRET || '',
accessToken: process.env.TWITTER_ACCESS_TOKEN || '',
accessTokenSecret: process.env.TWITTER_ACCESS_TOKEN_SECRET || '',
apiKey: process.env.TWITTER_API_KEY || "",
apiSecret: process.env.TWITTER_API_SECRET || "",
accessToken: process.env.TWITTER_ACCESS_TOKEN || "",
accessTokenSecret: process.env.TWITTER_ACCESS_TOKEN_SECRET || "",
},
near: {
networkId: process.env.NEAR_NETWORK_ID || 'testnet',
nodeUrl: process.env.NEAR_NODE_URL || 'https://rpc.testnet.near.org',
walletUrl: process.env.NEAR_WALLET_URL || 'https://wallet.testnet.near.org',
contractName: process.env.NEAR_CONTRACT_NAME || 'dev-1234567890-1234567890',
networkId: process.env.NEAR_NETWORK_ID || "testnet",
nodeUrl: process.env.NEAR_NODE_URL || "https://rpc.testnet.near.org",
walletUrl: process.env.NEAR_WALLET_URL || "https://wallet.testnet.near.org",
contractName: process.env.NEAR_CONTRACT_NAME || "dev-1234567890-1234567890",
},
environment: (process.env.NODE_ENV as 'development' | 'production' | 'test') || 'development',
environment:
(process.env.NODE_ENV as "development" | "production" | "test") ||
"development",
};

export default config;
18 changes: 9 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import dotenv from 'dotenv';
import { TwitterService } from './services/twitter/client';
import { NearService } from './services/near';
import config from './config/config';
import dotenv from "dotenv";
import { TwitterService } from "./services/twitter/client";
import { NearService } from "./services/near";
import config from "./config/config";

// Load environment variables
dotenv.config();
Expand All @@ -14,20 +14,20 @@ async function main() {
// Initialize Twitter service
const twitterService = new TwitterService(config.twitter.apiKey);
await twitterService.initialize();

// Start Twitter stream
const stream = await twitterService.startStream();

// Handle graceful shutdown
process.on('SIGINT', async () => {
console.log('Shutting down...');
process.on("SIGINT", async () => {
console.log("Shutting down...");
stream.destroy();
process.exit(0);
});

console.log('Bot is running...');
console.log("Bot is running...");
} catch (error) {
console.error('Error starting the bot:', error);
console.error("Error starting the bot:", error);
process.exit(1);
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/services/near/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { connect, keyStores, Near } from 'near-api-js';
import type { NearConfig } from '../../types';
import { connect, keyStores, Near } from "near-api-js";
import type { NearConfig } from "../../types";

export class NearService {
private near: Near;
Expand All @@ -17,7 +17,7 @@ export class NearService {
const account = await this.near.account(accountId);
return account;
} catch (error) {
console.error('Error getting NEAR account:', error);
console.error("Error getting NEAR account:", error);
throw error;
}
}
Expand All @@ -32,7 +32,7 @@ export class NearService {
});
return result;
} catch (error) {
console.error('Error calling view method:', error);
console.error("Error calling view method:", error);
throw error;
}
}
Expand All @@ -41,7 +41,7 @@ export class NearService {
contractId: string,
method: string,
args: object = {},
deposit: string = '0'
deposit: string = "0",
) {
try {
const account = await this.near.account(contractId);
Expand All @@ -53,7 +53,7 @@ export class NearService {
});
return result;
} catch (error) {
console.error('Error calling method:', error);
console.error("Error calling method:", error);
throw error;
}
}
Expand Down
72 changes: 42 additions & 30 deletions src/services/twitter/client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { TwitterApi } from 'twitter-api-v2';
import { TwitterSubmission, Moderation } from '../../types/twitter';
import { ADMIN_ACCOUNTS } from '../../config/admins';
import { TwitterApi } from "twitter-api-v2";
import { TwitterSubmission, Moderation } from "../../types/twitter";
import { ADMIN_ACCOUNTS } from "../../config/admins";

interface TwitterHashtag {
tag: string;
Expand Down Expand Up @@ -35,35 +35,40 @@ export class TwitterService {
const rules = await this.client.v2.streamRules();
if (rules.data?.length) {
await this.client.v2.updateStreamRules({
delete: { ids: rules.data.map(rule => rule.id) }
delete: { ids: rules.data.map((rule) => rule.id) },
});
}

// Add new rules
await this.client.v2.updateStreamRules({
add: [
{ value: '!submit', tag: 'submissions' },
{ value: '#approve', tag: 'approvals' },
{ value: '#reject', tag: 'rejections' }
]
{ value: "!submit", tag: "submissions" },
{ value: "#approve", tag: "approvals" },
{ value: "#reject", tag: "rejections" },
],
});
}

async startStream() {
const stream = await this.client.v2.searchStream({
'tweet.fields': ['author_id', 'referenced_tweets', 'entities', 'created_at'],
'user.fields': ['username']
"tweet.fields": [
"author_id",
"referenced_tweets",
"entities",
"created_at",
],
"user.fields": ["username"],
});

stream.on('data', async (data: TweetData) => {
stream.on("data", async (data: TweetData) => {
try {
if (this.isSubmission(data)) {
await this.handleSubmission(data);
} else if (this.isModeration(data)) {
await this.handleModeration(data);
}
} catch (error) {
console.error('Error processing tweet:', error);
console.error("Error processing tweet:", error);
}
});

Expand All @@ -75,24 +80,30 @@ export class TwitterService {
const dailyCount = this.submissionCount.get(userId) || 0;

if (dailyCount >= this.DAILY_SUBMISSION_LIMIT) {
await this.replyToTweet(tweet.id,
"You've reached your daily submission limit. Please try again tomorrow.");
await this.replyToTweet(
tweet.id,
"You've reached your daily submission limit. Please try again tomorrow.",
);
return;
}

const submission: TwitterSubmission = {
tweetId: tweet.id,
userId: userId,
content: tweet.text,
hashtags: tweet.entities?.hashtags?.map((h: TwitterHashtag) => h.tag) || [],
status: 'pending',
moderationHistory: []
hashtags:
tweet.entities?.hashtags?.map((h: TwitterHashtag) => h.tag) || [],
status: "pending",
moderationHistory: [],
};

this.submissions.set(tweet.id, submission);
this.submissionCount.set(userId, dailyCount + 1);

await this.replyToTweet(tweet.id, "Successfully submitted to publicgoods.news!");

await this.replyToTweet(
tweet.id,
"Successfully submitted to publicgoods.news!",
);
}

private async handleModeration(tweet: TweetData): Promise<void> {
Expand All @@ -113,7 +124,7 @@ export class TwitterService {

// Check if this admin has already moderated this submission
const hasModerated = submission.moderationHistory.some(
mod => mod.adminId === tweet.author_id
(mod) => mod.adminId === tweet.author_id,
);
if (hasModerated) return;

Expand All @@ -122,16 +133,16 @@ export class TwitterService {
adminId: tweet.author_id,
action: action,
timestamp: new Date(tweet.created_at),
tweetId: tweet.id
tweetId: tweet.id,
};
submission.moderationHistory.push(moderation);

// Update submission status based on latest moderation
submission.status = action === 'approve' ? 'approved' : 'rejected';
submission.status = action === "approve" ? "approved" : "rejected";
this.submissions.set(referencedTweet.id, submission);

// Process the moderation action
if (action === 'approve') {
if (action === "approve") {
await this.processApproval(submission);
} else {
await this.processRejection(submission);
Expand All @@ -142,21 +153,22 @@ export class TwitterService {
// TODO: Add NEAR integration here for approved submissions
await this.replyToTweet(
submission.tweetId,
"Your submission has been approved and will be added to the public goods news feed!"
"Your submission has been approved and will be added to the public goods news feed!",
);
}

private async processRejection(submission: TwitterSubmission): Promise<void> {
await this.replyToTweet(
submission.tweetId,
"Your submission has been reviewed and was not accepted for the public goods news feed."
"Your submission has been reviewed and was not accepted for the public goods news feed.",
);
}

private getModerationAction(tweet: TweetData): 'approve' | 'reject' | null {
const hashtags = tweet.entities?.hashtags?.map(h => h.tag.toLowerCase()) || [];
if (hashtags.includes('approve')) return 'approve';
if (hashtags.includes('reject')) return 'reject';
private getModerationAction(tweet: TweetData): "approve" | "reject" | null {
const hashtags =
tweet.entities?.hashtags?.map((h) => h.tag.toLowerCase()) || [];
if (hashtags.includes("approve")) return "approve";
if (hashtags.includes("reject")) return "reject";
return null;
}

Expand All @@ -165,7 +177,7 @@ export class TwitterService {
}

private isSubmission(tweet: TweetData): boolean {
return tweet.text.toLowerCase().includes('!submit');
return tweet.text.toLowerCase().includes("!submit");
}

private async replyToTweet(tweetId: string, message: string): Promise<void> {
Expand Down
10 changes: 5 additions & 5 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
export * from './twitter';
export * from './near';
export * from "./twitter";
export * from "./near";

export interface AppConfig {
twitter: import('./twitter').TwitterConfig;
near: import('./near').NearConfig;
environment: 'development' | 'production' | 'test';
twitter: import("./twitter").TwitterConfig;
near: import("./near").NearConfig;
environment: "development" | "production" | "test";
}
2 changes: 1 addition & 1 deletion src/types/near.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export interface NewsProposal {
submitter: string;
content: string;
category: string;
status: 'pending' | 'approved' | 'rejected';
status: "pending" | "approved" | "rejected";
tweetId: string;
}

Expand Down
4 changes: 2 additions & 2 deletions src/types/twitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ export interface TwitterSubmission {
hashtags: Array<string>;
category?: string;
description?: string;
status: 'pending' | 'approved' | 'rejected';
status: "pending" | "approved" | "rejected";
moderationHistory: Moderation[];
}

export interface Moderation {
adminId: string;
action: 'approve' | 'reject';
action: "approve" | "reject";
timestamp: Date;
tweetId: string;
}
Expand Down

0 comments on commit e8ee9f5

Please sign in to comment.