steampy icon indicating copy to clipboard operation
steampy copied to clipboard

Does anyone have problems with the API method GetTradeOffers

Open xidios opened this issue 1 year ago • 20 comments

{"response":{"next_cursor":0}} I get empty messages when I try to request all trade offers

xidios avatar Apr 03 '24 11:04 xidios

me too...

crab713 avatar Apr 03 '24 11:04 crab713

+1

maybe this is the steam problem?

BestNathan avatar Apr 03 '24 11:04 BestNathan

+1

maybe this is the steam problem?

Yes, this is steam problem, but mb someone know how to fix it?

xidios avatar Apr 03 '24 12:04 xidios

I saw that Steam released a new update that affected scam projects and other skin exchange sites like market csgo

nikitabiz avatar Apr 03 '24 12:04 nikitabiz

Maybe it doesn't work anymore.

nikitabiz avatar Apr 03 '24 12:04 nikitabiz

This solution can temporarily serve as a substitute, looking forward to other's solution.

def get_all_trade_offer_id(steam_client: SteamClient) -> List[dict]:
        steam_id = steam_client.get_steam_id()
        response  = steam_client._session.get('https://steamcommunity.com/profiles/{}/tradeoffers/'.format(steam_id))
        soup = BeautifulSoup(response.text, 'html.parser')
        trade_offer_soup_list = soup.find_all('div', class_='tradeoffer')
        result_list = []
        for trade_offer_soup in trade_offer_soup_list:
            if 'Trade Accepted' in trade_offer_soup.text or 'Trade Cancel' in trade_offer_soup.text:
                continue
            tradeoffer_item_lists = trade_offer_soup.find_all('div', class_='tradeoffer_item_list')
            trade_item_length = []
            for i, tradeoffer_item_list in enumerate(tradeoffer_item_lists, 1):
                trade_items = tradeoffer_item_list.find_all('div', class_='trade_item')
                trade_item_length.append(len(trade_items))
            trade = {
                "trade_id": trade_offer_soup['id'].split('_')[1],
                "receive_num": trade_item_length[0],
                "send_num": trade_item_length[1]
            }
            result_list.append(trade)
        return result_list

crab713 avatar Apr 03 '24 13:04 crab713

This solution can temporarily serve as a substitute, looking forward to other's solution.

def get_all_trade_offer_id(steam_client: SteamClient) -> List[dict]:
        steam_id = steam_client.get_steam_id()
        response  = steam_client._session.get('https://steamcommunity.com/profiles/{}/tradeoffers/'.format(steam_id))
        soup = BeautifulSoup(response.text, 'html.parser')
        trade_offer_soup_list = soup.find_all('div', class_='tradeoffer')
        result_list = []
        for trade_offer_soup in trade_offer_soup_list:
            if 'Trade Accepted' in trade_offer_soup.text or 'Trade Cancel' in trade_offer_soup.text:
                continue
            tradeoffer_item_lists = trade_offer_soup.find_all('div', class_='tradeoffer_item_list')
            trade_item_length = []
            for i, tradeoffer_item_list in enumerate(tradeoffer_item_lists, 1):
                trade_items = tradeoffer_item_list.find_all('div', class_='trade_item')
                trade_item_length.append(len(trade_items))
            trade = {
                "trade_id": trade_offer_soup['id'].split('_')[1],
                "receive_num": trade_item_length[0],
                "send_num": trade_item_length[1]
            }
            result_list.append(trade)
        return result_list

ty for code, do you have any idea how to parse the description of an item?

xidios avatar Apr 03 '24 14:04 xidios

I've done it completely, I can share it with anyone who needs it.

nikitabiz avatar Apr 03 '24 15:04 nikitabiz

I've done it completely, I can share it with anyone who needs it.

please,need it.

crab713 avatar Apr 03 '24 15:04 crab713

I've done it completely, I can share it with anyone who needs it.

using profile or api ?

BestNathan avatar Apr 03 '24 16:04 BestNathan

Here he is)

