Home

Awesome

z# steam-trade V0.3.3

PLEASE IF SOMETHING DOES NOT WORK PROPERLY MAKE A GITHUB ISSUE

This gem simplifes/allows sending steam trade offers programmatically.

this gem is primarly for trading cards, tho can be used to CS:GO and other games inventories

Changelog

0.3.3:
- hotfix login without api-key
0.3.2:
- added send_trade_allow_request() (mobile confirmation) and confirm_all() (mobile confirmation)
0.3.1:
- added cottage() , vote_2018() and sell_items()

0.3.0:
- hotfix for cookie login

0.2.9:
- hotfix for cookie login (remember me)

0.2.8:
- fixed cookie login

0.2.7:
- added salien_card() to collect steam Salien game Trading Cards

0.2.6:
- hotfix

0.2.5:
- added finish_queue() to collect Steam Sale Trading Cards
- hotfix

0.2.4:
- hotfix

0.2.3:
- hotfix

0.2.2:
- fixed issues with ruby 2.4+
- added class methods for fa(), normal_get_inventory(), raw_get_inventory, sets_count()

0.2.1:
- many many bugs fixed

0.2.0:
- hotfix

0.1.9:
- Handler.new() now accepts a hash contains login cookies.
- get_auth_cookies() returns cookies to use for the next login

0.1.8:
- hotfix

0.1.7:
- hotfix

0.1.6:
- hotfix

0.1.5:
- added mobile_login() which allows you to send and receive steam messages
- added oauth_login() uses oauth token and steamMachine cookie to login in ( you get those from mobile_login())

0.1.4:
- added Social commands : send friend request, accept friend request, remove friend, send message, get messages
- added function to update badges blueprint (useful when there is no gem update)

0.1.3:
- decreased cooldown between requests from 2 seconds to 1 second.
- added a 0.6 second wait before attempting to confirm a trade offer (mobile).
- added a 3 times retry to get an inventory chunk before raising an error.
- exception handling for sets_count, now no longer raises an error if the target inventory contains trading cards which are not specified in the bluepirnt.

0.1.2:
- normal_get_inventory() and raw_get_inventory() now uses Mechanize instead of open-uri.
- Handler.new() and fa() now accepts a time difference parameter to adjust your 2FA codes.
- sets_count() now writes the txt file faster.
- Mechanize session associated with the account now has a 2 second cooldown before each request to avoid spamming steam servers and resulting in a ban.

Table of content

Installation

in your commandline :

gem install steam-trade

Usage

First you need to require the gem:

require 'steam-trade'

Logging-in

Handler.new()

Handler.new(username, password,shared_secret,time_difference,remember_me)

then you need to login and optionally set your shared_secret and identity_secret:

require 'steam-trade'

account = Handler.new('username','password','shared_secret') # share secret is optional
account = Handler.new('username','password',50) #works
account = Handler.new('username','password','shared_secret',50)
account = Handler.new('username','password',50,'shared_secret') # this will not work

account = Handler.new('username','password','shared_secret',20,true) # works
account = Handler.new('username','password','shared_secret',true) #works
account = Handler.new('username','password',20,true) #works
account = Handler.new('username','password',true) #works

account = Handler.new('username','password','shared_secret',true,20) # will not work
##########
account = Handler.new('username') #this of course counts as non logged in

keep in mind you can initialize a Handler without params however the commands you will be able to use will be limited

require 'steam-trade'

account = Handler.new()
puts account.fa('v3dWNq2Ncutc7RelwRVXswT8CJX=v3dWNq2Ncutc7WelwRVXswT8CJk=') => random code

Handler.new(cookies_hash,shared_secret,time_difference,remember_me)
require 'steam-trade'
account = Handler.new(JSON.parse(File.read('./creds.json'))) # creds.json is created by get_auth_cookies()

account = Handler.new(JSON.parse(File.read('./creds.json')), 'shared_secret', 50)

get_auth_cookies()

require 'steam-trade'
account = Handler.new('username','password','shared_secret',true)
cookies = h.get_auth_cookies

File.open('creds.json', 'w') {|f| f.puts cookies.to_json}

next time :

require 'steam-trade'
account = Handler.new(JSON.parse(File.read('./creds.json')))

mobile_info(identity_secret)

require 'steam-trade'

