← back to Goodquestion Ai
scripts/bsky-engage-wave3.cjs
100 lines
const { BskyAgent, RichText } = require('@atproto/api');
async function main() {
const agent = new BskyAgent({ service: 'https://bsky.social' });
await agent.login({ identifier: 'agentabrams.bsky.social', password: '*Blueaccess911*' });
async function replyToPost(postUri, replyText) {
try {
const thread = await agent.getPostThread({ uri: postUri, depth: 0 });
const post = thread.data.thread.post;
const rt = new RichText({ text: replyText });
await rt.detectFacets(agent);
await agent.post({
text: rt.text,
facets: rt.facets,
reply: {
root: { uri: post.uri, cid: post.cid },
parent: { uri: post.uri, cid: post.cid }
},
createdAt: new Date().toISOString(),
});
console.log('Replied to @' + post.author.handle);
return true;
} catch(e) {
console.log('Reply skip: ' + (e.message || '').substring(0, 60));
return false;
}
}
// Search for fresh posts about building with AI, shipping, solo dev
const queries = ['building with ai', 'solo dev ai', 'shipped today', 'mcp server', 'claude api'];
let allPosts = [];
for (const q of queries) {
try {
const r = await agent.app.bsky.feed.searchPosts({ q, limit: 5, sort: 'latest' });
for (const p of r.data.posts) {
if (p.author.handle !== 'agentabrams.bsky.social') {
allPosts.push(p);
}
}
} catch(e) {}
}
// Deduplicate
const seen = new Set();
allPosts = allPosts.filter(p => {
if (seen.has(p.uri)) return false;
seen.add(p.uri);
return true;
});
console.log('Found ' + allPosts.length + ' fresh posts');
// Like everything relevant
let liked = 0;
for (const p of allPosts.slice(0, 12)) {
try {
await agent.like(p.uri, p.cid);
console.log('Liked @' + p.author.handle + ': ' + (p.record.text || '').substring(0, 70));
liked++;
} catch(e) {}
}
console.log('Liked ' + liked + ' posts\n');
// Pick 3 to reply to with thoughtful short comments
const replyPairs = [];
for (const p of allPosts) {
const t = (p.record.text || '').toLowerCase();
if (t.includes('ship') || t.includes('built') || t.includes('launch')) {
replyPairs.push([p.uri, 'Shipping beats perfection every time. Nice work.']);
} else if (t.includes('mcp') || t.includes('plugin') || t.includes('extension')) {
replyPairs.push([p.uri, 'The MCP ecosystem is still early but the composability is already wild. Every good tool makes the whole stack better.']);
} else if (t.includes('solo') || t.includes('indie') || t.includes('one person')) {
replyPairs.push([p.uri, 'Solo + AI agents is the new small team. The leverage is real.']);
} else if (t.includes('api') || t.includes('integrat')) {
replyPairs.push([p.uri, 'APIs are the nervous system. Once the agents can call them reliably, everything compounds.']);
}
if (replyPairs.length >= 3) break;
}
for (const [uri, text] of replyPairs) {
await replyToPost(uri, text);
}
// Post a third original thought
const text3 = 'Things I learned running 50+ autonomous agents in production:\n\n1. The agent that monitors other agents is the most important one\n2. Rate limits are your friend not your enemy\n3. Every agent needs a kill switch\n4. Log everything. You will need it at 2am.\n\n#AIAgents #DevOps';
const rt3 = new RichText({ text: text3 });
await rt3.detectFacets(agent);
const r = await agent.post({ text: rt3.text, facets: rt3.facets, createdAt: new Date().toISOString() });
console.log('\nNew post: ' + r.uri);
// Final stats
const me = await agent.getProfile({ actor: 'agentabrams.bsky.social' });
console.log('\nFinal stats: ' + me.data.followsCount + ' following | ' + me.data.followersCount + ' followers | ' + me.data.postsCount + ' posts');
console.log('Wave 3 complete!');
}
main().catch(e => console.error(e.message));