def get_all_trade_offer_id(self):
    steam_id = self.get_steam_id()
    response = self._session.get('https://steamcommunity.com/profiles/{}/tradeoffers/'.format(steam_id))
    soup = BeautifulSoup(response.text, 'html.parser')
    trade_offer_list = soup.find_all('div', class_='tradeoffer')
    if not trade_offer_list:
        return False

    result_trade_offers_list = []

    for trade_offer in trade_offer_list:
        trade_offer_status = 2
        trade_offer_id = trade_offer['id'].split('_')[1]

        if 'Trade Accepted' in trade_offer.text or 'Trade Cancel' in trade_offer.text:
            trade_offer_status = 0

        tradeoffer_item_lists = trade_offer.find_all('div', class_='tradeoffer_item_list')
        check_items_cs2 = False
        items_class = []
        trade_items_length = []

        for i, tradeoffer_item_list in enumerate(tradeoffer_item_lists, 1):
            trade_items = tradeoffer_item_list.find_all('div', class_='trade_item')
            trade_items_length.append(len(trade_items))

            for item in trade_items:
                data_economy_item = item['data-economy-item']
                values = data_economy_item.split('/')

                items_class.append(values[2])
                check_items_cs2 = True if int(values[1]) == 730 else False

        trade_app_id = 730 if check_items_cs2 else 0
        len_trade_items_to_receive = trade_items_length[0]
        len_trade_items_to_give = trade_items_length[1]

        trade_items_to_receive = {}
        if trade_app_id == 730:
            for item in items_class:
                url = f'http://api.steampowered.com/ISteamEconomy/GetAssetClassInfo/v1?key={self._api_key}&format=json&appid=730&class_count=1&classid0={item}'
                data = self._session.get(url).json()

                icon_url = data['result'][str(item)]['icon_url']
                market_hash_name = data['result'][str(item)]['market_hash_name']

                trade_items_to_receive[f"{item}"] = {
                    "icon_url": icon_url,
                    "market_hash_name": market_hash_name
                }

        trade = {
            "tradeofferid": trade_offer_id,
            "trade_offer_state": trade_offer_status,
            "items_to_receive": trade_items_to_receive,
            "appid": trade_app_id,
            "items_to_give": len_trade_items_to_give
        }
        result_trade_offers_list.append(trade)

    return result_trade_offers_list

nikitabiz avatar Apr 03 '24 16:04 nikitabiz

Redo my code for yourself, because I only need partner items, and only skins from CS2

nikitabiz avatar Apr 03 '24 16:04 nikitabiz

in the trade dictionary, you can see what my code can get from the trade

nikitabiz avatar Apr 03 '24 16:04 nikitabiz

Here he is)

def get_all_trade_offer_id(self):
    steam_id = self.get_steam_id()
    response = self._session.get('https://steamcommunity.com/profiles/{}/tradeoffers/'.format(steam_id))
    soup = BeautifulSoup(response.text, 'html.parser')
    trade_offer_list = soup.find_all('div', class_='tradeoffer')
    if not trade_offer_list:
        return False

    result_trade_offers_list = []

    for trade_offer in trade_offer_list:
        trade_offer_status = 2
        trade_offer_id = trade_offer['id'].split('_')[1]

        if 'Trade Accepted' in trade_offer.text or 'Trade Cancel' in trade_offer.text:
            trade_offer_status = 0

        tradeoffer_item_lists = trade_offer.find_all('div', class_='tradeoffer_item_list')
        check_items_cs2 = False
        items_class = []
        trade_items_length = []

        for i, tradeoffer_item_list in enumerate(tradeoffer_item_lists, 1):
            trade_items = tradeoffer_item_list.find_all('div', class_='trade_item')
            trade_items_length.append(len(trade_items))

            for item in trade_items:
                data_economy_item = item['data-economy-item']
                values = data_economy_item.split('/')

                items_class.append(values[2])
                check_items_cs2 = True if int(values[1]) == 730 else False

        trade_app_id = 730 if check_items_cs2 else 0
        len_trade_items_to_receive = trade_items_length[0]
        len_trade_items_to_give = trade_items_length[1]

        trade_items_to_receive = {}
        if trade_app_id == 730:
            for item in items_class:
                url = f'http://api.steampowered.com/ISteamEconomy/GetAssetClassInfo/v1?key={self._api_key}&format=json&appid=730&class_count=1&classid0={item}'
                data = self._session.get(url).json()

                icon_url = data['result'][str(item)]['icon_url']
                market_hash_name = data['result'][str(item)]['market_hash_name']

                trade_items_to_receive[f"{item}"] = {
                    "icon_url": icon_url,
                    "market_hash_name": market_hash_name
                }

        trade = {
            "tradeofferid": trade_offer_id,
            "trade_offer_state": trade_offer_status,
            "items_to_receive": trade_items_to_receive,
            "appid": trade_app_id,
            "items_to_give": len_trade_items_to_give
        }
        result_trade_offers_list.append(trade)

    return result_trade_offers_list

market_hash_name = data['result'][str(item)]['market_hash_name'] KeyError: 'market_hash_name'

data['result'] {'5676339596': {}, 'error': 'Unable to get appearance for app 730 classID 5676339596 instanceID 0\n', 'success': False}

NecroBoy avatar Apr 03 '24 18:04 NecroBoy

well, then there is no skin with such a class in the game with id 730, is everything written in error?)

nikitabiz avatar Apr 03 '24 19:04 nikitabiz