account = Handler.new('username','password','shared_secret')
account.mobile_info('identity_secret')

Getting someone's inventory

you might want to read this guide

normal_get_inventory('steamid','inventoryappid')

require 'steam-trade'
inventory = Handler.normal_get_inventory("nomg3r")


logged = Handler.new('username','password','shared_secret')
logged.mobile_info('identity_secret')
# while logged in
my_inventory = logged.normal_get_inventory() #will get your normal inventory(753) if you are logged in else raise an exception
my_inventory = logged.normal_get_inventory('730') # will get your CS:GO inventory if you are logged in else raise an exeception


#whatever can be done while **not** logged in, can be of course used while logged in
#while not logged in
nonlogged = Handler.new()
my_inventory = nonlogged.normal_get_inventory() #will raise an exception
my_inventory = nonlogged.normal_get_inventory('730') #will raise an exception

#whenever
partner_inventory = nonlogged.normal_get_inventory('76561198044170935') #using steamid
partner_inventory = nonlogged.normal_get_inventory('https://steamcommunity.com/tradeoffer/new/?partner=410155236&token=H-yK-GFt') #using trade link
partner_inventory = nonlogged.normal_get_inventory('CardExchange') #using profile id


partner_inventory = nonlogged.normal_get_inventory('76561198044170935',730) #will get that steamid CS:GO inventory
partner_inventory = nonlogged.normal_get_inventory('https://steamcommunity.com/tradeoffer/new/?partner=410155236&token=H-yK-GFt', '730') #will get that trade link owner's CS:GO inventory
partner_inventory = nonlogged.normal_get_inventory('CardExchange',730) # will get CardExchange's CS:GO inventory


the returned items from normal_get_inventory() are in the form of an array example : [item1,item2,item3...itemN].

each item is a hash which contains information about the item in the form of {"appid"=>'xxx',"contextid"=>'xxx',"assetid" => 'xxx',"classid"=> 'xxx',......"name"=> 'xxxx',"market_fee_app" => 'xxx',....}.

market_fee_app key gives you the appid of the game's app (for trading cards), for other items technically inventoryappid is the games appid.

name key gives you the item name.

raw_get_inventory(target,inventoryappid,trimming)

IMPORTANT: this command efficiency is better than normal_get_inventory, therefore i recommend using this one.

This command will return a hash nearly identitical to the one received from steam the hash will have 2 keys assets and descriptions:

require 'steam-trade'
inv = Handler.raw_get_inventory("nomg3r")


logged = Handler.new('username','password','shared_secret')
inv = logged.raw_get_inventory() #works
inv = logged.raw_get_inventory(false) # returns non trimmed
inv = logged.raw_get_inventory(440) #works
inv = logged.raw_get_inventory(76561198044170935,false) #works
inv = logged.raw_get_inventory(76561198044170935,440) # works

print inv['assets'] #will print all the assets
print inv['descriptions'] #will print all the descriptions

### how to accurately use this

class_instance = {}
## map all the items
inv['descriptions'].each { |desc|
  identifier = desc['classid'] + '_' + desc['instanceid']
  class_instance[identifier] = desc
}

## identify your items

inv['assets'].each { |asset|
  identifier = asset['classid'] + '_' + asset['instanceid']
  puts class_instance[identifier] this will output the item's description
}

set_inventory_cache()

set_inventory_cache() is:

require 'steam-trade'

logged = Handler.new('username','password','shared_secret')
logged.mobile_info('identity_secret')
logged.set_inventory_cache(150)


partner_inventory = loggedlogged.normal_get_inventory('CardExchange') #this will save CardExchange's inventory to a local file and return the inventory

partner_inventory = loggedlogged.normal_get_inventory('CardExchange') # this will load the locally saved file


IMPORTANT: normal_get_inventory() will load the whole target inventory, for each 5k of items, you are adding ~40MB to your memory and of course will affect performance of the code and the computer

Sending a trade offer

send_offer(myarray,theirarray,trade_offer_link,message)

MUST be logged in to use this command then you can send your offer

require 'steam-trade'

account = Handler.new('username','password','shared_secret')
account.mobile_info('identity_secret')

me = account.normal_get_inventory()
his = account.normal_get_inventory("nomg3r")

myarray = [me[5] , me[20] , me[60]].compact!
theirarray = [his[1], his[20], his[30]].compact!

