├── .gitignore ├── LICENSE ├── README.md ├── bot.js ├── config.js ├── install.bat ├── package.json └── start.bat /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 shanetechwiz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # node-steamcardbot 2 | Steam Trade Bot - CSGO Card Sets for Keys 3 | 4 | # CAUTION 5 | There are users that have cloned this repo and are inserting backdoors into the code. 6 | Please have a developer review the code if you did not get the code from it's original source [shanetechwiz/node-steamcardbot](https://github.com/shanetechwiz/node-steamcardbot) 7 | 8 | # To install 9 | 10 | npm install 11 | -------------------------------------------------------------------------------- /bot.js: -------------------------------------------------------------------------------- 1 | var Steam = require('steam'); 2 | var SteamUser = require('steam-user'); 3 | var TradeOfferManager = require('steam-tradeoffer-manager'); 4 | var SteamTotp = require('steam-totp'); 5 | var Steamcommunity = require('steamcommunity'); 6 | var SteamWebLogOn = require('steam-weblogon'); 7 | 8 | var util = require('util'); 9 | var UInt64 = require('cuint').UINT64; 10 | 11 | var client = new SteamUser(); 12 | 13 | var steamClient = new Steam.SteamClient(); 14 | var steamUser = new Steam.SteamUser(steamClient); 15 | var steamFriends = new Steam.SteamFriends(steamClient); 16 | var steamWebLogOn = new SteamWebLogOn(steamClient, steamUser); 17 | 18 | var community = new Steamcommunity(); 19 | var manager = new TradeOfferManager({ 20 | "steam": client, 21 | "domain": "example.com", 22 | "language": "en" 23 | }); 24 | 25 | var config = require('./config'); 26 | 27 | var code = SteamTotp.generateAuthCode(config.bot.shared_secret); 28 | 29 | var logOnOptions = { 30 | account_name: config.bot.username, 31 | password: config.bot.password, 32 | two_factor_code: code 33 | } 34 | 35 | function log(message) 36 | { 37 | console.log(new Date().toString() + ' - ' + message); 38 | steamFriends.sendMessage(config.admin, message.toString()); 39 | } 40 | 41 | function steamIdObjectToSteamId64(steamIdObject) { 42 | return new UInt64(steamIdObject.accountid, (steamIdObject.universe << 24) | (steamIdObject.type << 20) | (steamIdObject.instance)).toString(); 43 | } 44 | 45 | function Login(logOnOptions) 46 | { 47 | steamClient.connect(); 48 | 49 | steamClient.on('connected', function() { 50 | log('Connected...'); 51 | steamUser.logOn(logOnOptions); 52 | }); 53 | 54 | steamClient.on('logOnResponse', function(logonResp) { 55 | if (logonResp.eresult === Steam.EResult.OK) { 56 | log('Login Successful!'); 57 | steamFriends.setPersonaState(Steam.EPersonaState.Online); 58 | steamUser.gamesPlayed({ 59 | games_played: [{ 60 | game_id: '15444025664222527488', 61 | game_extra_info: '1 CS:GO key -> ' + config.sets_per_key + ' sets' 62 | }] 63 | }); 64 | steamWebLogOn.webLogOn(function(sessionID, cookies) { 65 | manager.setCookies(cookies, function(err) { 66 | if(err) { 67 | log(err); 68 | process.exit(1); 69 | return; 70 | } 71 | }); 72 | 73 | community.setCookies(cookies); 74 | community.startConfirmationChecker(30000, config.bot.identity_secret); 75 | 76 | if(community.chatState == 0) { 77 | community.chatLogon(); 78 | } 79 | 80 | community.on('chatMessage', function(sender, text) { 81 | handleChatMessages(sender, text); 82 | }); 83 | }); 84 | } 85 | else { log(logonResp.eresult); } 86 | }); 87 | } 88 | 89 | function handleChatMessages(steamID, message) { 90 | 91 | steamID = steamIdObjectToSteamId64(steamID); 92 | 93 | message = message.trim(); 94 | 95 | var friendList = steamFriends.friends; 96 | 97 | if(friendList[steamID] && friendList[steamID] == Steam.EFriendRelationship.Friend) { 98 | if(message.indexOf('!help') > -1) { 99 | steamFriends.sendMessage(steamID, config.message.help.toString()); 100 | } 101 | else if(message.indexOf('!buy') > -1) { 102 | 103 | numberOfKeys = message.replace ( /[^\d.]/g, '' ); 104 | 105 | if(isNaN(numberOfKeys) == true) { steamFriends.sendMessage(steamID, config.message.invalid_number_of_keys.toString()); } 106 | else { 107 | if(numberOfKeys > config.max_number_of_keys) { steamFriends.sendMessage(steamID, config.message.excess_keys.toString()); } 108 | else { 109 | sellSets(steamID, Math.round(numberOfKeys)); 110 | steamFriends.sendMessage(steamID, config.message.buy.toString()); 111 | } 112 | } 113 | } 114 | else { steamFriends.sendMessage(steamID, config.message.invalid_command.toString()); } 115 | } 116 | else { 117 | community.chatMessage(steamID, config.message.not_in_friendlist.toString()); 118 | } 119 | } 120 | 121 | var getSpecificItemFromInventoryByTagName = function(inventory, tagName) { 122 | var inventoryItems = []; 123 | 124 | inventory.forEach(function(inventoryItem) { 125 | if(inventoryItem.tags) { 126 | inventoryItem.tags.forEach(function(tag) { 127 | if(tag.name && tag.name == tagName) { 128 | inventoryItems.push(inventoryItem); 129 | } 130 | }); 131 | } 132 | }); 133 | return inventoryItems; 134 | } 135 | 136 | var getSpecificNumberOfItemsFromInventory = function(itemInventory, numberOfItems) { 137 | var items = []; 138 | 139 | for(var i = 0; i < numberOfItems; i++) { 140 | if(i < itemInventory.length) { 141 | var item = itemInventory[i]; 142 | items.push({ assetid: item.assetid, appid: item.appid, contextid: item.contextid, amount: 1}); 143 | } 144 | } 145 | 146 | return items; 147 | } 148 | 149 | var getSmallerNumber = function(first, second) { 150 | return Math.min(first, second); 151 | } 152 | 153 | 154 | function sellSets(steamID, numberOfKeys) { 155 | var theirItems = []; 156 | var myItems = []; 157 | 158 | manager.getUserInventoryContents(steamID, config.app_id.csgo, config.context_id.keys, true, function(err, userInventory, userCurrencies) { 159 | 160 | userInventory = getSpecificItemFromInventoryByTagName(userInventory, 'Key'); 161 | 162 | theirItems = getSpecificNumberOfItemsFromInventory(userInventory, numberOfKeys); 163 | 164 | if(theirItems.length > 0) { 165 | manager.getInventoryContents(config.app_id.steam, config.context_id.cards, true, function(err, inventory, currencies) { 166 | 167 | numberOfKeys = getSmallerNumber(numberOfKeys, theirItems.length); 168 | inventory = getSpecificItemFromInventoryByTagName(inventory, 'Trading Card'); 169 | 170 | var numberOfCardSets = numberOfKeys * config.sets_per_key; 171 | 172 | myItems = getSpecificNumberOfItemsFromInventory(inventory, numberOfCardSets); 173 | 174 | if(myItems.length > 0) { 175 | var offer = manager.createOffer(steamID); 176 | 177 | offer.addMyItems(myItems); 178 | offer.addTheirItems(theirItems); 179 | 180 | offer.setMessage(config.message.tradeoffer.toString()); 181 | 182 | offer.send(function(err, status) { 183 | if(err) { log('Sale of cards failed: ' + err); return; } 184 | 185 | if(status == 'pending') { community.checkConfirmations(); log('checkConfirmations executed'); } 186 | 187 | steamFriends.sendMessage(steamID, config.message.cards_sold.toString()); 188 | }); 189 | } 190 | }); 191 | } 192 | 193 | }); 194 | } 195 | 196 | Login(logOnOptions); 197 | 198 | steamFriends.on('friend', function(steamID, relationship) { 199 | if(relationship == Steam.EFriendRelationship.RequestRecipient) { 200 | steamFriends.addFriend(steamID); 201 | steamFriends.sendMessage(steamID, config.message.welcome.toString()); 202 | } 203 | }); 204 | -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 3 | admin: '76561198103757293', //your main steam64 id (get it from steamid.xyz) 4 | 5 | bot: { 6 | name: '', //username that bot will use once running 7 | username: '', //bot username (account login) 8 | password: '', // login password 9 | identity_secret: '', // identity secret (from SDA) 10 | shared_secret: '', // shared secret (from SDA) 11 | steam_id: '', // bot user steam id (get it from steamid.xyz) 12 | apikey: '', // steam api key, you can login to bot profile and get it from: http://steamcommunity.com/dev/apikey 13 | tradelink: '' //bot user trade link (i think) 14 | }, 15 | 16 | message: { 17 | welcome: '', //message to be sent once user adds you 18 | help: '', //message to be sent when user sends !help 19 | buy: '', // message to be sent when someone buys from bot (when trade is sent to user but not accepted yet) 20 | tradeoffer: '', // message to be included in trade offer 21 | cards_sold: '', // when cards are sold (trade completed) 22 | invalid_command: '', // if command does not exsist 23 | invalid_number_of_keys: '', // when number of keys is not a number (NaN) 24 | excess_keys: '', // when user want to buy for more keys than allowed in config (trade fails) 25 | not_in_friendlist: '' // if they are not on your friend list 26 | }, 27 | 28 | max_number_of_keys: 15, //max number of keys to be included in offer 29 | 30 | sets_per_key: 16, //sets that will be sent per key (1 csgo key:16 card sets) 31 | 32 | app_id: { 33 | csgo: 730, //steam id for CS:GO 34 | steam: 753 // steam id for steam app 35 | }, 36 | 37 | context_id: { 38 | keys: 2, //inventory context for csgo 39 | cards: 6 //inventory context for steam 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /install.bat: -------------------------------------------------------------------------------- 1 | npm install 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-steamcardbot", 3 | "version": "1.0.0", 4 | "description": "TradeBot - Cards for Keys", 5 | "main": "bot.js", 6 | "dependencies": { 7 | "cuint": "^0.2.2", 8 | "steam": "^1.4.0", 9 | "steam-totp": "^1.4.0", 10 | "steam-tradeoffer-manager": "^2.7.1", 11 | "steam-user": "^3.19.1", 12 | "steam-weblogon": "^0.0.5", 13 | "steamcommunity": "^3.30.7", 14 | "steamid": "^1.1.0", 15 | "util": "^0.10.3" 16 | }, 17 | "devDependencies": {}, 18 | "scripts": { 19 | "test": "echo \"Error: no test specified\" && exit 1" 20 | }, 21 | "author": "Oshane Spencer", 22 | "license": "ISC" 23 | } 24 | -------------------------------------------------------------------------------- /start.bat: -------------------------------------------------------------------------------- 1 | node bot.js 2 | --------------------------------------------------------------------------------