Files
TurboTrades/STEAM_BOT_SETUP.md
2026-01-10 04:57:43 +00:00

655 lines
14 KiB
Markdown

# Steam Bot Setup Guide
## 🤖 Overview
The Steam bot system handles trade offers for buying items from users. When a user sells items, instead of immediately crediting funds, the system:
1. ✅ Creates a trade offer via Steam bot
2. ⏳ Tracks trade state (pending, accepted, declined, etc.)
3. 💰 Credits user balance ONLY after trade is accepted
4. 🔄 Handles failures, expirations, and retries
---
## 📋 Prerequisites
### 1. Steam Bot Account
You need a separate Steam account for the bot:
- ✅ Account with Steam Mobile Authenticator enabled
- ✅ Public inventory
- ✅ Valid trade URL
- ✅ API key from https://steamcommunity.com/dev/apikey
- ✅ Not limited (must have spent $5+ on Steam)
- ✅ Trade cooldown period expired (if newly set up)
### 2. Required Packages
Already installed in package.json:
```json
{
"steam-user": "^5.0.0",
"steamcommunity": "^3.47.0",
"steam-tradeoffer-manager": "^2.10.6",
"steam-totp": "^2.1.1"
}
```
Install if needed:
```bash
npm install steam-user steamcommunity steam-tradeoffer-manager steam-totp
```
---
## 🔐 Getting Steam Bot Credentials
### Step 1: Get Shared Secret & Identity Secret
1. **Enable Steam Mobile Authenticator** on bot account
2. Use one of these tools to extract secrets:
- **SDA (Steam Desktop Authenticator)**: https://github.com/Jessecar96/SteamDesktopAuthenticator
- **Android**: Use app like "Steam Guard Mobile Authenticator"
- **Manual extraction**: Follow guides online
3. You'll need:
- `shared_secret` - For generating 2FA codes
- `identity_secret` - For confirming trades
### Step 2: Get Steam API Key
1. Go to: https://steamcommunity.com/dev/apikey
2. Register domain: `turbotrades.com` (or your domain)
3. Copy the API key
### Step 3: Get Bot Trade URL
1. Login to bot account
2. Go to: https://steamcommunity.com/id/me/tradeoffers/privacy
3. Copy the trade URL (looks like: `https://steamcommunity.com/tradeoffer/new/?partner=XXXXX&token=XXXXXXXX`)
---
## ⚙️ Configuration
### Environment Variables
Add to your `.env` file:
```env
# Steam Bot Credentials
STEAM_BOT_USERNAME=your_bot_username
STEAM_BOT_PASSWORD=your_bot_password
STEAM_BOT_SHARED_SECRET=your_shared_secret_here
STEAM_BOT_IDENTITY_SECRET=your_identity_secret_here
# Steam API
STEAM_API_KEY=your_steam_api_key
# Bot Trade URL
STEAM_BOT_TRADE_URL=https://steamcommunity.com/tradeoffer/new/?partner=XXXXX&token=XXXXXXXX
# Optional: Bot Settings
STEAM_BOT_POLL_INTERVAL=30000
STEAM_BOT_AUTO_START=true
```
### Security Notes
- ⚠️ **NEVER commit `.env` to git**
- ⚠️ Keep secrets secure
- ⚠️ Use different account from your personal Steam
- ⚠️ Enable Steam Guard on bot account
- ⚠️ Use strong password
---
## 🚀 Starting the Bot
### Automatic Start (Recommended)
Bot starts automatically when backend launches if `STEAM_BOT_AUTO_START=true`
```bash
npm run dev
```
You'll see:
```
🔐 Logging into Steam...
✅ Steam bot logged in successfully
✅ Steam web session established
🤖 Steam bot ready for trades
```
### Manual Start
```javascript
import { getSteamBot } from './services/steamBot.js';
const bot = getSteamBot();
await bot.login();
console.log('Bot ready:', bot.isOnline());
```
---
## 🔄 How It Works
### User Sells Items Flow
```
1. User selects items on Sell page
2. User clicks "Sell Selected Items"
3. Backend creates Trade record (state: pending)
- Does NOT credit balance yet
4. Steam bot creates trade offer
- Requests items from user
- User sees trade offer in Steam
5. User accepts trade in Steam app
6. Bot receives "trade accepted" event
7. Backend:
- Updates Trade state to "accepted"
- Creates Transaction record
- Credits user balance
- Updates WebSocket
8. User sees balance update in UI
```
### Trade States
| State | Description | User Balance | Can Retry |
|-------|-------------|--------------|-----------|
| **pending** | Trade offer sent, waiting for user | ❌ Not credited | ✅ Yes |
| **accepted** | User accepted, items received | ✅ Credited | ❌ No |
| **declined** | User declined the offer | ❌ Not credited | ⚠️ Maybe |
| **expired** | Trade offer expired (10min timeout) | ❌ Not credited | ✅ Yes |
| **canceled** | Trade was canceled | ❌ Not credited | ✅ Yes |
| **failed** | Technical error occurred | ❌ Not credited | ✅ Yes |
| **escrow** | Trade in Steam escrow | ❌ Not credited | ⏳ Wait |
---
## 📊 Database Schema
### Trade Model
```javascript
{
offerId: String, // Steam trade offer ID
userId: ObjectId, // User who's selling
steamId: String, // User's Steam ID
state: String, // pending, accepted, declined, etc.
items: [{
assetId: String,
name: String,
price: Number,
image: String,
// ... item details
}],
totalValue: Number, // Total price of all items
fee: Number, // Platform fee (e.g., 5%)
feePercentage: Number, // Fee percentage
userReceives: Number, // Amount user gets (after fees)
tradeUrl: String, // User's trade URL
tradeOfferUrl: String, // Link to view offer on Steam
sentAt: Date, // When trade was sent
acceptedAt: Date, // When user accepted
completedAt: Date, // When balance was credited
expiresAt: Date, // When trade expires (10min)
transactionId: ObjectId, // Transaction created after acceptance
sessionId: ObjectId, // User's session
errorMessage: String, // If failed
retryCount: Number, // How many times retried
metadata: Mixed // Additional data
}
```
---
## 🎮 Bot Events
The bot emits events you can listen to:
```javascript
const bot = getSteamBot();
// Bot is ready
bot.on('ready', () => {
console.log('Bot is ready!');
});
// Trade accepted
bot.on('tradeAccepted', async (offer, tradeData) => {
console.log('Trade accepted:', offer.id);
// Credit user balance here
});
// Trade declined
bot.on('tradeDeclined', async (offer, tradeData) => {
console.log('Trade declined:', offer.id);
// Notify user
});
// Trade expired
bot.on('tradeExpired', async (offer, tradeData) => {
console.log('Trade expired:', offer.id);
// Can retry or cancel
});
// Bot error
bot.on('error', (err) => {
console.error('Bot error:', err);
});
// Bot disconnected
bot.on('disconnected', () => {
console.warn('Bot disconnected, will reconnect...');
});
```
---
## 🛠️ API Endpoints
### Create Trade Offer
```http
POST /api/trade/create
Authorization: Bearer <token>
{
"items": [
{
"assetId": "123456789",
"name": "AK-47 | Redline (Field-Tested)",
"price": 12.50,
"image": "https://...",
// ... other item data
}
]
}
```
**Response:**
```json
{
"success": true,
"trade": {
"id": "trade_id",
"offerId": "steam_offer_id",
"state": "pending",
"totalValue": 12.50,
"userReceives": 11.88,
"items": [...],
"tradeOfferUrl": "https://steamcommunity.com/tradeoffer/...",
"expiresAt": "2024-01-10T12:10:00Z"
},
"message": "Trade offer sent! Check your Steam app to accept."
}
```
### Get Trade Status
```http
GET /api/trade/:tradeId
Authorization: Bearer <token>
```
**Response:**
```json
{
"success": true,
"trade": {
"id": "trade_id",
"offerId": "steam_offer_id",
"state": "accepted",
"totalValue": 12.50,
"userReceives": 11.88,
"acceptedAt": "2024-01-10T12:05:00Z",
"timeElapsed": "5m ago"
}
}
```
### Cancel Trade
```http
POST /api/trade/:tradeId/cancel
Authorization: Bearer <token>
```
### Retry Trade
```http
POST /api/trade/:tradeId/retry
Authorization: Bearer <token>
```
---
## 🔧 Bot Management
### Check Bot Status
```javascript
const bot = getSteamBot();
const health = bot.getHealth();
console.log(health);
// {
// isReady: true,
// isLoggedIn: true,
// activeTradesCount: 5,
// username: "bot_username"
// }
```
### Get Active Trades
```javascript
const activeTrades = bot.getActiveTrades();
console.log(`${activeTrades.length} trades active`);
```
### Cancel All Pending Trades
```javascript
const pendingTrades = await Trade.getPendingTrades();
for (const trade of pendingTrades) {
if (trade.isExpired) {
await bot.cancelTradeOffer(trade.offerId);
await trade.markAsExpired();
}
}
```
---
## 🧪 Testing
### Test Bot Login
```bash
node -e "import('./services/steamBot.js').then(async m => {
const bot = m.getSteamBot();
await bot.login();
console.log('Bot logged in:', bot.isOnline());
bot.logout();
process.exit(0);
})"
```
### Test Trade Creation
```javascript
const bot = getSteamBot();
await bot.login();
const result = await bot.createTradeOffer({
tradeUrl: "https://steamcommunity.com/tradeoffer/new/?partner=XXX&token=XXX",
itemsToReceive: [
{ assetid: "123456789", appid: 730, contextid: 2 }
],
message: "Test trade offer"
});
console.log('Trade created:', result);
```
---
## 📈 Monitoring
### Database Queries
```javascript
// Get all pending trades
const pending = await Trade.find({ state: 'pending' });
// Get expired trades
const expired = await Trade.getExpiredTrades();
// Get trade stats
const stats = await Trade.getStats();
console.log(`
Total trades: ${stats.total}
Accepted: ${stats.accepted}
Pending: ${stats.pending}
Declined: ${stats.declined}
`);
// Get user's trades
const userTrades = await Trade.getUserTrades(userId);
```
### Admin Panel Integration
Add to admin panel:
- ✅ View pending trades
- ✅ Cancel stale trades
- ✅ Retry failed trades
- ✅ View trade statistics
- ✅ Bot health status
---
## 🐛 Troubleshooting
### Bot Won't Login
**Check:**
- ✅ Username and password correct
- ✅ Shared secret is valid
- ✅ Steam account not limited
- ✅ No active VAC ban
- ✅ No trade cooldown
**Solution:**
```bash
# Test credentials
node -e "console.log('Username:', process.env.STEAM_BOT_USERNAME)"
node -e "console.log('Has password:', !!process.env.STEAM_BOT_PASSWORD)"
node -e "console.log('Has shared secret:', !!process.env.STEAM_BOT_SHARED_SECRET)"
```
### Trades Not Confirming
**Check:**
- ✅ Identity secret is correct
- ✅ Mobile authenticator is active
- ✅ Bot has trade URL
**Solution:**
- Manually confirm in Steam app first time
- Check if identity secret is correct
- Regenerate secrets if needed
### Trades Stuck in Pending
**Reasons:**
- User hasn't accepted yet
- Trade expired (10 minutes)
- Steam API issues
- User's inventory is private
**Solution:**
```javascript
// Cancel expired trades
const expired = await Trade.find({
state: 'pending',
expiresAt: { $lt: new Date() }
});
for (const trade of expired) {
await bot.cancelTradeOffer(trade.offerId);
await trade.markAsExpired();
}
```
### Bot Keeps Disconnecting
**Check:**
- ✅ Network connection stable
- ✅ Steam not under maintenance
- ✅ No rate limiting
**Solution:**
- Implement auto-reconnect (already built-in)
- Use connection pooling
- Monitor logs for error patterns
---
## 🔒 Security Best Practices
### 1. Secure Credentials
- ✅ Never hardcode credentials
- ✅ Use environment variables
- ✅ Keep .env out of git
- ✅ Rotate secrets regularly
### 2. Trade Validation
- ✅ Verify user owns items before creating trade
- ✅ Check item values match database
- ✅ Validate trade URLs
- ✅ Prevent duplicate trades
### 3. Rate Limiting
- ✅ Limit trades per user per hour
- ✅ Limit total trades per minute
- ✅ Queue trades during high load
### 4. Monitoring
- ✅ Log all trade events
- ✅ Alert on failed trades
- ✅ Track bot uptime
- ✅ Monitor Steam API status
---
## 📊 Performance Optimization
### Trade Queue System
For high volume, implement trade queue:
```javascript
// Redis-based queue
import Bull from 'bull';
const tradeQueue = new Bull('trades', {
redis: { host: 'localhost', port: 6379 }
});
tradeQueue.process(async (job) => {
const { userId, items } = job.data;
return await createTradeOffer(userId, items);
});
// Add to queue
await tradeQueue.add({ userId, items }, {
attempts: 3,
backoff: {
type: 'exponential',
delay: 2000
}
});
```
### Retry Strategy
```javascript
async function createTradeWithRetry(data, maxRetries = 3) {
let lastError;
for (let i = 0; i < maxRetries; i++) {
try {
return await bot.createTradeOffer(data);
} catch (error) {
lastError = error;
await sleep(Math.pow(2, i) * 1000); // Exponential backoff
}
}
throw lastError;
}
```
---
## 🎯 Next Steps
### Phase 1: Basic Setup (You are here)
- [x] Install packages
- [x] Create bot service
- [x] Create Trade model
- [ ] Configure environment variables
- [ ] Test bot login
### Phase 2: Integration
- [ ] Update sell endpoint to create trades
- [ ] Add trade event handlers
- [ ] Credit balance on acceptance
- [ ] Add trade status polling
### Phase 3: Frontend
- [ ] Show trade status in UI
- [ ] Add "View Trade" button
- [ ] Show pending trades list
- [ ] Add trade notifications
### Phase 4: Admin Tools
- [ ] Bot health dashboard
- [ ] Trade management panel
- [ ] Retry/cancel controls
- [ ] Statistics and reports
### Phase 5: Advanced
- [ ] Trade queue system
- [ ] Multiple bot support
- [ ] Automatic retries
- [ ] Fraud detection
---
## 📚 Additional Resources
- **Steam Web API**: https://developer.valvesoftware.com/wiki/Steam_Web_API
- **Trade Offer Manager**: https://github.com/DoctorMcKay/node-steam-tradeoffer-manager
- **Steam User**: https://github.com/DoctorMcKay/node-steam-user
- **Steam TOTP**: https://github.com/DoctorMcKay/node-steam-totp
---
## ✅ Configuration Checklist
Before going live:
- [ ] Bot account created and funded ($5+ spent)
- [ ] Steam Mobile Authenticator enabled
- [ ] Shared secret and identity secret extracted
- [ ] API key obtained from Steam
- [ ] Environment variables configured
- [ ] Bot successfully logs in
- [ ] Test trade offer sent and accepted
- [ ] Trade events properly handled
- [ ] Balance credits on acceptance
- [ ] Error handling tested
- [ ] Monitoring set up
- [ ] Backup credentials stored securely
---
**Status**: Implementation Ready
**Next**: Configure bot credentials and test login
**Priority**: High - Required for production sell functionality