# if you are friends
resp = account.send_offer(myarray,theirarray,"nomg3r",message)
#or (as friends)
account.send_offer(myarray,theirarray,'76561198370420964',message)

# whenever
account.send_offer(myarray,theirarray,"https://steamcommunity.com/tradeoffer/new/?partner=410155236&token=H-yK-GFt",message)


send_trade_allow_request(tradeofferid)

require 'steam-trade'

account = Handler.new('username','password','shared_secret')
account.mobile_info('identity_secret')

me = account.normal_get_inventory()
his = account.normal_get_inventory("nomg3r")

myarray = [me[5] , me[20] , me[60]].compact!
theirarray = [his[1], his[20], his[30]].compact!

resp = account.send_offer(myarray,theirarray,"nomg3r",message)

account.send_trade_allow_request(resp['tradeofferid'])

confirm_all()

require 'steam-trade'

account = Handler.new('username','password','shared_secret')
account.mobile_info('identity_secret')

account.confirm_all

Handling Trade Offers

you might want to read Steam Trading API

ALL OF THE COMMANDS BELOW REQUIRE AN API_KEY

set_api_key(API_KEY)

NOTE:If you are using a logged in Handler there is no need to set the API_KEY.

require 'steam-trade'
acc = Handler.new()
trade_offers = acc.get_trade_offers() # will raise an exception
acc.set_api_key('mykey')
trade_offers = acc.get_trade_offers() # after setting an API_KEY this will succeed

get_trade_offers(time)

require 'steam-trade'
logged = Handler.new('username','password','shared_secret')
logged.mobile_info('identity_secret')

time = '' # this is the initial check for offers so we want them all
polling = Thread.new(logged) { |logged|
  loop do
    offers = logged.get_trade_offers(time)
    time = Time.new.to_i # we save the time of the last check
    next if offers['trade_offers_received'] == nil # do nothing, if there is no trades
    puts offers['trade_offers_received'] # puts the trades
    sleep(15) # make sure not to spam steam's server or they will block list your IP for a period of time therefore you can't make requests
  end
}

get_trade_offer(tradeofferid)

gets more information about a specific trade offer

have no example how to actually use this cause get_trade_offers(time) is probably better

accept_trade_offer(tradeofferid)

require 'steam-trade'
logged = Handler.new('username','password','shared_secret')
logged.mobile_info('identity_secret')

time = '' # this is the initial check for offers so we want them all
polling = Thread.new(logged) { |logged|
  loop do
    offers = logged.get_trade_offers(time)
    time = Time.new.to_i # we save the time of the last check
    next if offers['trade_offers_received'] == nil # do nothing, if there is no trades
    offers['trade_offers_received'].each { |trade|
      if trade['accountid_other'].to_i == 83905207 ## this will accept all trade received from 83905207 (Steam32 ID)
        logged.accept_trade_offer(trade['tradeofferid']) # to accept the trade
      end
    }
    sleep(15) # make sure not to spam steam's server or they will block list your IP for a period of time therefore you can't make requests
  end
}

decline_trade_offer(tradeofferid)

this declines a trade offer you RECEIVED

require 'steam-trade'
logged = Handler.new('username','password','shared_secret')
logged.mobile_info('identity_secret')

time = '' # this is the initial check for offers so we want them all
polling = Thread.new(logged) { |logged|
  loop do
    offers = logged.get_trade_offers(time)
    time = Time.new.to_i # we save the time of the last check
    next if offers['trade_offers_received'] == nil # do nothing, if there is no trades
    offers['trade_offers_received'].each { |trade| # we need to check received offers to use 'decline'
      if trade['accountid_other'].to_i != 83905207 ## notice the '!='
        logged.decline_trade_offer(trade['tradeofferid']) # decline the trade
      end
    }
    sleep(15) # make sure not to spam steam's server or they will block list your IP for a period of time therefore you can't make requests
  end
}

cancel_trade_offer(tradeofferid)

this cancels a trade offer you SENT

require 'steam-trade'
logged = Handler.new('username','password','shared_secret')
logged.mobile_info('identity_secret')

