This is a Node.js port of SteamKit2. It lets you interface with Steam without running an actual Steam client. Could be used to run an autonomous chat/trade bot.
npm install steam
Note: there are a number of breaking changes in v0.6.0. Please read the release notes.
Windows note: this module depends on ursa. Follow its installation prerequisites first.
First, require
this module.
var Steam = require('steam');
Steam
is now a namespace (implemented as an object) containing the SteamClient class, servers
property, and a huge collection of enums (implemented as objects). More on those below.
Then you'll want to create an instance of SteamClient, call its logOn method and assign event listeners.
var bot = new Steam.SteamClient();
bot.logOn({
accountName: 'username',
password: 'password'
});
bot.on('loggedOn', function() { /* ... */});
See example.js for the usage of some of the available API.
Steam.servers
contains the list of CM servers node-steam will attempt to connect to. The bootstrapped list (see servers.js) is not always up-to-date and might contain dead servers. To avoid timeouts, replace it with your own list before logging in if you have one (see 'servers' event).
Since JavaScript's Number
type does not have enough precision to store 64-bit integers, SteamIDs are represented as decimal strings. (Just wrap the number in quotes)
Whenever a method accepts (or an event provides) an ESomething
, it's a Number
that represents some enum value. See steam_language.js for the whole list of them.
Note that you can't easily get the string value from the number, but you probably don't need to. You can still use them in conditions (e.g. if (type == Steam.EChatEntryType.Emote) ...
) or switch statements.
A boolean that indicates whether you are currently logged on. 'loggedOn' is emitted when it changes to true
, and 'loggedOff' or 'error' when it changes to false
, unless you called logOff. Accessing any other properties or calling any methods other than logOn or logOff is only allowed while logged on.
Your own SteamID.
Information about users you have encountered. It's an object with the following structure:
{
"steamID of the user": {
playerName: "the user's current profile name",
gameName: "the title of the game the user is currently playing"
// ...and other properties that come directly from Steam
}
// ...other users
}
Information about chat rooms you have joined. It's an object with the following structure:
{
"steamID of the chat": {
"steamID of one of the chat's current members": {
rank: "EClanPermission",
permissions: "a bitset of values from EChatPermission"
}
// other members
}
// other chats
}
For example, Object.keys(steamClient.chatRooms[chatID])
will return an array of the chat's current members, and steamClient.chatRooms[chatID][memberID].permissions & Steam.EChatPermission.Kick
will evaluate to a nonzero value if the specified user is allowed to kick from the specified chat.
An object that maps users' SteamIDs to their EFriendRelationship
with you. Empty until 'relationships' is emitted. 'friend' is emitted before this object changes.
An object that maps groups' SteamIDs to their EClanRelationship
with you. Empty until 'relationships' is emitted. 'group' is emitted before this object changes.
Connects to Steam and logs you on upon connecting. logOnDetails
is an object with the following properties:
accountName
- required.password
- required.authCode
- Steam Guard code. Must be valid if provided, otherwise the logon will fail. Note that Steam Guard codes expire after a short while.shaSentryfile
- sentry hash. If not provided, you'll receive one through the 'sentry' event (if the logon succeeds). If no Steam Guard code is provided, the hash must be already registered with this account, otherwise it's ignored.
If you provide neither a Steam Guard code nor a sentry hash registered with this account, the logon will fail and you'll receive an email with the code.
If you provide both a sentry hash and a valid Steam Guard code, the hash will be registered with this account. This allows you to reuse the same hash for multiple accounts.
You can call this method at any time. If you are already logged on, logs you off first. If there is an ongoing connection attempt, cancels it.
Logs you off from Steam. If you are already logged off, does nothing. If there is an ongoing connection attempt, cancels it. Will not emit either 'loggedOff' or 'error'.
Logs into Steam Community. You only need this if you know you do. callback
will be called with an array of your new cookies (as strings).
Do not call this before the first 'webSessionID' event, or you'll get a broken cookie. Feel free to call this whenever you need to refresh your web session - for example, if you log into the same account from a browser on another computer.
Tells Steam you are playing game(s). appIDs
is an array of AppIDs, for example [570]
. Multiple AppIDs can (used to?) be used for multi-game idling.
Changes your Steam profile name.
You'll want to call this with EPersonaState.Online
upon logon, otherwise you'll show up as offline.
Last parameter defaults to EChatEntryType.ChatMsg
. Another type you might want to use is EChatEntryType.Emote
.
Sends a friend request.
Removes a friend.
Joins the chat room of the specified group. Go to the group's Community page, press Ctrl+U and search for "joinchat". Will silently fail if you are not allowed to join.
Leaves the chat room of the specified group. Will silently fail if you are not currently in it. Removes the chat from chatRooms
.
Locks and unlocks a chat room respectively.
Enables and disables officers-only chat respectively.
kick(chatSteamID, memberSteamID), ban(chatSteamID, memberSteamID), unban(chatSteamID, memberSteamID)
Self-explanatory.
Sends a trade request to the specified user.
Same tradeID
as the one passed through the 'tradeProposed' event. acceptTrade
should be true
or false
.
Cancels your proposed trade to the specified user.
Sends a message to Game Coordinator. body
must be a serialized message without the header (it will be added by node-steam). type
must be masked accordingly if it's a protobuf message. If any extra arguments are provided and this message receives a response (JobID-based), they will be passed to the 'fromGC' event handler.
e
- anError
object
Something preventing continued operation of node-steam has occurred. e.cause
is a string containing one of these values:
- 'logonFail' - can't log into Steam.
e.eresult
is anEResult
, the logon response. Some values you might want to handle areInvalidPassword
,AlreadyLoggedInElsewhere
andAccountLogonDenied
(Steam Guard code required). - 'loggedOff' - you were logged off for a reason other than Steam going down.
e.eresult
is anEResult
, most likelyLoggedInElsewhere
.
You can now safely use all API.
- your new sessionID
If you are using Steam Community (including trading), you should call webLogOn again, since your current cookie is no longer valid.
- a Buffer containing your Steam Guard sentry file hash
If you didn't provide a hash when logging in, Steam will send you one through this event. If you have Steam Guard enabled, you should save this and use it for your further logons. It will not expire unlike the code.
- an Array containing the up-to-date server list
node-steam will use this new list when reconnecting, but it will be lost when your application restarts. You might want to save it to a file or a database and assign it to Steam.servers
before logging in next time.
Note that Steam.servers
will be automatically updated after this event is emitted. This will be useful if you want to compare the old list with the new one for some reason - otherwise it shouldn't matter.
You were logged off from Steam due to it going down. It will keep trying to reconnect and eventually emit either 'loggedOn' or 'error', unless you cancel it with logOff.
- SteamID of the chat you were invited to
- name of the chat
- SteamID of the user who invited you
- Object with new user data
Someone has gone offline/online, started a game, changed their nickname or something else. The provided object has the same structure as in the users
property, and its friendid
property contains the user's SteamID. Note that the users
property is not yet updated when this event is fired, so you can compare the new state with the old one to see what changed.
This API is unstable.
- SteamID of the user
- the user's string status (e.g. '#DOTA_RP_FINDING_MATCH' or '#DOTA_RP_PLAYING_AS')
- optional extra args (in Dota 2, hero level and hero name)
Game-specific information about a user. Only received when you're in the same game.
The friends
and groups
properties now contain data (unless your friend/group list is empty). Listen for this if you want to accept/decline friend requests that came while you were offline, for example.
- SteamID of the user
EFriendRelationship
Some activity in your friend list. For example, EFriendRelationship.PendingInvitee
means you got a friend invite, EFriendRelationship.None
means you got removed. The friends
property is updated after this event is emitted.
- SteamID of the group
EClanRelationship
Some activity in your group list. For example, EClanRelationship.Invited
means you got invited to a group, EClanRelationship.Kicked
means you got kicked. The groups
property is updated after this event is emitted.
- SteamID of the user
- the message
EChatEntryType
- SteamID of the chat room
- the message
EChatEntryType
- SteamID of the chatter
Same arguments as the above two, captures both events. In case of a friend message, the fourth argument will be undefined.
EChatMemberStateChange
- SteamID of the user who entered or left the chat room, disconnected, or was kicked or banned
- SteamID of the chat where it happened
- SteamID of the user who kicked or banned
Something happened in a chat you are in. For example, if the first argument equals Steam.EChatMemberStateChange.Kicked
, then someone got kicked.
- New count (can be zero)
Your number of pending incoming trade offers has changed.
- Trade ID
- SteamID of the user who proposed the trade
You were offered a trade.
- Trade ID
EEconTradeResponse
- SteamID of the user you sent a trade request
Listen for this event if you are the one sending a trade request.
- SteamID of the other party
The trade is now available at http://steamcommunity.com/trade/{SteamID}. You'll need the cookies from webLogOn. You can use node-steam-trade to automate the trade itself.
- SteamID of the group
- headline
Use the group's RSS feed to get the body of the announcement if you want it.
- appID
type
- masked accordingly for protobuf- the message body
- optional extra args
A message has been received from GC. The extra arguments are the same as passed to toGC if this message is a JobID-based response to it.