Create bot.js
This commit is contained in:
commit
5693cdffe6
230
bot.js
Normal file
230
bot.js
Normal file
@ -0,0 +1,230 @@
|
||||
const http = require('http');
|
||||
const https = require('https');
|
||||
const querystring = require('querystring');
|
||||
|
||||
// Configuration
|
||||
const GATHER_SPACE_ID = 'dashore-enterprises-db198865-9dd4-4406-8d0c-0bb71896f09e';
|
||||
const GATHER_API_KEY = 'gtr_L8dR5b9x8im9itQGYTc194Lia9KSTwTSCHAhN84av1s';
|
||||
const CLAUDE_API_KEY = process.env.CLAUDE_API_KEY || 'your-anthropic-key-here';
|
||||
const BOT_USER_ID = 'claude-bot-agent'; // This will be the bot's user ID
|
||||
const BOT_NAME = 'Claude Agent';
|
||||
|
||||
// Store bot position and state
|
||||
let botState = {
|
||||
position: { x: 10, y: 10 }, // Starting position in the space
|
||||
isActive: true,
|
||||
lastActivity: Date.now()
|
||||
};
|
||||
|
||||
// Function to call Claude API for AI responses
|
||||
async function askClaude(question) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const data = JSON.stringify({
|
||||
model: 'claude-3-5-sonnet-20241022',
|
||||
max_tokens: 300,
|
||||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: question
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
const options = {
|
||||
hostname: 'api.anthropic.com',
|
||||
port: 443,
|
||||
path: '/v1/messages',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'x-api-key': CLAUDE_API_KEY,
|
||||
'anthropic-version': '2023-06-01'
|
||||
}
|
||||
};
|
||||
|
||||
const req = https.request(options, (res) => {
|
||||
let body = '';
|
||||
res.on('data', chunk => body += chunk);
|
||||
res.on('end', () => {
|
||||
try {
|
||||
const parsed = JSON.parse(body);
|
||||
if (parsed.content && parsed.content[0]) {
|
||||
resolve(parsed.content[0].text);
|
||||
} else {
|
||||
reject(new Error('Invalid response from Claude API'));
|
||||
}
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', reject);
|
||||
req.write(data);
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
// Function to send message to chat in Gather
|
||||
async function sendMessage(text) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const data = JSON.stringify({
|
||||
message: text,
|
||||
userId: BOT_USER_ID
|
||||
});
|
||||
|
||||
const options = {
|
||||
hostname: 'gather.town',
|
||||
port: 443,
|
||||
path: `/api/v1/spaces/${GATHER_SPACE_ID}/chat`,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${GATHER_API_KEY}`
|
||||
}
|
||||
};
|
||||
|
||||
const req = https.request(options, (res) => {
|
||||
let body = '';
|
||||
res.on('data', chunk => body += chunk);
|
||||
res.on('end', () => {
|
||||
try {
|
||||
const parsed = JSON.parse(body);
|
||||
resolve(parsed);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', reject);
|
||||
req.write(data);
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
// Function to move bot to a location
|
||||
async function moveBotTo(x, y) {
|
||||
botState.position = { x, y };
|
||||
return new Promise((resolve, reject) => {
|
||||
const data = JSON.stringify({
|
||||
x: x,
|
||||
y: y,
|
||||
userId: BOT_USER_ID
|
||||
});
|
||||
|
||||
const options = {
|
||||
hostname: 'gather.town',
|
||||
port: 443,
|
||||
path: `/api/v1/spaces/${GATHER_SPACE_ID}/users/${BOT_USER_ID}/position`,
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${GATHER_API_KEY}`
|
||||
}
|
||||
};
|
||||
|
||||
const req = https.request(options, (res) => {
|
||||
let body = '';
|
||||
res.on('data', chunk => body += chunk);
|
||||
res.on('end', () => {
|
||||
try {
|
||||
const parsed = JSON.parse(body);
|
||||
resolve(parsed);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', reject);
|
||||
req.write(data);
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
// Listen for chat messages
|
||||
async function listenForMessages() {
|
||||
// This would use Gather's webhook system in a real implementation
|
||||
// For now, we'll use polling to check for new messages
|
||||
|
||||
const checkMessages = async () => {
|
||||
try {
|
||||
// Simulated message polling - in production use webhooks
|
||||
console.log('Bot is listening for messages...');
|
||||
|
||||
// Keep the bot active
|
||||
botState.lastActivity = Date.now();
|
||||
} catch (err) {
|
||||
console.error('Error listening for messages:', err);
|
||||
}
|
||||
|
||||
setTimeout(checkMessages, 5000);
|
||||
};
|
||||
|
||||
checkMessages();
|
||||
}
|
||||
|
||||
// Process incoming command
|
||||
async function processCommand(command) {
|
||||
console.log(`Processing command: ${command}`);
|
||||
|
||||
let response;
|
||||
|
||||
if (command.toLowerCase().includes('@claude')) {
|
||||
// Extract the actual question
|
||||
const question = command.replace(/@claude\s*/i, '').trim();
|
||||
|
||||
if (question) {
|
||||
try {
|
||||
console.log(`Asking Claude: ${question}`);
|
||||
response = await askClaude(question);
|
||||
await sendMessage(`Claude: ${response}`);
|
||||
} catch (err) {
|
||||
console.error('Error calling Claude:', err);
|
||||
await sendMessage(`Sorry, I encountered an error: ${err.message}`);
|
||||
}
|
||||
}
|
||||
} else if (command.toLowerCase() === 'come here') {
|
||||
await moveBotTo(15, 15);
|
||||
await sendMessage('I moved to a new location!');
|
||||
} else if (command.toLowerCase() === 'hello') {
|
||||
await sendMessage(`Hello! I'm ${BOT_NAME}, your AI assistant. Ask me anything by typing @claude followed by your question.`);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the bot
|
||||
async function initializeBot() {
|
||||
console.log(`\n🤖 Starting ${BOT_NAME}...`);
|
||||
console.log(`Space ID: ${GATHER_SPACE_ID}`);
|
||||
console.log(`Initial Position: (${botState.position.x}, ${botState.position.y})`);
|
||||
|
||||
// Move bot to starting position
|
||||
try {
|
||||
await moveBotTo(botState.position.x, botState.position.y);
|
||||
console.log('✅ Bot positioned successfully');
|
||||
} catch (err) {
|
||||
console.error('❌ Error positioning bot:', err);
|
||||
}
|
||||
|
||||
// Start listening for messages
|
||||
await listenForMessages();
|
||||
|
||||
console.log('✅ Bot initialized and listening for commands');
|
||||
console.log('Commands:');
|
||||
console.log(' - @claude [question] - Ask Claude anything');
|
||||
console.log(' - come here - Move bot to your location');
|
||||
console.log(' - hello - Say hello to the bot');
|
||||
}
|
||||
|
||||
// Handle graceful shutdown
|
||||
process.on('SIGINT', () => {
|
||||
console.log('\n👋 Shutting down bot...');
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
// Start the bot
|
||||
initializeBot().catch(err => {
|
||||
console.error('Fatal error:', err);
|
||||
process.exit(1);
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user