time = '' # this is the initial check for offers so we want them all
polling = Thread.new(logged) { |logged|
  loop do
    offers = logged.get_trade_offers(time)
    time = Time.new.to_i # we save the time of the last check
    next if offers['trade_offers_sent'] == nil # do nothing, if there is no trades
    offers['trade_offers_sent'].each { |trade| # we need to check sentoffers to use 'cancel'
      if trade['accountid_other'].to_i != 83905207 ## notice the '!='
        logged.cancel_trade_offer(trade['tradeofferid']) # cancel the trade
      end
    }
    sleep(15) # make sure not to spam steam's server or they will block list your IP for a period of time therefore you can't make requests
  end
}

Counting badges owned

sets_count(target,non_marketable)

this command does not count foil badges (only normal trading cards)

require 'steam-trade'
data = Handler.sets_count("CardExchange")


logged = Handler.new('username','password','shared_secret')
logged.mobile_info('identity_secret')
#with login
logged = account.sets_count()
logged = account.sets_count(false)
hash = account.sets_count('CardExchange',false)
hash = account.sets_count(76561198370420964)
hash = account.sets_count('https://steamcommunity.com/tradeoffer/new/?partner=410155236&token=H-yK-GFt',false)


#without login
nonlogged = Handler.new()
logged = account.sets_count() #raise exception
logged = account.sets_count(false) # raise exception
hash = account.sets_count('CardExchange')
hash = account.sets_count(76561198370420964)
hash = account.sets_count('https://steamcommunity.com/tradeoffer/new/?partner=410155236&token=H-yK-GFt',false)

update_blueprint()

require 'steam-trade'

handler = Handler.new

handler.update_blueprint()

2FA codes

fa(shared_secret, time_difference)

require 'steam-trade'
puts Hander.fa('random_shared_secret')


logged = Handler.new('username','password','inital_shared_secret')
puts logged.fa() #=> random code for your account
puts logged.fa('new_shared_secret') # => this will give you a random code for another account, AND will not edit your initial_shared_secret

####
logged_without_shared_secret = Handler.new('username','password') # this is possible of course
puts logged_without_shared_secret.fa() # this will not work
puts logged_without_shared_secret.fa('shared_secret') ## will give a random code
###
nonlogged = Handler.new()
puts nonlogged.fa() # will not work
puts logged.fa() # will give a random code

Social Commands

mobile_login('username','password','shared_secret')

require 'steam-trade'

h = Handler.new('user','pass','secret')
data = h.mobile_login() #this works are you have setted username and password
puts data ## will output with oauth token and steamMachine cookie

###################
h = Handler.new()
data = h.mobile_login() # will raise an error cause there is no username or password

##########

h = Handler.new()
data = h.mobile_login('user','pass','secret') ## will work, you are not logged in ( talking about community) here you can't use most of the commands (send_offer() etc) and those parameters you passed will not be setted as the Handler's

######
h = Handler.new('user1','pass1','secret1')
data = mobile_login('user2','pass2','secret2') # this works but trading commands etc will be called using user1, and chat commands will be called using user2

oauth_login(oauth_token,SteamMachine)

require 'steam-trade'
h = Handler.new()
h.oauth_login('oauth_token','SteamMachine')

send_message(target, message)

sends a message to the target

require 'steam-trade'

h = Handler.new('username', 'password')
h.send_message('nomg3r', "Hello, Friend")

poll_messages()

gives you the messages you receieved (after mobile login is initiated (after you call send_message() or poll_messages() ) )

require 'steam-trade'

h = Handler.new('username', 'password')
print h.poll_messages() # will not return messages so you call at again ( only the first time in the whole program )
puts ""
puts "------"
sleep(10) #send a message to the logged in account
print h.poll_messages() # actually have messages ( if you received some in the time between the first and the second request )

ALL OF THE COMMANDS BELOW REQUIRES LOGIN

send_friend_request(target)

sends a friend request to the target

require 'steam-trade'

h = Handler.new('username', 'password')
h.send_friend_request('nomg3r')

accept_friend_request(target)

accepts a friend request from the target

require 'steam-trade'

h = Handler.new('username', 'password')
h.accept_friend_request('nomg3r')

remove_friend(target)

removes a friend

require 'steam-trade'

h = Handler.new('username', 'password')
h.remove_friend('nomg3r')

More commands

you can find more non-vital commands in the wiki

License

The gem is available as open source under the terms of the GNU GPLV3.