Skip to content

Instantly share code, notes, and snippets.

@alex7kom
Last active July 15, 2022 16:15
Show Gist options
  • Star 19 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save alex7kom/d764ef2925060c4e7c27 to your computer and use it in GitHub Desktop.
Save alex7kom/d764ef2925060c4e7c27 to your computer and use it in GitHub Desktop.
Steam Donation Bot

Steam Donation Bot

A Steam bot that accepts item donations.

Basically, it accepts any offer that doesn't ask for any items from its inventory.

Feel free to use if you want to accept item donations for your project, or modify it as you see fit.

This bot does not support mobile auth as of yet.

Install and run

  1. Install the latest Node.js.
  2. Click 'Download ZIP' button on the top of this page.
  3. Unpack this ZIP file wherever you like.
  4. Switch to the resulting directory in a command line or a terminal.
  5. Do npm install in the directory.
  6. Edit donation_bot.js to put your account credentials. Leave authCode as is for now.
  7. Run node donation_bot.js. It will 'crash' shortly, and you'll receive an email with Steam Guard code.
  8. Edit donation_bot.js again to put Steam Guard code into authCode, then run node donation_bot.js again. A sentry file will be created in the same directory with the bot. From now on you can run node donation_bot.js to launch the bot.

Note: After sentry file is created, you'll need to wait for 7-15 days due to Steam Guard trade restrictions. Do NOT delete sentry file!

License

MIT

