mirror of
https://github.com/DoctorMcKay/node-steamcommunity.git
synced 2026-08-19 13:13:28 +08:00
Compare commits
140 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e09cf24fbf | ||
|
|
9d2b5ade67 | ||
|
|
be4e5c9449 | ||
|
|
5926197f23 | ||
|
|
2d86f81142 | ||
|
|
f37bff4a57 | ||
|
|
c700b7663b | ||
|
|
c26e548c64 | ||
|
|
658d8fb708 | ||
|
|
cd68841d1d | ||
|
|
5853968661 | ||
|
|
10d899f7a7 | ||
|
|
4e1453e702 | ||
|
|
f3cf2a4361 | ||
|
|
2890b70add | ||
|
|
1810727a2f | ||
|
|
3d566ed0fb | ||
|
|
80979bc387 | ||
|
|
4e326e3295 | ||
|
|
cff35ba863 | ||
|
|
d975fdfba8 | ||
|
|
4e3c319ee1 | ||
|
|
e5cbd23110 | ||
|
|
82f1d490f9 | ||
|
|
c3f5b492b3 | ||
|
|
09cd81b607 | ||
|
|
8a6d912374 | ||
|
|
c392f2ac74 | ||
|
|
8e6f859269 | ||
|
|
84dce9872a | ||
|
|
c2ad457e87 | ||
|
|
0116842deb | ||
|
|
3d0522a560 | ||
|
|
3db3d47e92 | ||
|
|
f341dbe72a | ||
|
|
22f388e110 | ||
|
|
115f13f686 | ||
|
|
a30739067e | ||
|
|
bd87f27c9c | ||
|
|
07c8c724e7 | ||
|
|
ea88c1cda4 | ||
|
|
c291f0fab3 | ||
|
|
88063ebf27 | ||
|
|
8485b447d8 | ||
|
|
df20c1ac25 | ||
|
|
49b038d3d2 | ||
|
|
d1efe5f203 | ||
|
|
b16a8144ff | ||
|
|
019e33d360 | ||
|
|
01093f38fa | ||
|
|
62c2f1b965 | ||
|
|
21895a221c | ||
|
|
f3d88d6b83 | ||
|
|
09327af220 | ||
|
|
0bb2cb6137 | ||
|
|
c9538137d5 | ||
|
|
df05fd04c4 | ||
|
|
dee52bf7e2 | ||
|
|
6d455e8797 | ||
|
|
a0b776ca8b | ||
|
|
3f0db21e02 | ||
|
|
6798b73a17 | ||
|
|
b98451a4b6 | ||
|
|
af2ba3f56b | ||
|
|
9c2662ae16 | ||
|
|
9ee49d4f15 | ||
|
|
911ae86379 | ||
|
|
a12e8cb67c | ||
|
|
edd95cc93f | ||
|
|
4f1f265c4d | ||
|
|
80c0c3ebbc | ||
|
|
a1ef4b5646 | ||
|
|
06f7f10dfe | ||
|
|
484c049940 | ||
|
|
36038daa1b | ||
|
|
12cffdd62c | ||
|
|
eaacef66bb | ||
|
|
0ef652cbac | ||
|
|
608377277c | ||
|
|
bcaa740b54 | ||
|
|
2674287b43 | ||
|
|
8b6bed5527 | ||
|
|
6def665b64 | ||
|
|
4f618c0a27 | ||
|
|
19fe951d96 | ||
|
|
a348112ccb | ||
|
|
dff2727f85 | ||
|
|
1fd12dd4d0 | ||
|
|
31093da1a8 | ||
|
|
1e609524e8 | ||
|
|
2a758fc180 | ||
|
|
eb2081c325 | ||
|
|
c60d4942e0 | ||
|
|
1aa42b89f7 | ||
|
|
e01d05c140 | ||
|
|
8ec0ef84c2 | ||
|
|
0e5929df24 | ||
|
|
74bf2dcfca | ||
|
|
e8634e17ca | ||
|
|
2a2947344f | ||
|
|
e789d07833 | ||
|
|
88059596b3 | ||
|
|
399cc5ee84 | ||
|
|
a24bb9d4ad | ||
|
|
81eb26b30d | ||
|
|
0c95e75e39 | ||
|
|
2eaa5b057d | ||
|
|
d5592246cf | ||
|
|
22ab86434a | ||
|
|
d367ceb2a6 | ||
|
|
5ab5a6d401 | ||
|
|
a88a39c62c | ||
|
|
5f4f4a03a4 | ||
|
|
079db4b7bf | ||
|
|
22ba30f5da | ||
|
|
8ca763d9b9 | ||
|
|
eb88ace3d7 | ||
|
|
4138d1c14a | ||
|
|
4c0cd4dc8b | ||
|
|
8bad7dd09f | ||
|
|
3402acb33a | ||
|
|
00426a6aea | ||
|
|
116c57e6ff | ||
|
|
193d77c3d1 | ||
|
|
6014ce1567 | ||
|
|
8e8ce2aa89 | ||
|
|
0cb5eef1f8 | ||
|
|
7f2a287c56 | ||
|
|
7643d2efad | ||
|
|
d257108500 | ||
|
|
b0b8dbbabf | ||
|
|
b1e31b32fe | ||
|
|
0f16f11668 | ||
|
|
e6789b1021 | ||
|
|
218d0dc7da | ||
|
|
5ca5bc30ac | ||
|
|
7d1c641967 | ||
|
|
90593b2dc0 | ||
|
|
3d3c899f9d | ||
|
|
037ac1a9d7 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1 +1,3 @@
|
||||
node_modules/*
|
||||
node_modules/*
|
||||
test.js
|
||||
.idea/
|
||||
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Alexander Corn
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
62
README.md
62
README.md
@@ -1,8 +1,13 @@
|
||||
# Steam Community for Node.js
|
||||
[](https://npmjs.com/package/steamcommunity)
|
||||
[](https://npmjs.com/package/steamcommunity)
|
||||
[](https://david-dm.org/DoctorMcKay/node-steamcommunity)
|
||||
[](https://github.com/DoctorMcKay/node-steamcommunity/blob/master/LICENSE)
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=N36YVAT42CZ4G&item_name=node%2dsteamcommunity¤cy_code=USD)
|
||||
|
||||
This lightweight module provides an easy interface to login to the Steam Community website. You can also login to the Steam Community website via [node-steam](https://github.com/seishun/node-steam)'s `webLogOn` method, but this module may be useful if you don't want to run an entire Steam instance.
|
||||
This module provides an easy interface for the Steam Community website. This module can be used to simply login to steamcommunity.com for use with other libraries, or to interact with steamcommunity.com.
|
||||
|
||||
It supports Steam Guard but doesn't support CAPTCHAs, so make sure you don't provide Steam with an incorrect password.
|
||||
It supports Steam Guard and CAPTCHAs.
|
||||
|
||||
# Installation
|
||||
|
||||
@@ -10,55 +15,6 @@ Install it from npm:
|
||||
|
||||
$ npm install steamcommunity
|
||||
|
||||
# Usage
|
||||
# Documentation
|
||||
|
||||
First, instantiate the `SteamCommunity` object:
|
||||
|
||||
```js
|
||||
var SteamCommunity = require('steamcommunity');
|
||||
var community = new SteamCommunity("username", "password");
|
||||
```
|
||||
|
||||
Then, simply call the `login` method:
|
||||
|
||||
```js
|
||||
community.login(function(err, sessionID, cookies, steamguard) {
|
||||
// Do something with the sessionID and cookies.
|
||||
// The steamguard parameter is only meaningful if you've entered a Steam Guard auth code, as shown below.
|
||||
});
|
||||
```
|
||||
|
||||
# Steam Guard
|
||||
|
||||
In order to authenticate with a Steam Guard authorization, you need to provide your 64-bit Steam ID and machineAuth value to the constructor:
|
||||
|
||||
```js
|
||||
var SteamCommunity = require('steamcommunity');
|
||||
var community = new SteamCommunity("username", "password", "steamid64", "machineAuth");
|
||||
```
|
||||
|
||||
If you don't have a prior authorization, you can get one by logging in as normal (without the steamID and machineAuth parameters). The callback to the `login` method will get `SteamGuard` as `err`. This means that an email has been sent to the email address tied to your account. Once you get the code, just call `login` again with the code as the first parameter:
|
||||
|
||||
```js
|
||||
community.login('ABCDE', function(err, sessionID, cookies, steamguard) {
|
||||
// steamguard is now an object with two properties: steamID and machineAuth. You'll want to save these and provide them to subsequent constructors.
|
||||
// If you call login again on this instance of SteamCommunity, the Steam Guard machineAuth will be sent automatically so you don't need to reconstruct a new instance.
|
||||
});
|
||||
```
|
||||
|
||||
# Methods
|
||||
|
||||
## Constructor: SteamCommunity(username, password[, steamID, machineAuth])
|
||||
|
||||
Instantiate a new instance of `SteamCommunity`. `steamID` and `machineAuth` are optional, but if you have them and your account is protectd by Steam Guard, you should provide them. Otherwise, you'll get a `SteamGuard` error when you try to login.
|
||||
|
||||
## login([code, ]callback)
|
||||
|
||||
Attempts to login to Steam Community using the credentials supplied in the constructor. If you have previously received a `SteamGuard` error and you have an email auth code, supply it here as the first parameter.
|
||||
|
||||
The `callback` has 4 parameters:
|
||||
|
||||
- `err` - An error that occurred, or `null` on success. The value will be `SteamGuard` if you need to supply an email auth code.
|
||||
- `sessionID` - This session's sessionID. Whatever module you're using with this will know what to do with it.
|
||||
- `cookies` - An array of session cookies. The format is the same as that returned by [node-steam](https://github.com/seishun/node-steam)'s `webLogOn` method, so anything designed to work with node-steam will also work with this.
|
||||
- `steamguard` - If you supplied an email auth code, this will contain your `steamID` and `machineAuth` code, which you should save and provide for subsequent logins.
|
||||
As of version 1.0.0, documentation is on the [GitHub wiki](https://github.com/DoctorMcKay/node-steamcommunity/wiki).
|
||||
59
classes/CEconItem.js
Normal file
59
classes/CEconItem.js
Normal file
@@ -0,0 +1,59 @@
|
||||
module.exports = CEconItem;
|
||||
|
||||
function CEconItem(item, descriptions, contextID) {
|
||||
var thing;
|
||||
for(thing in item) {
|
||||
if(item.hasOwnProperty(thing)) {
|
||||
this[thing] = item[thing];
|
||||
}
|
||||
}
|
||||
|
||||
this.assetid = this.id = (this.id || this.assetid);
|
||||
this.instanceid = this.instanceid || '0';
|
||||
this.amount = parseInt(this.amount, 10);
|
||||
this.contextid = this.contextid || contextID.toString();
|
||||
|
||||
// Merge the description
|
||||
if(descriptions) {
|
||||
var description = descriptions[this.classid + '_' + this.instanceid];
|
||||
if(description) {
|
||||
for(thing in description) {
|
||||
if(description.hasOwnProperty(thing)) {
|
||||
this[thing] = description[thing];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.tradable = !!this.tradable;
|
||||
this.marketable = !!this.marketable;
|
||||
this.commodity = !!this.commodity;
|
||||
this.market_tradable_restriction = (this.market_tradable_restriction ? parseInt(this.market_tradable_restriction, 10) : 0);
|
||||
this.market_marketable_restriction = (this.market_marketable_restriction ? parseInt(this.market_marketable_restriction, 10) : 0);
|
||||
}
|
||||
|
||||
CEconItem.prototype.getImageURL = function() {
|
||||
return "https://steamcommunity-a.akamaihd.net/economy/image/" + this.icon_url + "/";
|
||||
};
|
||||
|
||||
CEconItem.prototype.getLargeImageURL = function() {
|
||||
if(!this.icon_url_large) {
|
||||
return this.getImageURL();
|
||||
}
|
||||
|
||||
return "https://steamcommunity-a.akamaihd.net/economy/image/" + this.icon_url_large + "/";
|
||||
};
|
||||
|
||||
CEconItem.prototype.getTag = function(category) {
|
||||
if(!this.tags) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for(var i = 0; i < this.tags.length; i++) {
|
||||
if(this.tags[i].category == category) {
|
||||
return this.tags[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
126
classes/CMarketItem.js
Normal file
126
classes/CMarketItem.js
Normal file
@@ -0,0 +1,126 @@
|
||||
var SteamCommunity = require('../index.js');
|
||||
var Cheerio = require('cheerio');
|
||||
|
||||
SteamCommunity.prototype.getMarketItem = function(appid, hashName, callback) {
|
||||
var self = this;
|
||||
this.request("https://steamcommunity.com/market/listings/" + appid + "/" + encodeURIComponent(hashName), function(err, response, body) {
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $ = Cheerio.load(body);
|
||||
if($('.market_listing_table_message') && $('.market_listing_table_message').text().trim() == 'There are no listings for this item.') {
|
||||
callback(new Error("There are no listings for this item."));
|
||||
return;
|
||||
}
|
||||
|
||||
var item = new CMarketItem(self, body, $);
|
||||
if(item.commodity) {
|
||||
item.updatePrice(function(err) {
|
||||
if(err) {
|
||||
callback(err);
|
||||
} else {
|
||||
callback(null, item);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
callback(null, item);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function CMarketItem(community, body, $) {
|
||||
this._community = community;
|
||||
this._$ = $;
|
||||
|
||||
this._country = "US";
|
||||
var match = body.match(/var g_strCountryCode = "([^"]+)";/);
|
||||
if(match) {
|
||||
this._country = match[1];
|
||||
}
|
||||
|
||||
this.commodity = false;
|
||||
var match = body.match(/Market_LoadOrderSpread\(\s*(\d+)\s*\);/);
|
||||
if(match) {
|
||||
this.commodity = true;
|
||||
this.commodityID = parseInt(match[1], 10);
|
||||
}
|
||||
|
||||
this.medianSalePrices = null;
|
||||
match = body.match(/var line1=([^;]+);/);
|
||||
if(match) {
|
||||
try {
|
||||
this.medianSalePrices = JSON.parse(match[1]);
|
||||
this.medianSalePrices = this.medianSalePrices.map(function(item) {
|
||||
return {
|
||||
"hour": new Date(item[0]),
|
||||
"price": item[1],
|
||||
"quantity": parseInt(item[2], 10)
|
||||
};
|
||||
});
|
||||
} catch(e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
this.quantity = 0;
|
||||
this.lowestPrice = 0;
|
||||
|
||||
if(!this.commodity) {
|
||||
var total = $('#searchResults_total');
|
||||
if(total) {
|
||||
this.quantity = parseInt(total.text().replace(/[^\d]/g, '').trim(), 10);
|
||||
}
|
||||
|
||||
var lowest = $('.market_listing_price.market_listing_price_with_fee');
|
||||
if(lowest[0]) {
|
||||
this.lowestPrice = parseInt($(lowest[0]).text().replace(/[^\d]/g, '').trim(), 10);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Buying listings and placing buy orders
|
||||
}
|
||||
|
||||
CMarketItem.prototype.updatePrice = function(callback) {
|
||||
if(!this.commodity) {
|
||||
throw new Error("Cannot update price for non-commodity item");
|
||||
}
|
||||
|
||||
// TODO: Currency option maybe?
|
||||
var self = this;
|
||||
this._community.request({
|
||||
"uri": "https://steamcommunity.com/market/itemordershistogram?country=US&language=english¤cy=1&item_nameid=" + this.commodityID,
|
||||
"json": true,
|
||||
}, function(err, response, body) {
|
||||
if(self._community._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(body.success != 1) {
|
||||
if(callback) {
|
||||
callback(new Error("Error " + body.success));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var match = (body.sell_order_summary || '').match(/<span class="market_commodity_orders_header_promote">(\d+)<\/span>/);
|
||||
if(match) {
|
||||
self.quantity = parseInt(match[1], 10);
|
||||
}
|
||||
|
||||
self.buyQuantity = 0;
|
||||
match = (body.buy_order_summary || '').match(/<span class="market_commodity_orders_header_promote">(\d+)<\/span>/);
|
||||
if(match) {
|
||||
self.buyQuantity = parseInt(match[1], 10);
|
||||
}
|
||||
|
||||
self.lowestPrice = parseInt(body.lowest_sell_order, 10);
|
||||
self.highestBuyOrder = parseInt(body.highest_buy_order, 10);
|
||||
|
||||
// TODO: The tables?
|
||||
if(callback) {
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
};
|
||||
85
classes/CMarketSearchResult.js
Normal file
85
classes/CMarketSearchResult.js
Normal file
@@ -0,0 +1,85 @@
|
||||
var SteamCommunity = require('../index.js');
|
||||
var Cheerio = require('cheerio');
|
||||
|
||||
SteamCommunity.prototype.marketSearch = function(options, callback) {
|
||||
var qs = {};
|
||||
|
||||
if(typeof options === 'string') {
|
||||
qs.query = options;
|
||||
} else {
|
||||
qs.query = options.query || '';
|
||||
qs.appid = options.appid;
|
||||
qs.search_descriptions = options.searchDescriptions ? 1 : 0;
|
||||
|
||||
if(qs.appid) {
|
||||
for(var i in options) {
|
||||
if(['query', 'appid', 'searchDescriptions'].indexOf(i) != -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// This is a tag
|
||||
qs['category_' + qs.appid + '_' + i + '[]'] = 'tag_' + options[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qs.start = 0;
|
||||
qs.count = 100;
|
||||
qs.sort_column = 'price';
|
||||
qs.sort_dir = 'asc';
|
||||
performSearch.call(this, this.request, qs, [], callback);
|
||||
};
|
||||
|
||||
function performSearch(request, qs, results, callback) {
|
||||
var self = this;
|
||||
request({
|
||||
"uri": "https://steamcommunity.com/market/search/render/",
|
||||
"qs": qs,
|
||||
"headers": {
|
||||
"referer": "https://steamcommunity.com/market/search"
|
||||
},
|
||||
"json": true
|
||||
}, function(err, response, body) {
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!body.success) {
|
||||
callback(new Error("Success is not true"));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!body.results_html) {
|
||||
callback(new Error("No results_html in response"));
|
||||
return;
|
||||
}
|
||||
|
||||
var $ = Cheerio.load(body.results_html);
|
||||
if($('.market_listing_table_message').length > 0) {
|
||||
callback(new Error($('.market_listing_table_message').text()));
|
||||
return;
|
||||
}
|
||||
|
||||
var rows = $('.market_listing_row_link');
|
||||
for(var i = 0; i < rows.length; i++) {
|
||||
results.push(new CMarketSearchResult($(rows[i])));
|
||||
}
|
||||
|
||||
if(body.start + body.pagesize >= body.total_count) {
|
||||
callback(null, results);
|
||||
} else {
|
||||
qs.start += body.pagesize;
|
||||
performSearch(request, qs, results, callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function CMarketSearchResult(row) {
|
||||
var match = row.attr('href').match(/\/market\/listings\/(\d+)\/(.+)/);
|
||||
|
||||
this.appid = parseInt(match[1], 10);
|
||||
this.market_hash_name = decodeURIComponent(match[2]);
|
||||
this.image = row.find('.market_listing_item_img').attr('src').match(/^https?:\/\/[^\/]+\/economy\/image\/[^\/]+\//)[0];
|
||||
this.price = parseInt(row.find('.market_listing_their_price .market_table_value span').text().replace(/[^\d]+/g, ''), 10);
|
||||
this.quantity = parseInt(row.find('.market_listing_num_listings_qty').text().replace(/[^\d]+/g, ''), 10);
|
||||
}
|
||||
97
classes/CSteamGroup.js
Normal file
97
classes/CSteamGroup.js
Normal file
@@ -0,0 +1,97 @@
|
||||
var SteamCommunity = require('../index.js');
|
||||
var SteamID = require('steamid');
|
||||
var xml2js = require('xml2js');
|
||||
|
||||
SteamCommunity.prototype.getSteamGroup = function(id, callback) {
|
||||
if(typeof id !== 'string' && !(typeof id === 'object' && id.__proto__ === SteamID.prototype)) {
|
||||
throw new Error("id parameter should be a group URL string or a SteamID object");
|
||||
}
|
||||
|
||||
if(typeof id === 'object' && (id.universe != SteamID.Universe.PUBLIC || id.type != SteamID.Type.CLAN)) {
|
||||
throw new Error("SteamID must stand for a clan account in the public universe");
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.request("https://steamcommunity.com/" + (typeof id === 'string' ? "groups/" + id : "gid/" + id.toString()) + "/memberslistxml/?xml=1", function(err, response, body) {
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(self._checkCommunityError(body, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
xml2js.parseString(body, function(err, result) {
|
||||
if(err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, new CSteamGroup(self, result.memberList));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
function CSteamGroup(community, groupData) {
|
||||
this._community = community;
|
||||
|
||||
this.steamID = new SteamID(groupData.groupID64[0]);
|
||||
this.name = groupData.groupDetails[0].groupName[0];
|
||||
this.url = groupData.groupDetails[0].groupURL[0];
|
||||
this.headline = groupData.groupDetails[0].headline[0];
|
||||
this.summary = groupData.groupDetails[0].summary[0];
|
||||
this.avatarHash = groupData.groupDetails[0].avatarIcon[0].match(/([0-9a-f]+)\.jpg$/)[1];
|
||||
this.members = parseInt(groupData.groupDetails[0].memberCount[0], 10);
|
||||
this.membersInChat = parseInt(groupData.groupDetails[0].membersInChat[0], 10);
|
||||
this.membersInGame = parseInt(groupData.groupDetails[0].membersInGame[0], 10);
|
||||
this.membersOnline = parseInt(groupData.groupDetails[0].membersOnline[0], 10);
|
||||
}
|
||||
|
||||
CSteamGroup.prototype.getAvatarURL = function(size, protocol) {
|
||||
size = size || '';
|
||||
protocol = protocol || 'http://';
|
||||
|
||||
var url = protocol + "steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/" + this.avatarHash.substring(0, 2) + "/" + this.avatarHash;
|
||||
if(size == 'full' || size == 'medium') {
|
||||
return url + "_" + size + ".jpg";
|
||||
} else {
|
||||
return url + ".jpg";
|
||||
}
|
||||
};
|
||||
|
||||
CSteamGroup.prototype.getMembers = function(addresses, callback) {
|
||||
if(typeof addresses === 'function') {
|
||||
callback = addresses;
|
||||
addresses = null;
|
||||
}
|
||||
|
||||
this._community.getGroupMembers(this.steamID, callback, null, null, addresses, 0);
|
||||
};
|
||||
|
||||
CSteamGroup.prototype.join = function(callback) {
|
||||
this._community.joinGroup(this.steamID, callback);
|
||||
};
|
||||
|
||||
CSteamGroup.prototype.leave = function(callback) {
|
||||
this._community.leaveGroup(this.steamID, callback);
|
||||
};
|
||||
|
||||
CSteamGroup.prototype.postAnnouncement = function(headline, content, callback) {
|
||||
this._community.postGroupAnnouncement(this.steamID, headline, content, callback);
|
||||
};
|
||||
|
||||
CSteamGroup.prototype.scheduleEvent = function(name, type, description, time, server, callback) {
|
||||
this._community.scheduleGroupEvent(this.steamID, name, type, description, time, server, callback);
|
||||
};
|
||||
|
||||
CSteamGroup.prototype.setPlayerOfTheWeek = function(steamID, callback) {
|
||||
this._community.setGroupPlayerOfTheWeek(this.steamID, steamID, callback);
|
||||
};
|
||||
|
||||
CSteamGroup.prototype.kick = function(steamID, callback) {
|
||||
this._community.kickGroupMember(this.steamID, steamID, callback);
|
||||
};
|
||||
|
||||
CSteamGroup.prototype.getHistory = function(page, callback) {
|
||||
this._community.getGroupHistory(this.steamID, page, callback);
|
||||
};
|
||||
161
classes/CSteamUser.js
Normal file
161
classes/CSteamUser.js
Normal file
@@ -0,0 +1,161 @@
|
||||
var SteamCommunity = require('../index.js');
|
||||
var SteamID = require('steamid');
|
||||
var xml2js = require('xml2js');
|
||||
|
||||
SteamCommunity.prototype.getSteamUser = function(id, callback) {
|
||||
if(typeof id !== 'string' && !(typeof id === 'object' && id.__proto__ === SteamID.prototype)) {
|
||||
throw new Error("id parameter should be a user URL string or a SteamID object");
|
||||
}
|
||||
|
||||
if(typeof id === 'object' && (id.universe != SteamID.Universe.PUBLIC || id.type != SteamID.Type.INDIVIDUAL)) {
|
||||
throw new Error("SteamID must stand for an individual account in the public universe");
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.request("http://steamcommunity.com/" + (typeof id === 'string' ? "id/" + id : "profiles/" + id.toString()) + "/?xml=1", function(err, response, body) {
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(self._checkCommunityError(body, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
xml2js.parseString(body, function(err, result) {
|
||||
if(err || (!result.response && !result.profile)) {
|
||||
callback(err || new Error("No valid response"));
|
||||
return;
|
||||
}
|
||||
|
||||
if(result.response && result.response.error && result.response.error.length) {
|
||||
callback(new Error(result.response.error[0]));
|
||||
return;
|
||||
}
|
||||
|
||||
// Try and find custom URL from redirect
|
||||
var customurl = null;
|
||||
if(response.request.redirects && response.request.redirects.length) {
|
||||
var match = response.request.redirects[0].redirectUri.match(/https?:\/\/steamcommunity\.com\/id\/([^/])+\/\?xml=1/);
|
||||
if(match) {
|
||||
customurl = match[1];
|
||||
}
|
||||
}
|
||||
|
||||
if(!result.profile.steamID64) {
|
||||
callback(new Error("No valid response"));
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, new CSteamUser(self, result.profile, customurl));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
function CSteamUser(community, userData, customurl) {
|
||||
this._community = community;
|
||||
|
||||
this.steamID = new SteamID(userData.steamID64[0]);
|
||||
this.name = processItem('steamID');
|
||||
this.onlineState = processItem('onlineState');
|
||||
this.stateMessage = processItem('stateMessage');
|
||||
this.privacyState = processItem('privacyState', 'uncreated');
|
||||
this.visibilityState = processItem('visibilityState');
|
||||
this.avatarHash = processItem('avatarIcon', '').match(/([0-9a-f]+)\.[a-z]+$/);
|
||||
if(this.avatarHash) {
|
||||
this.avatarHash = this.avatarHash[1];
|
||||
}
|
||||
|
||||
this.vacBanned = !!processItem('vacBanned', false);
|
||||
this.tradeBanState = processItem('tradeBanState', 'None');
|
||||
this.isLimitedAccount = !!processItem('isLimitedAccount');
|
||||
this.customURL = processItem('customURL', customurl);
|
||||
|
||||
if(this.visibilityState == 3) {
|
||||
this.memberSince = new Date(processItem('memberSince', '0').replace(/(\d{1,2})(st|nd|th)/, "$1"));
|
||||
this.location = processItem('location');
|
||||
this.realName = processItem('realname');
|
||||
this.summary = processItem('summary');
|
||||
} else {
|
||||
this.memberSince = null;
|
||||
this.location = null;
|
||||
this.realName = null;
|
||||
this.summary = null;
|
||||
}
|
||||
|
||||
// Maybe handle mostPlayedGames?
|
||||
|
||||
this.groups = null;
|
||||
this.primaryGroup = null;
|
||||
|
||||
var self = this;
|
||||
if(userData.groups && userData.groups[0] && userData.groups[0].group) {
|
||||
this.groups = userData.groups[0].group.map(function(group) {
|
||||
if(group['$'] && group['$'].isPrimary) {
|
||||
self.primaryGroup = new SteamID(group.groupID64[0]);
|
||||
}
|
||||
|
||||
return new SteamID(group.groupID64[0]);
|
||||
});
|
||||
}
|
||||
|
||||
function processItem(name, defaultVal) {
|
||||
if(!userData[name]) {
|
||||
return defaultVal;
|
||||
}
|
||||
|
||||
return userData[name][0];
|
||||
}
|
||||
}
|
||||
|
||||
CSteamUser.getAvatarURL = function(hash, size, protocol) {
|
||||
size = size || '';
|
||||
protocol = protocol || 'http://';
|
||||
|
||||
var url = protocol + "steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/" + hash.substring(0, 2) + "/" + hash;
|
||||
if(size == 'full' || size == 'medium') {
|
||||
return url + "_" + size + ".jpg";
|
||||
} else {
|
||||
return url + ".jpg";
|
||||
}
|
||||
};
|
||||
|
||||
CSteamUser.prototype.getAvatarURL = function(size, protocol) {
|
||||
return CSteamUser.getAvatarURL(this.avatarHash, size, protocol);
|
||||
};
|
||||
|
||||
CSteamUser.prototype.addFriend = function(callback) {
|
||||
this._community.addFriend(this.steamID, callback);
|
||||
};
|
||||
|
||||
CSteamUser.prototype.acceptFriendRequest = function(callback) {
|
||||
this._community.acceptFriendRequest(this.steamID, callback);
|
||||
};
|
||||
|
||||
CSteamUser.prototype.removeFriend = function(callback) {
|
||||
this._community.removeFriend(this.steamID, callback);
|
||||
|
||||
};
|
||||
|
||||
CSteamUser.prototype.blockCommunication = function(callback) {
|
||||
this._community.blockCommunication(this.steamID, callback);
|
||||
};
|
||||
|
||||
CSteamUser.prototype.unblockCommunication = function(callback) {
|
||||
this._community.unblockCommunication(this.steamID, callback);
|
||||
};
|
||||
|
||||
CSteamUser.prototype.comment = function(message, callback) {
|
||||
this._community.postUserComment(this.steamID, message, callback);
|
||||
};
|
||||
|
||||
CSteamUser.prototype.inviteToGroup = function(groupID, callback) {
|
||||
this._community.inviteUserToGroup(this.steamID, groupID, callback);
|
||||
};
|
||||
|
||||
CSteamUser.prototype.getInventoryContexts = function(callback) {
|
||||
this._community.getUserInventoryContexts(this.steamID, callback);
|
||||
};
|
||||
|
||||
CSteamUser.prototype.getInventory = function(appID, contextID, tradableOnly, callback) {
|
||||
this._community.getUserInventory(this.steamID, appID, contextID, tradableOnly, callback);
|
||||
};
|
||||
253
components/chat.js
Normal file
253
components/chat.js
Normal file
@@ -0,0 +1,253 @@
|
||||
var SteamCommunity = require('../index.js');
|
||||
var SteamID = require('steamid');
|
||||
|
||||
SteamCommunity.ChatState = {
|
||||
"Offline": 0,
|
||||
"LoggingOn": 1,
|
||||
"LogOnFailed": 2,
|
||||
"LoggedOn": 3
|
||||
};
|
||||
|
||||
SteamCommunity.PersonaState = {
|
||||
"Offline": 0,
|
||||
"Online": 1,
|
||||
"Busy": 2,
|
||||
"Away": 3,
|
||||
"Snooze": 4,
|
||||
"LookingToTrade": 5,
|
||||
"LookingToPlay": 6,
|
||||
"Max": 7
|
||||
};
|
||||
|
||||
SteamCommunity.PersonaStateFlag = {
|
||||
"HasRichPresence": 1,
|
||||
"InJoinableGame": 2,
|
||||
|
||||
"OnlineUsingWeb": 256,
|
||||
"OnlineUsingMobile": 512,
|
||||
"OnlineUsingBigPicture": 1024
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.chatLogon = function(interval, uiMode) {
|
||||
if(this.chatState == SteamCommunity.ChatState.LoggingOn || this.chatState == SteamCommunity.ChatState.LoggedOn) {
|
||||
return;
|
||||
}
|
||||
|
||||
interval = interval || 500;
|
||||
uiMode = uiMode || "web";
|
||||
|
||||
this.emit('debug', 'Requesting chat WebAPI token');
|
||||
this.chatState = SteamCommunity.ChatState.LoggingOn;
|
||||
|
||||
var self = this;
|
||||
this.request("https://steamcommunity.com/chat", function(err, response, body) {
|
||||
if(err || response.statusCode != 200) {
|
||||
self.emit('debug', 'Error requesting chat WebAPI token: ' + (err ? err.message : "HTTP error " + response.statusCode));
|
||||
self.chatState = SteamCommunity.ChatState.LogOnFailed;
|
||||
setTimeout(self.chatLogon.bind(self), 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
var match = body.match(/[0-9a-f]{32}/);
|
||||
if(!match) {
|
||||
self.emit('debug', 'Couldn\'t find a WebAPI chat token in the response.');
|
||||
self.chatState = SteamCommunity.ChatState.LogOnFailed;
|
||||
setTimeout(self.chatLogon.bind(self), 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
self.request.post({
|
||||
"uri": "https://api.steampowered.com/ISteamWebUserPresenceOAuth/Logon/v1",
|
||||
"form": {
|
||||
"ui_mode": uiMode,
|
||||
"access_token": match[0]
|
||||
},
|
||||
"json": true
|
||||
}, function(err, response, body) {
|
||||
if(err || response.statusCode != 200) {
|
||||
self.emit('debug', 'Error logging into webchat: ' + (err ? err.message : "HTTP error " + response.statusCode));
|
||||
self.chatState = SteamCommunity.ChatState.LogOnFailed;
|
||||
setTimeout(self.chatLogon.bind(self), 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
if(body.error != 'OK') {
|
||||
self.emit('debug', 'Error logging into webchat: ' + body.error);
|
||||
self.chatState = SteamCommunity.ChatState.LogOnFailed;
|
||||
setTimeout(self.chatLogon.bind(self), 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
self._chat = {
|
||||
"umqid": body.umqid,
|
||||
"message": body.message,
|
||||
"accessToken": match[0],
|
||||
"interval": interval
|
||||
};
|
||||
|
||||
self.chatFriends = {};
|
||||
|
||||
self.chatState = SteamCommunity.ChatState.LoggedOn;
|
||||
self.emit('chatLoggedOn');
|
||||
self._chatPoll();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.chatMessage = function(recipient, text, type, callback) {
|
||||
if(this.chatState != SteamCommunity.ChatState.LoggedOn) {
|
||||
throw new Error("Chat must be logged on before messages can be sent");
|
||||
}
|
||||
|
||||
if(typeof recipient === 'string') {
|
||||
recipient = new SteamID(recipient);
|
||||
}
|
||||
|
||||
if(typeof type === 'function') {
|
||||
callback = type;
|
||||
type = 'saytext';
|
||||
}
|
||||
|
||||
type = type || 'saytext';
|
||||
|
||||
this.request.post({
|
||||
"uri": "https://api.steampowered.com/ISteamWebUserPresenceOAuth/Message/v1",
|
||||
"form": {
|
||||
"access_token": this._chat.accessToken,
|
||||
"steamid_dst": recipient.toString(),
|
||||
"text": text,
|
||||
"type": type,
|
||||
"umqid": this._chat.umqid
|
||||
},
|
||||
"json": true
|
||||
}, function(err, response, body) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(body.error != 'OK') {
|
||||
callback(new Error(body.error));
|
||||
} else {
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.chatLogoff = function() {
|
||||
var self = this;
|
||||
this.request.post({
|
||||
"uri": "https://api.steampowered.com/ISteamWebUserPresenceOAuth/Logoff/v1",
|
||||
"form": {
|
||||
"access_token": this._chat.accessToken,
|
||||
"umqid": this._chat.umqid
|
||||
}
|
||||
}, function(err, response, body) {
|
||||
if(err || response.statusCode != 200) {
|
||||
self.emit('debug', 'Error logging off of chat: ' + (err ? err.message : "HTTP error " + response.statusCode));
|
||||
setTimeout(self.chatLogoff.bind(self), 1000);
|
||||
} else {
|
||||
self.emit('chatLoggedOff');
|
||||
clearTimeout(self._chat.timer);
|
||||
delete self._chat;
|
||||
delete self.chatFriends;
|
||||
self.chatState = SteamCommunity.ChatState.Offline;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype._chatPoll = function() {
|
||||
this.emit('debug', 'Doing chat poll');
|
||||
|
||||
var self = this;
|
||||
this.request.post({
|
||||
"uri": "https://api.steampowered.com/ISteamWebUserPresenceOAuth/Poll/v1",
|
||||
"form": {
|
||||
"umqid": self._chat.umqid,
|
||||
"message": self._chat.message,
|
||||
"pollid": 1,
|
||||
"sectimeout": 20,
|
||||
"secidletime": 0,
|
||||
"use_accountids": 1,
|
||||
"access_token": self._chat.accessToken
|
||||
},
|
||||
"json": true
|
||||
}, function(err, response, body) {
|
||||
if(self.chatState == SteamCommunity.ChatState.Offline) {
|
||||
return;
|
||||
}
|
||||
|
||||
self._chat.timer = setTimeout(self._chatPoll.bind(self), self._chat.interval);
|
||||
|
||||
if(err || response.statusCode != 200) {
|
||||
self.emit('debug', 'Error in chat poll: ' + (err ? err.message : "HTTP error " + response.statusCode));
|
||||
return;
|
||||
}
|
||||
|
||||
if(body.error != 'OK') {
|
||||
self.emit('debug', 'Error in chat poll: ' + body.error);
|
||||
return;
|
||||
}
|
||||
|
||||
self._chat.message = body.messagelast;
|
||||
|
||||
(body.messages || []).forEach(function(message) {
|
||||
var sender = new SteamID();
|
||||
sender.universe = SteamID.Universe.PUBLIC;
|
||||
sender.type = SteamID.Type.INDIVIDUAL;
|
||||
sender.instance = SteamID.Instance.DESKTOP;
|
||||
sender.accountid = message.accountid_from;
|
||||
|
||||
switch(message.type) {
|
||||
case 'personastate':
|
||||
self._chatUpdatePersona(sender);
|
||||
break;
|
||||
|
||||
case 'saytext':
|
||||
self.emit('chatMessage', sender, message.text);
|
||||
break;
|
||||
|
||||
case 'typing':
|
||||
self.emit('chatTyping', sender);
|
||||
break;
|
||||
|
||||
default:
|
||||
self.emit('debug', 'Unhandled chat message type: ' + message.type);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype._chatUpdatePersona = function(steamID) {
|
||||
this.emit('debug', 'Updating persona data for ' + steamID);
|
||||
var self = this;
|
||||
this.request({
|
||||
"uri": "https://steamcommunity.com/chat/friendstate/" + steamID.accountid,
|
||||
"json": true
|
||||
}, function(err, response, body) {
|
||||
if(err || response.statusCode != 200) {
|
||||
self.emit('debug', 'Chat update persona error: ' + (err ? err.message : "HTTP error " + response.statusCode));
|
||||
setTimeout(function() {
|
||||
self._chatUpdatePersona(steamID);
|
||||
}, 2000);
|
||||
return;
|
||||
}
|
||||
|
||||
var persona = {
|
||||
"steamID": steamID,
|
||||
"personaName": body.m_strName,
|
||||
"personaState": body.m_ePersonaState,
|
||||
"personaStateFlags": body.m_nPersonaStateFlags || 0,
|
||||
"avatarHash": body.m_strAvatarHash,
|
||||
"inGame": !!body.m_bInGame,
|
||||
"inGameAppID": body.m_nInGameAppID ? parseInt(body.m_nInGameAppID, 10) : null,
|
||||
"inGameName": body.m_strInGameName || null
|
||||
};
|
||||
|
||||
self.emit('chatPersonaState', steamID, persona);
|
||||
self.chatFriends[steamID.getSteamID64()] = persona;
|
||||
});
|
||||
};
|
||||
386
components/groups.js
Normal file
386
components/groups.js
Normal file
@@ -0,0 +1,386 @@
|
||||
var SteamCommunity = require('../index.js');
|
||||
var SteamID = require('steamid');
|
||||
var xml2js = require('xml2js');
|
||||
var Cheerio = require('cheerio');
|
||||
|
||||
SteamCommunity.prototype.getGroupMembers = function(gid, callback, members, link, addresses, addressIdx) {
|
||||
members = members || [];
|
||||
|
||||
if (!link) {
|
||||
if (typeof gid !== 'string') {
|
||||
// It's a SteamID object
|
||||
link = "http://steamcommunity.com/gid/" + gid.toString() + "/memberslistxml/?xml=1";
|
||||
} else {
|
||||
try {
|
||||
var sid = new SteamID(gid);
|
||||
if (sid.type == SteamID.Type.CLAN && sid.isValid()) {
|
||||
link = "http://steamcommunity.com/gid/" + sid.getSteamID64() + "/memberslistxml/?xml=1";
|
||||
} else {
|
||||
throw new Error("Doesn't particularly matter what this message is");
|
||||
}
|
||||
} catch (e) {
|
||||
link = "http://steamcommunity.com/groups/" + gid + "/memberslistxml/?xml=1";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addressIdx = addressIdx || 0;
|
||||
|
||||
var options = {};
|
||||
options.uri = link;
|
||||
|
||||
if(addresses) {
|
||||
if(addressIdx >= addresses.length) {
|
||||
addressIdx = 0;
|
||||
}
|
||||
|
||||
options.localAddress = addresses[addressIdx];
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.request(options, function(err, response, body) {
|
||||
if (self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
xml2js.parseString(body, function(err, result) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
members = members.concat(result.memberList.members[0].steamID64.map(function(steamID) {
|
||||
return new SteamID(steamID);
|
||||
}));
|
||||
|
||||
if (result.memberList.nextPageLink) {
|
||||
addressIdx++;
|
||||
self.getGroupMembers(gid, callback, members, result.memberList.nextPageLink[0], addresses, addressIdx);
|
||||
} else {
|
||||
callback(null, members);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.getGroupMembersEx = function(gid, addresses, callback) {
|
||||
this.getGroupMembers(gid, callback, null, null, addresses, 0);
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.joinGroup = function(gid, callback) {
|
||||
if(typeof gid === 'string') {
|
||||
gid = new SteamID(gid);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.request.post({
|
||||
"uri": "https://steamcommunity.com/gid/" + gid.getSteamID64(),
|
||||
"form": {
|
||||
"action": "join",
|
||||
"sessionID": this.getSessionID()
|
||||
}
|
||||
}, function(err, response, body) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(err || response.statusCode >= 400) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
return;
|
||||
}
|
||||
|
||||
if(self._checkCommunityError(body, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null);
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.leaveGroup = function(gid, callback) {
|
||||
if(typeof gid === 'string') {
|
||||
gid = new SteamID(gid);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this._myProfile("home_process", {
|
||||
"sessionID": this.getSessionID(),
|
||||
"action": "leaveGroup",
|
||||
"groupId": gid.getSteamID64()
|
||||
}, function(err, response, body) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(err || response.statusCode >= 400) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
return;
|
||||
}
|
||||
|
||||
if(self._checkCommunityError(body, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null);
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.postGroupAnnouncement = function(gid, headline, content, callback) {
|
||||
if(typeof gid === 'string') {
|
||||
gid = new SteamID(gid);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.request.post({
|
||||
"uri": "https://steamcommunity.com/gid/" + gid.getSteamID64() + "/announcements",
|
||||
"form": {
|
||||
"sessionID": this.getSessionID(),
|
||||
"action": "post",
|
||||
"headline": headline,
|
||||
"body": content
|
||||
}
|
||||
}, function(err, response, body) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(err || response.statusCode >= 400) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
return;
|
||||
}
|
||||
|
||||
if(self._checkCommunityError(body, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null);
|
||||
})
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.scheduleGroupEvent = function(gid, name, type, description, time, server, callback) {
|
||||
if(typeof gid === 'string') {
|
||||
gid = new SteamID(gid);
|
||||
}
|
||||
|
||||
// Event types: ChatEvent - Chat, OtherEvent - A lil somethin somethin, PartyEvent - Party!, MeetingEvent - Important meeting, SpecialCauseEvent - Special cause (charity ball?), MusicAndArtsEvent - Music or Art type thing, SportsEvent - Sporting endeavor, TripEvent - Out of town excursion
|
||||
// Passing a number for type will make it a game event for that appid
|
||||
|
||||
if(typeof server === 'function') {
|
||||
callback = server;
|
||||
server = {"ip": "", "password": ""};
|
||||
} else if(typeof server === 'string') {
|
||||
server = {"ip": server, "password": ""};
|
||||
} else {
|
||||
server = {"ip": "", "password": ""};
|
||||
}
|
||||
|
||||
var form = {
|
||||
"sessionid": this.getSessionID(),
|
||||
"action": "newEvent",
|
||||
"tzOffset": new Date().getTimezoneOffset() * -60,
|
||||
"name": name,
|
||||
"type": (typeof type === 'number' || !isNaN(parseInt(type, 10)) ? "GameEvent" : type),
|
||||
"appID": (typeof type === 'number' || !isNaN(parseInt(type, 10)) ? type : ''),
|
||||
"serverIP": server.ip,
|
||||
"serverPassword": server.password,
|
||||
"notes": description,
|
||||
"eventQuickTime": "now"
|
||||
};
|
||||
|
||||
if(time === null) {
|
||||
form.startDate = 'MM/DD/YY';
|
||||
form.startHour = '12';
|
||||
form.startMinute = '00';
|
||||
form.startAMPM = 'PM';
|
||||
form.timeChoice = 'quick';
|
||||
} else {
|
||||
form.startDate = (time.getMonth() + 1 < 10 ? '0' : '') + (time.getMonth() + 1) + '/' + (time.getDate() < 10 ? '0' : '') + time.getDate() + '/' + time.getFullYear().toString().substring(2);
|
||||
form.startHour = (time.getHours() === 0 ? '12' : (time.getHours() > 12 ? time.getHours() - 12 : time.getHours()));
|
||||
form.startMinute = (time.getMinutes() < 10 ? '0' : '') + time.getMinutes();
|
||||
form.startAMPM = (time.getHours() <= 12 ? 'AM' : 'PM');
|
||||
form.timeChoice = 'specific';
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.request.post({
|
||||
"uri": "https://steamcommunity.com/gid/" + gid.toString() + "/eventEdit",
|
||||
"form": form
|
||||
}, function(err, response, body) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(err || response.statusCode >= 400) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
return;
|
||||
}
|
||||
|
||||
if(self._checkCommunityError(body, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null);
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.setGroupPlayerOfTheWeek = function(gid, steamID, callback) {
|
||||
if(typeof gid === 'string') {
|
||||
gid = new SteamID(gid);
|
||||
}
|
||||
|
||||
if(typeof steamID === 'string') {
|
||||
steamID = new SteamID(steamID);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.request.post({
|
||||
"uri": "https://steamcommunity.com/gid/" + gid.getSteamID64() + "/potwEdit",
|
||||
"form": {
|
||||
"xml": 1,
|
||||
"action": "potw",
|
||||
"memberId": steamID.getSteam3RenderedID(),
|
||||
"sessionid": this.getSessionID()
|
||||
}
|
||||
}, function(err, response, body) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(err || response.statusCode != 200) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
return;
|
||||
}
|
||||
|
||||
xml2js.parseString(body, function(err, results) {
|
||||
if(err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if(results.response.results[0] == 'OK') {
|
||||
callback(null, new SteamID(results.response.oldPOTW[0]), new SteamID(results.response.newPOTW[0]));
|
||||
} else {
|
||||
callback(new Error(results.response.results[0]));
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.kickGroupMember = function(gid, steamID, callback) {
|
||||
if(typeof gid === 'string') {
|
||||
gid = new SteamID(gid);
|
||||
}
|
||||
|
||||
if(typeof steamID === 'string') {
|
||||
steamID = new SteamID(steamID);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.request.post({
|
||||
"uri": "https://steamcommunity.com/gid/" + gid.getSteamID64() + "/membersManage",
|
||||
"form": {
|
||||
"sessionID": this.getSessionID(),
|
||||
"action": "kick",
|
||||
"memberId": steamID.getSteamID64(),
|
||||
"queryString": ""
|
||||
}
|
||||
}, function(err, response, body) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(err || response.statusCode >= 400) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
return;
|
||||
}
|
||||
|
||||
if(self._checkCommunityError(body, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null);
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.getGroupHistory = function(gid, page, callback) {
|
||||
if(typeof gid === 'string') {
|
||||
gid = new SteamID(gid);
|
||||
}
|
||||
|
||||
if(typeof page === 'function') {
|
||||
callback = page;
|
||||
page = 1;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.request("https://steamcommunity.com/gid/" + gid.getSteamID64() + "/history?p=" + page, function(err, response, body) {
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(self._checkCommunityError(body, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $ = Cheerio.load(body);
|
||||
var output = {};
|
||||
|
||||
var paging = $('.group_paging p').text();
|
||||
var match = paging.match(/(\d+) - (\d+) of (\d+)/);
|
||||
|
||||
if(match) {
|
||||
output.first = parseInt(match[1], 10);
|
||||
output.last = parseInt(match[2], 10);
|
||||
output.total = parseInt(match[3], 10);
|
||||
}
|
||||
|
||||
output.items = [];
|
||||
var currentYear = (new Date()).getFullYear();
|
||||
var lastDate = Date.now();
|
||||
|
||||
Array.prototype.forEach.call($('.historyItem, .historyItemb'), function(item) {
|
||||
var data = {};
|
||||
|
||||
var $item = $(item);
|
||||
data.type = $item.find('.historyShort').text().replace(/ /g, '');
|
||||
|
||||
var users = $item.find('.whiteLink[data-miniprofile]');
|
||||
var sid;
|
||||
if(users[0]) {
|
||||
sid = new SteamID();
|
||||
sid.universe = SteamID.Universe.PUBLIC;
|
||||
sid.type = SteamID.Type.INDIVIDUAL;
|
||||
sid.instance = SteamID.Instance.DESKTOP;
|
||||
sid.accountid = $(users[0]).data('miniprofile');
|
||||
data.user = sid;
|
||||
}
|
||||
|
||||
if(users[1]) {
|
||||
sid = new SteamID();
|
||||
sid.universe = SteamID.Universe.PUBLIC;
|
||||
sid.type = SteamID.Type.INDIVIDUAL;
|
||||
sid.instance = SteamID.Instance.DESKTOP;
|
||||
sid.accountid = $(users[0]).data('miniprofile');
|
||||
data.actor = sid;
|
||||
}
|
||||
|
||||
// Figure out the date. Of course there's no year, because Valve
|
||||
var dateParts = $item.find('.historyDate').text().split('@');
|
||||
var date = dateParts[0].trim().replace(/(st|nd|th)$/, '').trim() + ', ' + currentYear;
|
||||
var time = dateParts[1].trim().replace(/(am|pm)/, ' $1');
|
||||
|
||||
date = new Date(date + ' ' + time + ' UTC');
|
||||
|
||||
// If this date is in the future, or it's later than the previous one, decrement the year
|
||||
if(date.getTime() > lastDate) {
|
||||
date.setFullYear(date.getFullYear() - 1);
|
||||
}
|
||||
|
||||
data.date = date;
|
||||
|
||||
output.items.push(data);
|
||||
});
|
||||
|
||||
callback(null, output);
|
||||
});
|
||||
};
|
||||
141
components/inventoryhistory.js
Normal file
141
components/inventoryhistory.js
Normal file
@@ -0,0 +1,141 @@
|
||||
var SteamCommunity = require('../index.js');
|
||||
var CEconItem = require('../classes/CEconItem.js');
|
||||
var SteamID = require('steamid');
|
||||
var request = require('request');
|
||||
var Cheerio = require('cheerio');
|
||||
var Async = require('async');
|
||||
|
||||
SteamCommunity.prototype.getInventoryHistory = function(options, callback) {
|
||||
if(typeof options === 'function') {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
options.page = options.page || 1;
|
||||
|
||||
this.request("https://steamcommunity.com/my/inventoryhistory?l=english&p=" + options.page, function(err, response, body) {
|
||||
if(err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
var output = {};
|
||||
var vanityURLs = [];
|
||||
|
||||
var $ = Cheerio.load(body);
|
||||
var html = $('.inventory_history_pagingrow').html();
|
||||
if(!html) {
|
||||
callback("Malformed page: no paging row found");
|
||||
return;
|
||||
}
|
||||
|
||||
var match = html.match(/(\d+) - (\d+) of (\d+) History Items/);
|
||||
|
||||
output.first = parseInt(match[1], 10);
|
||||
output.last = parseInt(match[2], 10);
|
||||
output.totalTrades = parseInt(match[3], 10);
|
||||
|
||||
// Load the inventory item data
|
||||
var match2 = body.match(/var g_rgHistoryInventory = (.*);/);
|
||||
if(!match2) {
|
||||
callback(new Error("Malformed page: no trade found"));
|
||||
return;
|
||||
}
|
||||
var historyInventory = JSON.parse(match2[1]);
|
||||
|
||||
output.trades = [];
|
||||
var trades = $('.tradehistoryrow');
|
||||
|
||||
var item, trade, profileLink, items, j, econItem, timeMatch, time;
|
||||
for(var i = 0; i < trades.length; i++) {
|
||||
item = $(trades[i]);
|
||||
trade = {};
|
||||
|
||||
timeMatch = item.find('.tradehistory_timestamp').html().match(/(\d+):(\d+)(am|pm)/);
|
||||
if(timeMatch[1] == 12 && timeMatch[3] == 'am') {
|
||||
timeMatch[1] = 0;
|
||||
}
|
||||
|
||||
if(timeMatch[1] < 12 && timeMatch[3] == 'pm') {
|
||||
timeMatch[1] = parseInt(timeMatch[1], 10) + 12;
|
||||
}
|
||||
|
||||
time = (timeMatch[1] < 10 ? '0' : '') + timeMatch[1] + ':' + timeMatch[2] + ':00';
|
||||
|
||||
trade.date = new Date(item.find('.tradehistory_date').html() + ' ' + time);
|
||||
trade.partnerName = item.find('.tradehistory_event_description a').html();
|
||||
trade.partnerSteamID = null;
|
||||
trade.partnerVanityURL = null;
|
||||
trade.itemsReceived = [];
|
||||
trade.itemsGiven = [];
|
||||
|
||||
profileLink = item.find('.tradehistory_event_description a').attr('href');
|
||||
if(profileLink.indexOf('/profiles/') != -1) {
|
||||
trade.partnerSteamID = new SteamID(profileLink.match(/(\d+)$/)[1]);
|
||||
} else {
|
||||
trade.partnerVanityURL = profileLink.match(/\/([^\/]+)$/)[1];
|
||||
if(options.resolveVanityURLs && vanityURLs.indexOf(trade.partnerVanityURL) == -1) {
|
||||
vanityURLs.push(trade.partnerVanityURL);
|
||||
}
|
||||
}
|
||||
|
||||
items = item.find('.history_item');
|
||||
for(j = 0; j < items.length; j++) {
|
||||
match = body.match(new RegExp("HistoryPageCreateItemHover\\( '" + $(items[j]).attr('id') + "', (\\d+), '(\\d+)', '(\\d+)', '(\\d+)' \\);"));
|
||||
econItem = historyInventory[match[1]][match[2]][match[3]];
|
||||
|
||||
if($(items[j]).attr('id').indexOf('received') != -1) {
|
||||
trade.itemsReceived.push(new CEconItem(econItem));
|
||||
} else {
|
||||
trade.itemsGiven.push(new CEconItem(econItem));
|
||||
}
|
||||
}
|
||||
|
||||
output.trades.push(trade);
|
||||
}
|
||||
|
||||
if(options.resolveVanityURLs) {
|
||||
Async.map(vanityURLs, resolveVanityURL, function(err, results) {
|
||||
if(err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = 0; i < output.trades.length; i++) {
|
||||
if(output.trades[i].partnerSteamID || !output.trades[i].partnerVanityURL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find the vanity URL
|
||||
for(j = 0; j < results.length; j++) {
|
||||
if(results[j].vanityURL == output.trades[i].partnerVanityURL) {
|
||||
output.trades[i].partnerSteamID = new SteamID(results[j].steamID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callback(null, output);
|
||||
});
|
||||
} else {
|
||||
callback(null, output);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function resolveVanityURL(vanityURL, callback) {
|
||||
request("https://steamcommunity.com/id/" + vanityURL + "/?xml=1", function(err, response, body) {
|
||||
if(err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
var match = body.match(/<steamID64>(\d+)<\/steamID64>/);
|
||||
if(!match || !match[1]) {
|
||||
callback(new Error("Couldn't find Steam ID"));
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, {"vanityURL": vanityURL, "steamID": match[1]});
|
||||
});
|
||||
}
|
||||
25
components/market.js
Normal file
25
components/market.js
Normal file
@@ -0,0 +1,25 @@
|
||||
var SteamCommunity = require('../index.js');
|
||||
var Cheerio = require('cheerio');
|
||||
|
||||
SteamCommunity.prototype.getMarketApps = function(callback) {
|
||||
var self = this;
|
||||
this.request('https://steamcommunity.com/market/', function (err, response, body) {
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
var $ = Cheerio.load(body);
|
||||
if ($('.market_search_game_button_group')) {
|
||||
apps = {};
|
||||
$('.market_search_game_button_group > a').each(function (i, element) {
|
||||
var e = Cheerio.load(element);
|
||||
var name = e('.game_button_game_name').text().trim();
|
||||
var url = element.attribs.href;
|
||||
var appid = url.substr(url.indexOf('=') + 1);
|
||||
apps[appid] = name;
|
||||
});
|
||||
callback(null, apps);
|
||||
} else {
|
||||
callback(new Error("Malformed response"));
|
||||
}
|
||||
});
|
||||
}
|
||||
363
components/profile.js
Normal file
363
components/profile.js
Normal file
@@ -0,0 +1,363 @@
|
||||
var SteamCommunity = require('../index.js');
|
||||
var SteamID = require('steamid');
|
||||
var Cheerio = require('cheerio');
|
||||
var fs = require('fs');
|
||||
|
||||
SteamCommunity.PrivacyState = {
|
||||
"Private": 1,
|
||||
"FriendsOnly": 2,
|
||||
"Public": 3
|
||||
};
|
||||
|
||||
var CommentPrivacyState = {
|
||||
"1": "commentselfonly",
|
||||
"2": "commentfriendsonly",
|
||||
"3": "commentanyone"
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.setupProfile = function(callback) {
|
||||
var self = this;
|
||||
this._myProfile("edit?welcomed=1", null, function(err, response, body) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(err || response.statusCode != 200) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
} else {
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.editProfile = function(settings, callback) {
|
||||
var self = this;
|
||||
this._myProfile("edit", null, function(err, response, body) {
|
||||
if(err || response.statusCode != 200) {
|
||||
if(callback) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var $ = Cheerio.load(body);
|
||||
var form = $('#editForm');
|
||||
if(!form) {
|
||||
if(callback) {
|
||||
callback(new Error("Malformed response"));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var values = {};
|
||||
form.serializeArray().forEach(function(item) {
|
||||
values[item.name] = item.value;
|
||||
});
|
||||
|
||||
for(var i in settings) {
|
||||
if(!settings.hasOwnProperty(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(i) {
|
||||
case 'name':
|
||||
values.personaName = settings[i];
|
||||
break;
|
||||
|
||||
case 'realName':
|
||||
values.real_name = settings[i];
|
||||
break;
|
||||
|
||||
case 'summary':
|
||||
values.summary = settings[i];
|
||||
break;
|
||||
|
||||
case 'country':
|
||||
values.country = settings[i];
|
||||
break;
|
||||
|
||||
case 'state':
|
||||
values.state = settings[i];
|
||||
break;
|
||||
|
||||
case 'city':
|
||||
values.city = settings[i];
|
||||
break;
|
||||
|
||||
case 'customURL':
|
||||
values.customURL = settings[i];
|
||||
break;
|
||||
|
||||
case 'background':
|
||||
// The assetid of our desired profile background
|
||||
values.profile_background = settings[i];
|
||||
break;
|
||||
|
||||
case 'featuredBadge':
|
||||
// Currently, game badges aren't supported
|
||||
values.favorite_badge_badgeid = settings[i];
|
||||
break;
|
||||
|
||||
case 'primaryGroup':
|
||||
if(typeof settings[i] === 'object' && settings[i].getSteamID64) {
|
||||
values.primary_group_steamid = settings[i].getSteamID64();
|
||||
} else {
|
||||
values.primary_group_steamid = new SteamID(settings[i]).getSteamID64();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// TODO: profile showcases
|
||||
}
|
||||
}
|
||||
|
||||
self._myProfile("edit", values, function(err, response, body) {
|
||||
if(err || response.statusCode != 200) {
|
||||
if(callback) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for an error
|
||||
var $ = Cheerio.load(body);
|
||||
var error = $('#errorText .formRowFields');
|
||||
if(error) {
|
||||
error = error.text().trim();
|
||||
if(error) {
|
||||
if(callback) {
|
||||
callback(new Error(error));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(callback) {
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.profileSettings = function(settings, callback) {
|
||||
var self = this;
|
||||
this._myProfile("edit/settings", null, function(err, response, body) {
|
||||
if(err || response.statusCode != 200) {
|
||||
if(callback) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var $ = Cheerio.load(body);
|
||||
var form = $('#editForm');
|
||||
if(!form) {
|
||||
if(callback) {
|
||||
callback(new Error("Malformed response"));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var values = {};
|
||||
form.serializeArray().forEach(function(item) {
|
||||
values[item.name] = item.value;
|
||||
});
|
||||
|
||||
for(var i in settings) {
|
||||
if(!settings.hasOwnProperty(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(i) {
|
||||
case 'profile':
|
||||
values.privacySetting = settings[i];
|
||||
break;
|
||||
|
||||
case 'comments':
|
||||
values.commentSetting = CommentPrivacyState[settings[i]];
|
||||
break;
|
||||
|
||||
case 'inventory':
|
||||
values.inventoryPrivacySetting = settings[i];
|
||||
break;
|
||||
|
||||
case 'inventoryGifts':
|
||||
values.inventoryGiftPrivacy = settings[i] ? 1 : 0;
|
||||
break;
|
||||
|
||||
case 'emailConfirmation':
|
||||
values.tradeConfirmationSetting = settings[i] ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
self._myProfile("edit/settings", values, function(err, response, body) {
|
||||
if(err || response.statusCode != 200) {
|
||||
if(callback) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(callback) {
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.uploadAvatar = function(image, format, callback) {
|
||||
if(typeof format === 'function') {
|
||||
callback = format;
|
||||
format = null;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
|
||||
if(image instanceof Buffer) {
|
||||
doUpload(image);
|
||||
} else if(image.match(/^https?:\/\//)) {
|
||||
this.request.get({
|
||||
"uri": image,
|
||||
"encoding": null
|
||||
}, function(err, response, body) {
|
||||
if(err || response.statusCode != 200) {
|
||||
if(callback) {
|
||||
callback(err ? new Error(err.message + " downloading image") : new Error("HTTP error " + response.statusCode + " downloading image"));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(!format) {
|
||||
format = response.headers['content-type'];
|
||||
}
|
||||
|
||||
doUpload(body);
|
||||
})
|
||||
} else {
|
||||
if(!format) {
|
||||
format = image.match(/\.([^\.]+)$/);
|
||||
if(format) {
|
||||
format = format[1];
|
||||
}
|
||||
}
|
||||
|
||||
fs.readFile(image, function(err, file) {
|
||||
if(err) {
|
||||
if(callback) {
|
||||
callback(err);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
doUpload(file);
|
||||
})
|
||||
}
|
||||
|
||||
function doUpload(buffer) {
|
||||
if(!format) {
|
||||
if(callback) {
|
||||
callback(new Error("Unknown image format"));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(format.match(/^image\//)) {
|
||||
format = format.substring(6);
|
||||
}
|
||||
|
||||
var filename = '';
|
||||
var contentType = '';
|
||||
|
||||
switch(format.toLowerCase()) {
|
||||
case 'jpg':
|
||||
case 'jpeg':
|
||||
filename = 'avatar.jpg';
|
||||
contentType = 'image/jpeg';
|
||||
break;
|
||||
|
||||
case 'png':
|
||||
filename = 'avatar.png';
|
||||
contentType = 'image/png';
|
||||
break;
|
||||
|
||||
case 'gif':
|
||||
filename = 'avatar.gif';
|
||||
contentType = 'image/gif';
|
||||
break;
|
||||
|
||||
default:
|
||||
if(callback) {
|
||||
callback(new Error("Unknown or invalid image format"));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self.request.post({
|
||||
"uri": "https://steamcommunity.com/actions/FileUploader",
|
||||
"formData": {
|
||||
"MAX_FILE_SIZE": buffer.length,
|
||||
"type": "player_avatar_image",
|
||||
"sId": self.steamID.getSteamID64(),
|
||||
"sessionid": self.getSessionID(),
|
||||
"doSub": 1,
|
||||
"json": 1,
|
||||
"avatar": {
|
||||
"value": buffer,
|
||||
"options": {
|
||||
"filename": filename,
|
||||
"contentType": contentType
|
||||
}
|
||||
}
|
||||
},
|
||||
"json": true
|
||||
}, function(err, response, body) {
|
||||
if(err) {
|
||||
if(callback) {
|
||||
callback(err);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(body && !body.success && body.message) {
|
||||
if(callback) {
|
||||
callback(new Error(body.message));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(response.statusCode != 200) {
|
||||
if(callback) {
|
||||
callback(new Error("HTTP error " + response.statusCode));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(!body || !body.success) {
|
||||
if(callback) {
|
||||
callback(new Error("Malformed response"));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(callback) {
|
||||
callback(null, body.images.full);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
298
components/users.js
Normal file
298
components/users.js
Normal file
@@ -0,0 +1,298 @@
|
||||
var SteamCommunity = require('../index.js');
|
||||
var SteamID = require('steamid');
|
||||
var CEconItem = require('../classes/CEconItem.js');
|
||||
|
||||
SteamCommunity.prototype.addFriend = function(userID, callback) {
|
||||
if(typeof userID === 'string') {
|
||||
userID = new SteamID(userID);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.request.post({
|
||||
"uri": "https://steamcommunity.com/actions/AddFriendAjax",
|
||||
"form": {
|
||||
"accept_invite": 0,
|
||||
"sessionID": this.getSessionID(),
|
||||
"steamid": userID.toString()
|
||||
},
|
||||
"json": true
|
||||
}, function(err, response, body) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(body.success) {
|
||||
callback(null);
|
||||
} else {
|
||||
callback(new Error("Unknown error"));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.acceptFriendRequest = function(userID, callback) {
|
||||
if(typeof userID === 'string') {
|
||||
userID = new SteamID(userID);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.request.post({
|
||||
"uri": "https://steamcommunity.com/actions/AddFriendAjax",
|
||||
"form": {
|
||||
"accept_invite": 1,
|
||||
"sessionID": this.getSessionID(),
|
||||
"steamid": userID.toString()
|
||||
}
|
||||
}, function(err, response, body) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null);
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.removeFriend = function(userID, callback) {
|
||||
if(typeof userID === 'string') {
|
||||
userID = new SteamID(userID);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.request.post({
|
||||
"uri": "https://steamcommunity.com/actions/RemoveFriendAjax",
|
||||
"form": {
|
||||
"sessionID": this.getSessionID(),
|
||||
"steamid": userID.toString()
|
||||
}
|
||||
}, function(err, response, body) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null);
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.blockCommunication = function(userID, callback) {
|
||||
if(typeof userID === 'string') {
|
||||
userID = new SteamID(userID);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.request.post({
|
||||
"uri": "https://steamcommunity.com/actions/BlockUserAjax",
|
||||
"form": {
|
||||
"sessionID": this.getSessionID(),
|
||||
"steamid": userID.toString()
|
||||
}
|
||||
}, function(err, response, body) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null);
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.unblockCommunication = function(userID, callback) {
|
||||
if(typeof userID === 'string') {
|
||||
userID = new SteamID(userID);
|
||||
}
|
||||
|
||||
var form = {"action": "unignore"};
|
||||
form['friends[' + userID.toString() + ']'] = 1;
|
||||
|
||||
this._myProfile('friends/blocked/', form, function(err, response, body) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(err || response.statusCode >= 400) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null);
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.postUserComment = function(userID, message, callback) {
|
||||
if(typeof userID === 'string') {
|
||||
userID = new SteamID(userID);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.request.post({
|
||||
"uri": "https://steamcommunity.com/comment/Profile/post/" + userID.toString() + "/-1",
|
||||
"form": {
|
||||
"comment": message,
|
||||
"count": 6,
|
||||
"sessionid": this.getSessionID()
|
||||
},
|
||||
"json": true
|
||||
}, function(err, response, body) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(body.success) {
|
||||
callback(null);
|
||||
} else if(bpdy.error) {
|
||||
callback(new Error(body.error));
|
||||
} else {
|
||||
callback(new Error("Unknown error"));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.inviteUserToGroup = function(userID, groupID, callback) {
|
||||
if(typeof userID === 'string') {
|
||||
userID = new SteamID(userID);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.request.post({
|
||||
"uri": "https://steamcommunity.com/actions/GroupInvite",
|
||||
"form": {
|
||||
"group": groupID.toString(),
|
||||
"invitee": userID.toString(),
|
||||
"json": 1,
|
||||
"sessionID": this.getSessionID(),
|
||||
"type": "groupInvite"
|
||||
},
|
||||
"json": true
|
||||
}, function(err, response, body) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(body.results == 'OK') {
|
||||
callback(null);
|
||||
} else if(body.results) {
|
||||
callback(new Error(body.results));
|
||||
} else {
|
||||
callback(new Error("Unknown error"));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.getUserInventoryContexts = function(userID, callback) {
|
||||
if(typeof userID === 'string') {
|
||||
userID = new SteamID(userID);
|
||||
}
|
||||
|
||||
if(typeof userID === 'function') {
|
||||
callback = userID;
|
||||
userID = this.steamID;
|
||||
}
|
||||
|
||||
if(!userID) {
|
||||
callback(new Error("No SteamID specified and not logged in"));
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.request("https://steamcommunity.com/profiles/" + userID.getSteamID64() + "/inventory/", function(err, response, body) {
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var match = body.match(/var g_rgAppContextData = ([^\n]+);\r?\n/);
|
||||
if(!match) {
|
||||
callback(new Error("Malformed response"));
|
||||
return;
|
||||
}
|
||||
|
||||
var data;
|
||||
try {
|
||||
data = JSON.parse(match[1]);
|
||||
} catch(e) {
|
||||
callback(new Error("Malformed response"));
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, data);
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.getUserInventory = function(userID, appID, contextID, tradableOnly, callback) {
|
||||
var self = this;
|
||||
|
||||
if(typeof userID === 'string') {
|
||||
userID = new SteamID(userID);
|
||||
}
|
||||
|
||||
var endpoint = "/profiles/" + userID.getSteamID64();
|
||||
get([], []);
|
||||
|
||||
function get(inventory, currency, start) {
|
||||
self.request({
|
||||
"uri": "https://steamcommunity.com" + endpoint + "/inventory/json/" + appID + "/" + contextID,
|
||||
"qs": {
|
||||
"start": start,
|
||||
"trading": tradableOnly ? 1 : undefined
|
||||
},
|
||||
"json": true
|
||||
}, function(err, response, body) {
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!body || !body.success || !body.rgInventory || !body.rgDescriptions || !body.rgCurrency) {
|
||||
callback(new Error(body.Error || "Malformed response"));
|
||||
return;
|
||||
}
|
||||
|
||||
var i;
|
||||
for(i in body.rgInventory) {
|
||||
if(!body.rgInventory.hasOwnProperty(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
inventory.push(new CEconItem(body.rgInventory[i], body.rgDescriptions, contextID));
|
||||
}
|
||||
|
||||
for(i in body.rgCurrency) {
|
||||
if(!body.rgCurrency.hasOwnProperty(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
currency.push(new CEconItem(body.rgInventory[i], body.rgDescriptions, contextID));
|
||||
}
|
||||
|
||||
if(body.more) {
|
||||
var match = response.request.uri.href.match(/\/(profiles|id)\/([^\/]+)\//);
|
||||
if(match) {
|
||||
endpoint = "/" + match[1] + "/" + match[2];
|
||||
}
|
||||
|
||||
get(inventory, currency, body.more_start);
|
||||
} else {
|
||||
callback(null, inventory, currency);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
358
index.js
358
index.js
@@ -1,33 +1,41 @@
|
||||
var Request = require('request');
|
||||
var RSA = require('node-bignumber').Key;
|
||||
var hex2b64 = require('node-bignumber').hex2b64;
|
||||
var SteamID = require('steamid');
|
||||
|
||||
require('util').inherits(SteamCommunity, require('events').EventEmitter);
|
||||
|
||||
module.exports = SteamCommunity;
|
||||
|
||||
function SteamCommunity(username, password, steamID, machineAuth) {
|
||||
this._username = username;
|
||||
this._password = password;
|
||||
this._steamID = steamID;
|
||||
this._sentry = machineAuth;
|
||||
SteamCommunity.SteamID = SteamID;
|
||||
|
||||
function SteamCommunity(localAddress) {
|
||||
this._jar = Request.jar();
|
||||
this._captchaGid = -1;
|
||||
this.chatState = SteamCommunity.ChatState.Offline;
|
||||
|
||||
var defaults = {"jar": this._jar, "timeout": 50000};
|
||||
if(localAddress) {
|
||||
defaults.localAddress = localAddress;
|
||||
}
|
||||
|
||||
this.request = Request.defaults(defaults);
|
||||
|
||||
// English
|
||||
this._jar.setCookie(Request.cookie('Steam_Language=english'), 'https://steamcommunity.com');
|
||||
|
||||
// UTC
|
||||
this._jar.setCookie(Request.cookie('timezoneOffset=0,0'), 'https://steamcommunity.com');
|
||||
}
|
||||
|
||||
SteamCommunity.prototype.login = function(authCode, callback) {
|
||||
if(typeof authCode === 'function') {
|
||||
callback = authCode;
|
||||
authCode = "";
|
||||
}
|
||||
|
||||
var request;
|
||||
if(this._steamID && this._sentry) {
|
||||
var jar = Request.jar();
|
||||
request = Request.defaults({"jar": jar});
|
||||
jar.setCookieSync(Request.cookie('steamMachineAuth' + this._steamID + '=' + this._sentry), 'https://steamcommunity.com');
|
||||
} else {
|
||||
request = Request;
|
||||
SteamCommunity.prototype.login = function(details, callback) {
|
||||
if(details.steamguard) {
|
||||
var parts = details.steamguard.split('||');
|
||||
this._jar.setCookie(Request.cookie('steamMachineAuth' + parts[0] + '=' + encodeURIComponent(parts[1])), 'https://steamcommunity.com');
|
||||
}
|
||||
|
||||
var self = this;
|
||||
request.post("https://steamcommunity.com/login/getrsakey/", {"form": {"username": this._username}}, function(err, response, body) {
|
||||
this.request.post("https://steamcommunity.com/login/getrsakey/", {"form": {"username": details.accountName}}, function(err, response, body) {
|
||||
if(err) {
|
||||
callback(err);
|
||||
return;
|
||||
@@ -45,64 +53,286 @@ SteamCommunity.prototype.login = function(authCode, callback) {
|
||||
key.setPublic(json.publickey_mod, json.publickey_exp);
|
||||
|
||||
var form = {
|
||||
"captcha_text": "",
|
||||
"captchagid": -1,
|
||||
"emailauth": authCode || "",
|
||||
"captcha_text": details.captcha || "",
|
||||
"captchagid": self._captchaGid,
|
||||
"emailauth": details.authCode || "",
|
||||
"emailsteamid": "",
|
||||
"loginfriendlyname": "",
|
||||
"password": hex2b64(key.encrypt(self._password)),
|
||||
"remember_login": false,
|
||||
"password": hex2b64(key.encrypt(details.password)),
|
||||
"remember_login": "true",
|
||||
"rsatimestamp": json.timestamp,
|
||||
"twofactorcode": "",
|
||||
"username": self._username
|
||||
"twofactorcode": details.twoFactorCode || "",
|
||||
"username": details.accountName
|
||||
};
|
||||
|
||||
request.post("https://steamcommunity.com/login/dologin/", {"form": form}, function(err, response, body) {
|
||||
if(err) {
|
||||
callback(err);
|
||||
self.request.post({
|
||||
"uri": "https://steamcommunity.com/login/dologin/",
|
||||
"json": true,
|
||||
"form": form
|
||||
}, function(err, response, body) {
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var json;
|
||||
try {
|
||||
json = JSON.parse(body);
|
||||
} catch(e) {
|
||||
callback(e);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!json.success) {
|
||||
callback(json.message);
|
||||
if(!body.success && body.emailauth_needed) {
|
||||
// Steam Guard (email)
|
||||
var error = new Error("SteamGuard");
|
||||
error.emaildomain = body.emaildomain;
|
||||
|
||||
callback(error);
|
||||
} else if(!body.success && body.requires_twofactor) {
|
||||
// Steam Guard (app)
|
||||
callback(new Error("SteamGuardMobile"));
|
||||
} else if(!body.success && body.captcha_needed) {
|
||||
var error = new Error("CAPTCHA");
|
||||
error.captchaurl = "https://steamcommunity.com/public/captcha.php?gid=" + body.captcha_gid;
|
||||
|
||||
self._captchaGid = body.captcha_gid;
|
||||
|
||||
callback(error);
|
||||
} else if(!body.success) {
|
||||
callback(new Error(body.message || "Unknown error"));
|
||||
} else {
|
||||
var cookies = [];
|
||||
for(var i = 0; i < response.headers['set-cookie'].length; i++) {
|
||||
var header = response.headers['set-cookie'][i];
|
||||
var pos = header.indexOf(';');
|
||||
if(pos != -1) {
|
||||
header = header.substring(0, pos);
|
||||
var sessionID = generateSessionID();
|
||||
self._jar.setCookie(Request.cookie('sessionid=' + sessionID), 'http://steamcommunity.com');
|
||||
|
||||
self.steamID = new SteamID(body.transfer_parameters.steamid);
|
||||
var cookies = self._jar.getCookieString("https://steamcommunity.com").split(';').map(function(cookie) {
|
||||
return cookie.trim();
|
||||
});
|
||||
|
||||
// Find the Steam Guard cookie
|
||||
var steamguard = null;
|
||||
for(var i = 0; i < cookies.length; i++) {
|
||||
var parts = cookies[i].split('=');
|
||||
if(parts[0] == 'steamMachineAuth' + self.steamID) {
|
||||
steamguard = self.steamID.toString() + '||' + decodeURIComponent(parts[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
cookies.push(header);
|
||||
}
|
||||
|
||||
var sessionID = Math.floor(Math.random() * 1000000000);
|
||||
cookies.push('sessionid=' + sessionID);
|
||||
|
||||
if(self._steamID && self._sentry) {
|
||||
cookies.push('steamMachineAuth' + self._steamID + '=' + self._sentry);
|
||||
}
|
||||
|
||||
var steamguard = {};
|
||||
if(json.transfer_parameters.steamid && json.transfer_parameters.webcookie) {
|
||||
steamguard.steamID = json.transfer_parameters.steamid;
|
||||
steamguard.machineAuth = json.transfer_parameters.webcookie;
|
||||
|
||||
self._steamID = steamguard.steamID;
|
||||
self._sentry = steamguard.machineAuth;
|
||||
}
|
||||
|
||||
callback(null, sessionID, cookies, steamguard);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.setCookies = function(cookies) {
|
||||
var self = this;
|
||||
cookies.forEach(function(cookie) {
|
||||
var cookieName = cookie.match(/(.+)=/)[1];
|
||||
if(cookieName == 'steamLogin') {
|
||||
self.steamID = new SteamID(cookie.match(/=(\d+)/)[1]);
|
||||
}
|
||||
|
||||
self._jar.setCookie(Request.cookie(cookie), (cookieName.match(/^steamMachineAuth/) || cookieName.match(/Secure$/) ? "https://" : "http://") + "steamcommunity.com");
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.getSessionID = function() {
|
||||
var cookies = this._jar.getCookieString("http://steamcommunity.com").split(';');
|
||||
for(var i = 0; i < cookies.length; i++) {
|
||||
var match = cookies[i].trim().match(/([^=]+)=(.+)/);
|
||||
if(match[1] == 'sessionid') {
|
||||
return decodeURIComponent(match[2]);
|
||||
}
|
||||
}
|
||||
|
||||
var sessionID = generateSessionID();
|
||||
this._jar.setCookie(Request.cookie('sessionid=' + sessionID), "http://steamcommunity.com");
|
||||
return sessionID;
|
||||
};
|
||||
|
||||
function generateSessionID() {
|
||||
return Math.floor(Math.random() * 1000000000);
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.getWebApiKey = function(domain, callback) {
|
||||
var self = this;
|
||||
this.request({
|
||||
"uri": "https://steamcommunity.com/dev/apikey",
|
||||
"followRedirect": false
|
||||
}, function(err, response, body) {
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(body.match(/<h2>Access Denied<\/h2>/)) {
|
||||
return callback(new Error("Access Denied"));
|
||||
}
|
||||
|
||||
var match = body.match(/<p>Key: ([0-9A-F]+)<\/p>/);
|
||||
if(match) {
|
||||
// We already have an API key registered
|
||||
callback(null, match[1]);
|
||||
} else {
|
||||
// We need to register a new API key
|
||||
self.request.post('https://steamcommunity.com/dev/registerkey', {
|
||||
"form": {
|
||||
"domain": domain,
|
||||
"agreeToTerms": "agreed",
|
||||
"sessionid": self.getSessionID(),
|
||||
"Submit": "Register"
|
||||
}
|
||||
}, function(err, response, body) {
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.getWebApiKey(domain, callback);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.parentalUnlock = function(pin, callback) {
|
||||
this.request.post("https://steamcommunity.com/parental/ajaxunlock", {
|
||||
"json": true,
|
||||
"form": {
|
||||
"pin": pin
|
||||
}
|
||||
}, function(err, response, body) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!body || typeof body.success !== 'boolean') {
|
||||
return callback("Invalid response");
|
||||
}
|
||||
|
||||
if(!body.success) {
|
||||
return callback("Incorrect PIN");
|
||||
}
|
||||
|
||||
callback();
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.getNotifications = function(callback) {
|
||||
this.request.get("https://steamcommunity.com/actions/RefreshNotificationArea", function(err, response, body) {
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var notifications = {
|
||||
"comments": 0,
|
||||
"items": 0,
|
||||
"invites": 0,
|
||||
"gifts": 0,
|
||||
"chat": 0,
|
||||
"trades": 0
|
||||
};
|
||||
|
||||
var items = {
|
||||
"comments": /(\d+) new comments?/,
|
||||
"items": /(\d+) new items? in your inventory/,
|
||||
"invites": /(\d+) new invites?/,
|
||||
"gifts": /(\d+) new gifts?/,
|
||||
"chat": /(\d+) unread chat messages?/,
|
||||
"trades": /(\d+) new trade notifications?/
|
||||
};
|
||||
|
||||
var match;
|
||||
for(var i in items) {
|
||||
if(match = body.match(items[i])) {
|
||||
notifications[i] = parseInt(match[1], 10);
|
||||
}
|
||||
}
|
||||
|
||||
callback(null, notifications);
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.resetItemNotifications = function(callback) {
|
||||
this.request.get("https://steamcommunity.com/my/inventory", function(err, response, body) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null);
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.loggedIn = function(callback) {
|
||||
this.request("https://steamcommunity.com/my", {"followRedirect": false}, function(err, response, body) {
|
||||
if(err || (response.statusCode != 302 && response.statusCode != 403)) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
return;
|
||||
}
|
||||
|
||||
if(response.statusCode == 403) {
|
||||
callback(null, true, true);
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, !!response.headers.location.match(/steamcommunity\.com(\/(id|profiles)\/[^\/]+)\/?/), false);
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype._checkCommunityError = function(html, callback) {
|
||||
if(html.match(/<h1>Sorry!<\/h1>/)) {
|
||||
var match = html.match(/<h3>(.+)<\/h3>/);
|
||||
callback(new Error(match ? match[1] : "Unknown error occurred"));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
SteamCommunity.prototype._myProfile = function(endpoint, form, callback) {
|
||||
var self = this;
|
||||
this.request("https://steamcommunity.com/my", {"followRedirect": false}, function(err, response, body) {
|
||||
if(err || response.statusCode != 302) {
|
||||
callback(err || "HTTP error " + response.statusCode);
|
||||
return;
|
||||
}
|
||||
|
||||
var match = response.headers.location.match(/steamcommunity\.com(\/(id|profiles)\/[^\/]+)\/?/);
|
||||
if(!match) {
|
||||
callback("Can't get profile URL");
|
||||
return;
|
||||
}
|
||||
|
||||
(form ? self.request.post : self.request)("https://steamcommunity.com" + match[1] + "/" + endpoint, form ? {"form": form} : {}, callback);
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype._checkHttpError = function(err, response, callback) {
|
||||
if(err) {
|
||||
callback(err);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(response.statusCode >= 300 && response.statusCode <= 399 && response.headers.location.indexOf('/login') != -1) {
|
||||
callback(new Error("Not Logged In"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if(response.statusCode >= 400) {
|
||||
var error = new Error("HTTP error " + response.statusCode);
|
||||
error.code = response.statusCode;
|
||||
callback(error);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
require('./components/chat.js');
|
||||
require('./components/profile.js');
|
||||
require('./components/market.js');
|
||||
require('./components/groups.js');
|
||||
require('./components/users.js');
|
||||
require('./components/inventoryhistory.js');
|
||||
require('./classes/CMarketItem.js');
|
||||
require('./classes/CMarketSearchResult.js');
|
||||
require('./classes/CSteamGroup.js');
|
||||
require('./classes/CSteamUser.js');
|
||||
|
||||
14
package.json
14
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "steamcommunity",
|
||||
"version": "0.1.0",
|
||||
"description": "Facilitates logins to the Steam Communtiy website",
|
||||
"version": "3.9.8",
|
||||
"description": "Provides an interface for logging into and interacting with the Steam Community website",
|
||||
"keywords": ["steam", "steam community"],
|
||||
"homepage": "https://github.com/DoctorMcKay/node-steamcommunity",
|
||||
"bugs": {
|
||||
@@ -10,10 +10,14 @@
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Doctor_McKay/node-steamcommunity.git"
|
||||
"url": "https://github.com/DoctorMcKay/node-steamcommunity.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"request": "2.44.x",
|
||||
"node-bignumber": "1.2.x"
|
||||
"request": "^2.61.0",
|
||||
"node-bignumber": "^1.2.1",
|
||||
"steamid": "^0.3.1",
|
||||
"xml2js": "^0.4.11",
|
||||
"cheerio": "^0.19.0",
|
||||
"async": "^1.4.2"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user