Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip: Auto Trader - Super Goat #1100

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/client-reddit/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*

!dist/**
!package.json
!readme.md
!tsup.config.ts
3 changes: 3 additions & 0 deletions packages/client-reddit/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import eslintGlobalConfig from "../../eslint.config.mjs";

export default [...eslintGlobalConfig];
22 changes: 22 additions & 0 deletions packages/client-reddit/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "@ai16z/client-reddit",
"version": "0.1.0",
"main": "dist/index.js",
"type": "module",
"types": "dist/index.d.ts",
"dependencies": {
"@ai16z/eliza": "workspace:*",
"snoowrap": "^1.23.0"
},
"devDependencies": {
"@types/node": "^20.0.0",
"tsup": "8.3.5",
"vitest": "^2.1.4"
},
"scripts": {
"build": "tsup --format esm --dts",
"dev": "tsup --format esm --dts --watch",
"test": "vitest run",
"test:watch": "vitest watch"
}
}
49 changes: 49 additions & 0 deletions packages/client-reddit/src/actions/comment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Action, IAgentRuntime, Memory } from "@ai16z/eliza";

export const createComment: Action = {
name: "CREATE_REDDIT_COMMENT",
similes: ["COMMENT_ON_REDDIT", "REPLY_ON_REDDIT"],
validate: async (runtime: IAgentRuntime, message: Memory) => {
const hasCredentials = !!runtime.getSetting("REDDIT_CLIENT_ID") &&
!!runtime.getSetting("REDDIT_CLIENT_SECRET") &&
!!runtime.getSetting("REDDIT_REFRESH_TOKEN");
return hasCredentials;
},
handler: async (
runtime: IAgentRuntime,
message: Memory,
state: any,
options: any
) => {
const { reddit } = await runtime.getProvider("redditProvider");

// Extract post ID and comment content from message
const postId = options.postId; // This should be a fullname (t3_postid)
const content = message.content.text;

try {
await reddit.getSubmission(postId).reply(content);
return true;
} catch (error) {
console.error("Failed to create Reddit comment:", error);
return false;
}
},
examples: [
[
{
user: "{{user1}}",
content: {
text: "Comment on this Reddit post: t3_abc123 with: Great post!"
},
},
{
user: "{{agentName}}",
content: {
text: "I'll add that comment to the Reddit post",
action: "CREATE_REDDIT_COMMENT",
},
},
],
],
};
88 changes: 88 additions & 0 deletions packages/client-reddit/src/actions/post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { Action, IAgentRuntime, Memory } from "@ai16z/eliza";
import { RedditPost } from "../types";

export const createPost: Action = {
name: "CREATE_REDDIT_POST",
similes: ["POST_TO_REDDIT", "SUBMIT_REDDIT_POST"],
validate: async (runtime: IAgentRuntime, message: Memory) => {
const hasCredentials = !!runtime.getSetting("REDDIT_CLIENT_ID") &&
!!runtime.getSetting("REDDIT_CLIENT_SECRET") &&
!!runtime.getSetting("REDDIT_REFRESH_TOKEN");
return hasCredentials;
},
handler: async (
runtime: IAgentRuntime,
message: Memory,
state: any,
options: any
) => {
const { reddit } = await runtime.getProvider("redditProvider");

// Parse the subreddit and content from the message
// Expected format: "Post to r/subreddit: Title | Content"
const messageText = message.content.text;
const match = messageText.match(/Post to r\/(\w+):\s*([^|]+)\|(.*)/i);

if (!match) {
throw new Error("Invalid post format. Use: Post to r/subreddit: Title | Content");
}

const [_, subreddit, title, content] = match;

try {
const post = await reddit.submitSelfpost({
subredditName: subreddit.trim(),
title: title.trim(),
text: content.trim()
});

return {
success: true,
data: {
id: post.id,
url: post.url,
subreddit: post.subreddit.display_name,
title: post.title
}
};
} catch (error) {
console.error("Failed to create Reddit post:", error);
return {
success: false,
error: error.message
};
}
},
examples: [
[
{
user: "{{user1}}",
content: {
text: "Post to r/test: My First Post | This is the content of my post"
},
},
{
user: "{{agentName}}",
content: {
text: "I'll create that post on r/test for you",
action: "CREATE_REDDIT_POST",
},
},
],
[
{
user: "{{user1}}",
content: {
text: "Post to r/AskReddit: What's your favorite book? | I'm curious to know what books everyone loves and why."
},
},
{
user: "{{agentName}}",
content: {
text: "Creating your post on r/AskReddit",
action: "CREATE_REDDIT_POST",
},
},
],
],
};
49 changes: 49 additions & 0 deletions packages/client-reddit/src/actions/vote.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Action, IAgentRuntime, Memory } from "@ai16z/eliza";

export const vote: Action = {
name: "REDDIT_VOTE",
similes: ["UPVOTE_ON_REDDIT", "DOWNVOTE_ON_REDDIT"],
validate: async (runtime: IAgentRuntime, message: Memory) => {
const hasCredentials = !!runtime.getSetting("REDDIT_CLIENT_ID") &&
!!runtime.getSetting("REDDIT_CLIENT_SECRET") &&
!!runtime.getSetting("REDDIT_REFRESH_TOKEN");
return hasCredentials;
},
handler: async (
runtime: IAgentRuntime,
message: Memory,
state: any,
options: any
) => {
const { reddit } = await runtime.getProvider("redditProvider");

// Extract target ID and vote direction
const targetId = options.targetId; // fullname of post/comment
const direction = options.direction; // 1 for upvote, -1 for downvote

try {
await reddit.getSubmission(targetId).upvote(); // or downvote()
return true;
} catch (error) {
console.error("Failed to vote on Reddit:", error);
return false;
}
},
examples: [
[
{
user: "{{user1}}",
content: {
text: "Upvote this Reddit post: t3_abc123"
},
},
{
user: "{{agentName}}",
content: {
text: "I'll upvote that post for you",
action: "REDDIT_VOTE",
},
},
],
],
};
52 changes: 52 additions & 0 deletions packages/client-reddit/src/clients/redditClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { IAgentRuntime, elizaLogger } from "@ai16z/eliza";
import { RedditProvider } from "../providers/redditProvider";
import { RedditPostClient } from "./redditPostClient";
import Snoowrap from "snoowrap";

export class RedditClient {
provider: RedditProvider;
postClient: RedditPostClient;
runtime: IAgentRuntime;

constructor(runtime: IAgentRuntime) {
this.runtime = runtime;
const reddit = new Snoowrap({
userAgent: runtime.getSetting("REDDIT_USER_AGENT"),
clientId: runtime.getSetting("REDDIT_CLIENT_ID"),
clientSecret: runtime.getSetting("REDDIT_CLIENT_SECRET"),
refreshToken: runtime.getSetting("REDDIT_REFRESH_TOKEN")
});
this.provider = new RedditProvider(runtime, reddit);
this.postClient = new RedditPostClient(runtime, this.provider);
}

async start() {
elizaLogger.info("Starting Reddit client");
await this.provider.start();

const autoPost = this.runtime.getSetting("REDDIT_AUTO_POST") === "true";
if (autoPost) {
elizaLogger.info("Auto-posting enabled for Reddit");
await this.postClient.start(true);
}
}

async stop() {
elizaLogger.info("Stopping Reddit client");
await this.postClient.stop();
}

async submitPost(subreddit: string, title: string, content: string) {
try {
const post = await this.provider.submitSelfpost({
subredditName: subreddit,
title,
text: content
});
return post;
} catch (error) {
elizaLogger.error("Error submitting Reddit post:", error);
throw error;
}
}
}
Loading
Loading