use web access token can get tradeoffer info at this time:

    def get_trade_offers(self, merge: bool = True,sent:int=1,received:int=1,use_webtoken=False) -> dict:
        params = {'key'if not use_webtoken else 'access_token': self._api_key if not use_webtoken else self._access_token,
                  'get_sent_offers': sent,
                  'get_received_offers': received,
                  'get_descriptions': 1,
                  'language': 'english',
                  'active_only': 1,
                  'historical_only': 0,
                  'time_historical_cutoff': ''}


        try:
            response = self.api_call('GET', 'IEconService', 'GetTradeOffers', 'v1', params)

            response = response.json()

        except json.decoder.JSONDecodeError:
            time.sleep(2)
            return self.get_trade_offers(merge,sent,received)
        response = self._filter_non_active_offers(response)

        if merge:
            response = merge_items_with_descriptions_from_offers(response)
        return response

for webapi token self._access_token, add a new function or simply added following block under the login function:

from urllib.parse import unquote

steam_login_secure_cookies = [cookie for cookie in self._session.cookies if cookie.name == 'steamLoginSecure']
cookie_value = steam_login_secure_cookies[0].value
decoded_cookie_value = unquote(cookie_value)
access_token_parts = decoded_cookie_value.split('||')
if len(access_token_parts) < 2:
    print(decoded_cookie_value)
    raise ValueError('Access token not found in steamLoginSecure cookie')

access_token = access_token_parts[1]
self._access_token = access_token

more details for web access token, see https://github.com/DoctorMcKay/node-steam-tradeoffer-manager/wiki/Access-Tokens

Marvin0729 avatar Apr 04 '24 04:04 Marvin0729

use web access token can get tradeoffer info at this time:

    def get_trade_offers(self, merge: bool = True,sent:int=1,received:int=1,use_webtoken=False) -> dict:
        params = {'key'if not use_webtoken else 'access_token': self._api_key if not use_webtoken else self._access_token,
                  'get_sent_offers': sent,
                  'get_received_offers': received,
                  'get_descriptions': 1,
                  'language': 'english',
                  'active_only': 1,
                  'historical_only': 0,
                  'time_historical_cutoff': ''}


        try:
            response = self.api_call('GET', 'IEconService', 'GetTradeOffers', 'v1', params)

            response = response.json()

        except json.decoder.JSONDecodeError:
            time.sleep(2)
            return self.get_trade_offers(merge,sent,received)
        response = self._filter_non_active_offers(response)

        if merge:
            response = merge_items_with_descriptions_from_offers(response)
        return response

for webapi token self._access_token, add a new function or simply added following block under the login function:

from urllib.parse import unquote

steam_login_secure_cookies = [cookie for cookie in self._session.cookies if cookie.name == 'steamLoginSecure']
cookie_value = steam_login_secure_cookies[0].value
decoded_cookie_value = unquote(cookie_value)
access_token_parts = decoded_cookie_value.split('||')
if len(access_token_parts) < 2:
    print(decoded_cookie_value)
    raise ValueError('Access token not found in steamLoginSecure cookie')

access_token = access_token_parts[1]
self._access_token = access_token

more details for web access token, see https://github.com/DoctorMcKay/node-steam-tradeoffer-manager/wiki/Access-Tokens

thks bro!

BestNathan avatar Apr 04 '24 06:04 BestNathan

use web access token can get tradeoffer info at this time:

    def get_trade_offers(self, merge: bool = True,sent:int=1,received:int=1,use_webtoken=False) -> dict:
        params = {'key'if not use_webtoken else 'access_token': self._api_key if not use_webtoken else self._access_token,
                  'get_sent_offers': sent,
                  'get_received_offers': received,
                  'get_descriptions': 1,
                  'language': 'english',
                  'active_only': 1,
                  'historical_only': 0,
                  'time_historical_cutoff': ''}


        try:
            response = self.api_call('GET', 'IEconService', 'GetTradeOffers', 'v1', params)

            response = response.json()

        except json.decoder.JSONDecodeError:
            time.sleep(2)
            return self.get_trade_offers(merge,sent,received)
        response = self._filter_non_active_offers(response)

        if merge:
            response = merge_items_with_descriptions_from_offers(response)
        return response

for webapi token self._access_token, add a new function or simply added following block under the login function:

from urllib.parse import unquote

steam_login_secure_cookies = [cookie for cookie in self._session.cookies if cookie.name == 'steamLoginSecure']
cookie_value = steam_login_secure_cookies[0].value
decoded_cookie_value = unquote(cookie_value)
access_token_parts = decoded_cookie_value.split('||')
if len(access_token_parts) < 2:
    print(decoded_cookie_value)
    raise ValueError('Access token not found in steamLoginSecure cookie')

access_token = access_token_parts[1]
self._access_token = access_token

more details for web access token, see https://github.com/DoctorMcKay/node-steam-tradeoffer-manager/wiki/Access-Tokens

working good, thank you very much!

NecroBoy avatar Apr 04 '24 08:04 NecroBoy

could you create a pull request instead of having these snippets of code copy-pasted around? I don't think pasting the code in comments is the solution considering that people are starting to refer to comments instead of referring to tangible commits

CFD2 avatar Apr 20 '24 18:04 CFD2

Indeed, please create pr so I can fix the issue

bukson avatar May 29 '24 08:05 bukson