/* START EDITING */
// Put your 64-bit SteamID here so the bot can accept your offers
var admin = '';
var logOnOptions = {
account_name: '',
password: ''
};
var authCode = ''; // Code received by email
/* STOP EDITING */
var fs = require('fs');
var crypto = require('crypto');
var Steam = require('steam');
var SteamWebLogOn = require('steam-weblogon');
var getSteamAPIKey = require('steam-web-api-key');
var SteamTradeOffers = require('steam-tradeoffers');
var sentryFileName = 'sentry'; // steam guard data file name
try {
logOnOptions.sha_sentryfile = getSHA1(fs.readFileSync(sentryFileName));
} catch (e) {
if (authCode !== '') {
logOnOptions.auth_code = authCode;
}
}
// if we've saved a server list, use it
if (fs.existsSync('servers')) {
Steam.servers = JSON.parse(fs.readFileSync('servers'));
}
var steamClient = new Steam.SteamClient();
var steamUser = new Steam.SteamUser(steamClient);
var steamFriends = new Steam.SteamFriends(steamClient);
var steamWebLogOn = new SteamWebLogOn(steamClient, steamUser);
var offers = new SteamTradeOffers();
steamClient.connect();
steamClient.on('connected', function() {
steamUser.logOn(logOnOptions);
});
steamClient.on('logOnResponse', function(logonResp) {
if (logonResp.eresult === Steam.EResult.OK) {
console.log('Logged in!');
steamFriends.setPersonaState(Steam.EPersonaState.Online);
steamWebLogOn.webLogOn(function(sessionID, newCookie) {
getSteamAPIKey({
sessionID: sessionID,
webCookie: newCookie
}, function(err, APIKey) {
offers.setup({
sessionID: sessionID,
webCookie: newCookie,
APIKey: APIKey
});
handleOffers();
});
});
}
});
steamClient.on('servers', function(servers) {
fs.writeFile('servers', JSON.stringify(servers));
});
steamUser.on('updateMachineAuth', function(sentry, callback) {
fs.writeFileSync(sentryFileName, sentry.bytes);
callback({ sha_file: getSHA1(sentry.bytes) });
});
steamUser.on('tradeOffers', function(number) {
if (number > 0) {
handleOffers();
}
});
function handleOffers() {
offers.getOffers({
get_received_offers: 1,
active_only: 1,
time_historical_cutoff: Math.round(Date.now() / 1000),
get_descriptions: 1
}, function(error, body) {
if (error) {
return log(error);
}
if (
body
&& body.response
&& body.response.trade_offers_received
) {
var descriptions = {};
body.response.descriptions = body.response.descriptions || [];
body.response.descriptions.forEach(function (desc) {
descriptions[
desc.appid + ';' + desc.classid + ';' + desc.instanceid
] = desc;
});
body.response.trade_offers_received.forEach(function (offer) {
if (offer.trade_offer_state !== 2) {
return;
}
var offerMessage = 'Got an offer ' + offer.tradeofferid +
' from ' + offer.steamid_other + '\n';
if (offer.items_to_receive) {
offerMessage += 'Items to receive: ' +
offer.items_to_receive.map(function (item) {
var desc = descriptions[
item.appid + ';' + item.classid + ';' + item.instanceid
];
return desc.name + ' (' + desc.type + ')';
}).join(', ') + '\n';
}
if (offer.items_to_give) {
offerMessage += 'Items to give: ' +
offer.items_to_give.map(function (item) {
var desc = descriptions[
item.appid + ';' + item.classid + ';' + item.instanceid
];
return desc.name + ' (' + desc.type + ')';
}).join(', ') + '\n';
}
if (offer.message && offer.message !== '') {
offerMessage += 'Message: ' + offer.message;
}
log(offerMessage);
if (offer.steamid_other === admin || !offer.items_to_give) {
offers.acceptOffer({
tradeOfferId: offer.tradeofferid,
partnerSteamId: offer.steamid_other
}, function (error, result) {
if (error) {
return log(error);
}
log('Offer ' + offer.tradeofferid + ' accepted');
offers.getOffer({
tradeofferid: offer.tradeofferid
}, function (error, result) {
if (error) {
return log(error);
}
if (result
&& result.response
&& result.response.offer
&& result.response.offer.tradeid
) {
offers.getItems({
tradeId: result.response.offer.tradeid
}, function (error, result) {
if (error) {
return log(error);
}
var items = 'Got items:\n' +
result.map(function (item) {
return 'http://steamcommunity.com/profiles/' +
item.owner + '/inventory/#' +
item.appid + '_' + item.contextid + '_' + item.id;
}).join('\n');
log(items);
});
}
});
});
} else {
offers.declineOffer({
tradeOfferId: offer.tradeofferid
}, function (error, result) {
if (error) {
return log(error);
}
log('Offer ' + offer.tradeofferid + ' declined');
});
}
});
}
});
}
function log (message) {
console.log(new Date().toString() + ' - ' + message);
steamFriends.sendMessage(admin, message.toString());
}
function getSHA1 (bytes) {
var shasum = crypto.createHash('sha1');
shasum.end(bytes);
return shasum.read();
}
{
"name": "donation-bot",
"description": "A Steam bot that accepts item donations.",
"version": "0.0.2",
"author": "Alex7Kom",
"dependencies": {
"steam": "*",
"steam-tradeoffers": "*",
"steam-web-api-key": "*",
"steam-weblogon": "*"
}
}
@EmmyLouise
Copy link

EmmyLouise commented Jul 11, 2016

I have almost the exact same error as Mr0Inka but have not received any emails to copy codes across. Any ideas?
Edit: Scrap that. Ran it a second time and it succeeded.

@Govind13100
Copy link

Can anyone explain here what is the use of sentry file??????

And the wait for 7-15 days are mandatory for all devices or only for new devices????

@F1zzzy
Copy link

F1zzzy commented Dec 12, 2017

Ребят кто русские помогите!!!
P.S.
Проблема с другим ботом
Error: Cannot find module '@protobufjs/aspromise'
at Function.Module._resolveFilename (module.js:536:15)
at Function.Module._load (module.js:466:25)
at Module.require (module.js:579:17)
at require (internal/module.js:11:18)
at Object. (C:\Users\Евгений\Desktop\node_modules\protobufjs\src\util\minimal.js:5:18)
at Module._compile (module.js:635:30)
at Object.Module._extensions..js (module.js:646:10)
at Module.load (module.js:554:32)
at tryModuleLoad (module.js:497:12)
at Function.Module._load (module.js:489:3)

@iSize1ce
Copy link

iSize1ce commented Feb 21, 2018

This bot does not support mobile auth as of yet.

Only email? Auth code from mobile app same as email, isn't?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment