def main():
    try:
        steamguard_path = join('accounts_data', account_file)
        with open(steamguard_path, 'r') as guard_file:
            data = json.load(guard_file)

            username = data['username']
            password = data['password']
            api_key = data['api_key']
            print('Запуск бота, принимающего входящие офферы')
            client = SteamClient(api_key)
            client.login(username, password, steamguard_path)
            print('Вход в Steam прошёл успешно.')
            print(
                'Офферы будут подтверждаться каждые 10 секунд. Нажмите Ctrl+С, чтобы сделать паузу.'
            )
            accept_offers(client)

    except FileNotFoundError:
        add_new_account()

    except json.decoder.JSONDecodeError:
        user_answer = prompt(
            '\nОшибка декодирования. Скорее всего файлы с данными об аккаунтах пусты'
            ' или введены не верно.\n'
            'Введите add, чтобы добавить\перезаписать новый аккаунт или любые символы, '
            'чтобы выйти из программы\n'
            'Ввод')

        if user_answer == 'add':
            add_new_account()

        else:
            exit()
Beispiel #2
0
 def test_accept_trade_offer(self):
     client = SteamClient(self.credentials.api_key)
     client.login(self.credentials.login, self.credentials.password,
                  self.steam_guard_file)
     trade_offer_id = '1451378159'
     response_dict = client.accept_trade_offer(trade_offer_id)
     self.assertIsNotNone(response_dict)
Beispiel #3
0
 def test_create_and_remove_sell_listing(self):
     client = SteamClient(self.credentials.api_key)
     client.login(self.credentials.login, self.credentials.password,
                  self.steam_guard_file)
     game = GameOptions.DOTA2
     inventory = client.get_my_inventory(game)
     asset_id_to_sell = None
     for asset_id, item in inventory.items():
         if item.get("marketable") == 1:
             asset_id_to_sell = asset_id
             break
     self.assertIsNotNone(
         asset_id_to_sell,
         "You need at least 1 marketable item to pass this test")
     response = client.market.create_sell_order(asset_id_to_sell, game,
                                                "10000")
     self.assertTrue(response["success"])
     sell_listings = client.market.get_my_market_listings()["sell_listings"]
     listing_to_cancel = None
     for listing in sell_listings.values():
         if listing["description"]["id"] == asset_id_to_sell:
             listing_to_cancel = listing["listing_id"]
             break
     self.assertIsNotNone(listing_to_cancel)
     response = client.market.cancel_sell_order(listing_to_cancel)
Beispiel #4
0
 def test_decline_trade_offer(self):
     client = SteamClient(self.credentials.api_key)
     client.login(self.credentials.login, self.credentials.password,
                  self.steam_guard_file)
     trade_offer_id = '1449530707'
     response_dict = client.decline_trade_offer(trade_offer_id)
     self.assertEqual(response_dict['response'], {})
Beispiel #5
0
 def test_cancel_trade_offer(self):
     client = SteamClient(self.credentials.api_key)
     client.login(self.credentials.login, self.credentials.password,
                  self.steam_guard_file)
     trade_offer_id = '1450637835'
     response_dict = client.cancel_trade_offer(trade_offer_id)
     self.assertEqual(response_dict['response'], {})
Beispiel #6
0
 def test_get_escrow_duration(self):
     sample_trade_url = "https://steamcommunity.com/tradeoffer/new/?partner=314218906&token=sgA4FdNm"  # a sample trade url with escrow time of 15 days cause mobile auth not added
     client = SteamClient(self.credentials.api_key)
     client.login(self.credentials.login, self.credentials.password,
                  self.steam_guard_file)
     response = client.get_escrow_duration(sample_trade_url)
     self.assertEqual(response, 15)
Beispiel #7
0
def log_in():
    global username
    global password
    global market_api_key
    global api_key
    global steamguard_path
    global client
    username = login_entry.get()
    password = password_entry.get()
    market_api_key = market_api_entry.get()
    api_key = steam_api_entry.get()
    steamguard_path = entry_path.get()
    if not are_credentials_filled():
        messagebox.showerror("Error", "You have to fill credentials.")
        return
    try:
        client = SteamClient(api_key)
        client.login(username, password, steamguard_path)
        messagebox.showinfo("Success",
                            'Bot logged in successfully:' + time.strftime("%d/%m/%Y, %H:%M:%S", time.localtime()))
        save_data()
        create_widgets()
        global win
        win.destroy()
    except:
        messagebox.showerror("Error", "The account name or password that you have entered is incorrect or you made too"
                                      " many tryes to log in.")
Beispiel #8
0
 def test_get_all_listings_from_market(self):
     client = SteamClient(self.credentials.api_key)
     client.login(self.credentials.login, self.credentials.password, self.steam_guard_file)
     listings = client.market.get_my_market_listings()
     self.assertTrue(len(listings) == 2)
     self.assertTrue(len(listings.get("buy_orders")) == 1)
     self.assertTrue(len(listings.get("sell_listings")) == 1)
     self.assertIsInstance(next(iter(listings.get("sell_listings").values())).get("description"), dict)
Beispiel #9
0
 def test_get_partner_inventory(self):
     client = SteamClient(self.credentials.api_key)
     client.login(self.credentials.login, self.credentials.password,
                  self.steam_guard_file)
     partner_id = ''
     game = GameOptions.TF2
     inventory = client.get_partner_inventory(partner_id, game)
     self.assertIsNotNone(inventory)
Beispiel #10
0
    def test_get_price_to_many_requests(self):
        def request_loop() -> None:
            item = 'M4A1-S | Cyrex (Factory New)'
            for _ in range(21):
                client.fetch_price(item, GameOptions.CS)

        client = SteamClient(self.credentials.api_key)
        client.login(self.credentials.login, self.credentials.password, self.steam_guard_file)
        self.assertRaises(TooManyRequests, request_loop)
def accept_incoming_offers(username, password, api_key, steamguard_path):
    print('Запуск бота, принимающего входящие офферы')
    client = SteamClient(api_key)
    client.login(username, password, steamguard_path)
    print('Вход в Steam прошёл успешно.')
    print(
        'Офферы будут подтверждаться каждые 10 секунд. Нажмите Ctrl+С, чтобы сделать паузу. Затем можно будет'
        ' выйти из цикла.')
    accept_offers_loop(client)
Beispiel #12
0
    def test_get_price_to_many_requests(self):
        def request_loop() -> None:
            item = 'M4A1-S | Cyrex (Factory New)'
            for _ in range(21):
                client.market.fetch_price(item, GameOptions.CS)

        client = SteamClient(self.credentials.api_key)
        client.login(self.credentials.login, self.credentials.password, self.steam_guard_file)
        self.assertRaises(TooManyRequests, request_loop)
Beispiel #13
0
def _login(steamid):
    print("Logging {0}".format(db.get_account_username_by_steamid(steamid)))

    username, password, steamapikey = db.get_login_creds_by_steamid(steamid)
    client = SteamClient(steamapikey)
    client.login(username, password, generate_path_by_steamid(steamid))
    _save_session(client)
    print("LOGGED")
    return client
Beispiel #14
0
 def test_sessionid_cookie(self):
     client = SteamClient(self.credentials.api_key)
     client.login(self.credentials.login, self.credentials.password,
                  self.steam_guard_file)
     community_cookies = client._session.cookies.get_dict(
         "steamcommunity.com")
     store_cookies = client._session.cookies.get_dict(
         "store.steampowered.com")
     self.assertTrue("sessionid" in community_cookies)
     self.assertTrue("sessionid" in store_cookies)
Beispiel #15
0
 def test_create_and_cancel_buy_order(self):
     client = SteamClient(self.credentials.api_key)
     client.login(self.credentials.login, self.credentials.password, self.steam_guard_file)
     # PUT THE REAL CURRENCY OF YOUR STEAM WALLET, OTHER CURRENCIES WILL NOT WORK
     response = client.market.create_buy_order("AK-47 | Redline (Field-Tested)", "10.34", 2, GameOptions.CS,
                                               Currency.EURO)
     buy_order_id = response["buy_orderid"]
     self.assertTrue(response["success"] == 1)
     self.assertIsNotNone(buy_order_id)
     response = client.market.cancel_buy_order(buy_order_id)
     self.assertTrue(response["success"])
Beispiel #16
0
 def __init__(self, col):
     self.user = col['username']
     self.psw = col['password']
     self.apikey = col['dev_key']
     self.guard_info = {
         "steamid": str(col['steam_id']),
         "shared_secret": col['configs']['shared_secret'],
         "identity_secret": col['configs']['identity_secret'],
     }
     self.steam_client = SteamClient(self.apikey)
     self.steam_client.login(self.user, self.psw, json.dumps(self.guard_info))
Beispiel #17
0
 def test_get_all_listings_from_market(self):
     client = SteamClient(self.credentials.api_key)
     client.login(self.credentials.login, self.credentials.password,
                  self.steam_guard_file)
     listings = client.market.get_my_market_listings()
     self.assertTrue(len(listings) == 2)
     self.assertTrue(len(listings.get("buy_orders")) == 1)
     self.assertTrue(len(listings.get("sell_listings")) == 1)
     self.assertIsInstance(
         next(iter(
             listings.get("sell_listings").values())).get("description"),
         dict)
Beispiel #18
0
 def test_create_and_cancel_buy_order(self):
     client = SteamClient(self.credentials.api_key)
     client.login(self.credentials.login, self.credentials.password,
                  self.steam_guard_file)
     # PUT THE REAL CURRENCY OF YOUR STEAM WALLET, OTHER CURRENCIES WILL NOT WORK
     response = client.market.create_buy_order(
         "AK-47 | Redline (Field-Tested)", "10.34", 2, GameOptions.CS,
         Currency.EURO)
     buy_order_id = response["buy_orderid"]
     self.assertTrue(response["success"] == 1)
     self.assertIsNotNone(buy_order_id)
     response = client.market.cancel_buy_order(buy_order_id)
     self.assertTrue(response["success"])
Beispiel #19
0
def main():
    print('This is the chat bot.')
    if not are_credentials_filled():
        print('You have to fill the credentials to run the example')
        print('Terminating bot')
        return
    client = SteamClient(api_key)
    client.login(username, password, steamguard_path)
    print('Bot logged in successfully, polling messages every 10 seconds')
    while True:
        time.sleep(10)
        messages = client.chat.fetch_messages()['received']
        for message in messages:
            client.chat.send_message(message['partner'], "Got your message: " + message['message'])
Beispiel #20
0
def main():
    print('This is the chat bot.')
    if not are_credentials_filled():
        print('You have to fill the credentials to run the example')
        print('Terminating bot')
        return
    client = SteamClient(api_key)
    client.login(username, password, steamguard_path)
    print('Bot logged in successfully, polling messages every 10 seconds')
    while True:
        time.sleep(10)
        messages = client.chat.fetch_messages()['received']
        for message in messages:
            client.chat.send_message(message['partner'],
                                     "Got your message: " + message['message'])
Beispiel #21
0
    def __init__(self, steam_id, bot_type='trader'):
        self.bot_type = bot_type
        with open(self.__authenticator_files_path + steam_id + '.json') as f:
            self.config = json.load(f)

        self.auth_path = self.__authenticator_files_path + 'guards/' + steam_id + '.json'
        with open(self.auth_path, 'w') as f:
            json.dump(
                {
                    "steamid": steam_id,
                    "shared_secret": self.config['shared_secret'],
                    "identity_secret": self.config['identity_secret'],
                }, f)
        self.client = SteamClient(self.config['apikey'])
        self.online = False
Beispiel #22
0
def main():
    print('Steam 聊天机器人启动...')
    if not are_credentials_filled():
        print('你需要按要求填写所有信息!')
        print('Steam 聊天机器人结束。')
        return
    client = SteamClient(api_key)
    client.login(username, password, steamguard_path)
    print('机器人登录成功!已设定为每 10 秒轮询一次聊天列表。')
    client.chat._login()
    while True:
        time.sleep(10)
        messages = client.chat.fetch_messages()['received']
        for message in messages:
            client.chat.send_message(message['partner'],
                                     "Got your message: " + message['message'])
Beispiel #23
0
 def test_send_offer_without_sessionid_cookie(self):
     client = SteamClient(self.credentials.api_key)
     client.login(self.credentials.login, self.credentials.password,
                  self.steam_guard_file)
     client._session.cookies.set('sessionid',
                                 None,
                                 domain="steamcommunity.com")
     cookies = client._session.cookies.get_dict('steamcommunity.com')
     self.assertFalse('sessionid' in cookies)
     game = GameOptions.TF2
     asset_id = ''
     my_asset = Asset(asset_id, game)
     trade_offer_url = ''
     make_offer = lambda: client.make_offer_with_url([my_asset], [
     ], trade_offer_url, "TEST")
     self.assertRaises(AttributeError, make_offer)
Beispiel #24
0
 def test_get_price_history(self):
     with SteamClient(self.credentials.api_key, self.credentials.login,
                      self.credentials.password,
                      self.steam_guard_file) as client:
         item = 'M4A1-S | Cyrex (Factory New)'
         response = client.market.fetch_price_history(item, GameOptions.CS)
         self.assertTrue(response['success'])
         self.assertIn('prices', response)
Beispiel #25
0
 def test_get_wallet_balance(self):
     with SteamClient(self.credentials.api_key, self.credentials.login,
                      self.credentials.password,
                      self.steam_guard_file) as client:
         wallet_balance = client.get_wallet_balance()
         self.assertTrue(type(wallet_balance), float)
         wallet_balance = client.get_wallet_balance(convert_to_float=False)
         self.assertTrue(type(wallet_balance), str)
Beispiel #26
0
    def __init__(self, cfg_account: str, recipient_id: str) -> None:

        self.cfg_account = json.load(open(cfg_account))
        self.login = self.cfg_account["login"]
        self.api_token = self.cfg_account['API']
        self.password = self.cfg_account['password']
        self.recipient_id = recipient_id
        self.partner_id = int(self.recipient_id) - 76561197960265728
        self.adapter = CustomAdapter(logger, {'account': self.login})

        try:
            self.account = SteamClient(self.api_token)
            self.account.login(self.login, self.password, cfg_account)
            self.adapter.info(translate.word('good_auth'))
            self.decline_all_trades()

        except steampy.exceptions.InvalidCredentials as e:
            self.adapter.warning(translate.word('bad_auth').format(e))
Beispiel #27
0
def _login_from_session(steamid):
    print("Logging {0} from session file".format(
        db.get_account_username_by_steamid(steamid)))
    account = db.get_all_creds_by_steamid(steamid)
    path = os.path.join(USER_DATA_FOLDER, steamid + ".session")
    if not os.path.exists(path):
        return None
    sg_path = os.path.join(USER_DATA_FOLDER, steamid + ".json")
    session = requests.session()
    with open(path, 'rb') as f:
        session.cookies.update(pickle.load(f))
    client = SteamClient(account['steamapikey'], account['username'],
                         account['password'], sg_path)
    client._session = session
    client.was_login_executed = True
    if client.is_session_alive():
        print("LOGGED FROM SESSION")
        return client
Beispiel #28
0
class Bot(object):
    __authenticator_files_path = 'files/'

    def __init__(self, steam_id, bot_type='trader'):
        self.bot_type = bot_type
        with open(self.__authenticator_files_path + steam_id + '.json') as f:
            self.config = json.load(f)

        self.auth_path = self.__authenticator_files_path + 'guards/' + steam_id + '.json'
        with open(self.auth_path, 'w') as f:
            json.dump(
                {
                    "steamid": steam_id,
                    "shared_secret": self.config['shared_secret'],
                    "identity_secret": self.config['identity_secret'],
                }, f)
        self.client = SteamClient(self.config['apikey'])
        self.online = False

    def __str__(self):
        tmp = self.config
        tmp.pop('shared_secret')
        tmp.pop('secret_1')
        tmp.pop('apikey')
        tmp['online'] = self.online
        tmp['type'] = self.bot_type
        return json.dumps(tmp)

    def login(self):
        while True:
            try:
                self.client.login(self.config['account_name'],
                                  self.config['password'], self.auth_path)
                break
            except InvalidCredentials:
                print('Error with logging in')

    def get_code(self):
        return generate_one_time_code(self.config['shared_secret'],
                                      int(datetime.now().timestamp()))

    def make_offer(self, partner_id, item_ids):
        pass
Beispiel #29
0
 def test_create_and_remove_sell_listing(self):
     client = SteamClient(self.credentials.api_key)
     client.login(self.credentials.login, self.credentials.password, self.steam_guard_file)
     game = GameOptions.DOTA2
     inventory = client.get_my_inventory(game)
     asset_id_to_sell = None
     for asset_id, item in inventory.items():
         if item.get("marketable") == 1:
             asset_id_to_sell = asset_id
             break
     self.assertIsNotNone(asset_id_to_sell, "You need at least 1 marketable item to pass this test")
     response = client.market.create_sell_order(asset_id_to_sell, game, "10000")
     self.assertTrue(response["success"])
     sell_listings = client.market.get_my_market_listings()["sell_listings"]
     listing_to_cancel = None
     for listing in sell_listings.values():
         if listing["description"]["id"] == asset_id_to_sell:
             listing_to_cancel = listing["listing_id"]
             break
     self.assertIsNotNone(listing_to_cancel)
     response = client.market.cancel_sell_order(listing_to_cancel)
Beispiel #30
0
 def test_make_offer(self):
     client = SteamClient(self.credentials.api_key)
     client.login(self.credentials.login, self.credentials.password, self.steam_guard_file)
     partner_id = ''
     game = GameOptions.CS
     my_items = client.get_my_inventory(game)
     partner_items = client.get_partner_inventory(partner_id, game)
     my_first_item = next(iter(my_items.values()))
     partner_first_item = next(iter(partner_items.values()))
     my_asset = Asset(my_first_item['id'], game)
     partner_asset = Asset(partner_first_item['id'], game)
     response = client.make_offer([my_asset], [partner_asset], partner_id, 'TESTOWA OFERTA')
     self.assertIsNotNone(response)
Beispiel #31
0
 def test_make_offer_with_trade_url(self):
     sample_trade_url="https://steamcommunity.com/tradeoffer/new/?partner=314218906&token=sgA4FdNm"
     client = SteamClient(self.credentials.api_key)
     client.login(self.credentials.login, self.credentials.password, self.steam_guard_file)
     partner_id = '76561198274484634'
     game = GameOptions.CS
     my_items = client.get_my_inventory(game)
     partner_items = client.get_partner_inventory(partner_id, game)
     my_first_item = next(iter(my_items.values()))
     partner_first_item = next(iter(partner_items.values()))
     my_asset = Asset(my_first_item['id'], game)
     partner_asset = Asset(partner_first_item['id'], game)
     response = client.make_offer_url([my_asset], [partner_asset],sample_trade_url, 'TESTOWA OFERTA')
     self.assertIsNotNone(response)
Beispiel #32
0
class BotTrade:
    def __init__(self, col):
        self.user = col['username']
        self.psw = col['password']
        self.apikey = col['dev_key']
        self.guard_info = {
            "steamid": str(col['steam_id']),
            "shared_secret": col['configs']['shared_secret'],
            "identity_secret": col['configs']['identity_secret'],
        }
        self.steam_client = SteamClient(self.apikey)
        self.steam_client.login(self.user, self.psw, json.dumps(self.guard_info))

    def send_all_items(self, trade_url, max_for_offer=300):
        my_asset_list = self.get_all_tradable_assetid()
        offer_id_list = []
        while my_asset_list:
            send_asset_list = my_asset_list[:max_for_offer]
            del my_asset_list[:max_for_offer]
            resp_dict = self.steam_client.make_offer_with_url(send_asset_list, [], trade_url, '')
            print(resp_dict)
            offer_id_list.append(resp_dict['tradeofferid'])
            time.sleep(10)
        return offer_id_list

    def send_all_items_to_many(self, trade_url_list):
        result = []
        my_asset_list = self.get_all_tradable_assetid()
        count = len(my_asset_list) // len(trade_url_list)  # 整除
        for index, value in enumerate(trade_url_list):
            if index == len(trade_url_list) - 1:
                data = my_asset_list[count * index:]
            else:
                data = my_asset_list[count * index:count * (index + 1)]
            resp_dict = self.steam_client.make_offer_with_url(data, [], value, '')
            result.append((value, resp_dict['tradeofferid']))
        return result

    def accept(self, trade_offer_id):
        resp = self.steam_client.accept_trade_offer(trade_offer_id)
        print('Accept trade', resp)
        if 'tradeid' in resp:
            return True
        return False

    def get_all_tradable_assetid(self):
        game = GameOptions.DOTA2
        my_items = self.steam_client.get_my_inventory_by_eshao(game)
        my_asset_list = []
        for i in my_items:
            if i['tradable'] == 1:
                my_asset_list.append(Asset(i['assetid'], game))
        return my_asset_list
Beispiel #33
0
 def loginBot(self, bot_creds):
     try:
         self.bots[bot_creds['username']] = SteamClient('not_needed')
         self.bots[
             bot_creds['username']].time_banned = datetime.datetime.now(
             ) - datetime.timedelta(1, 1, 0)
         while True:
             try:
                 if 'extra' in bot_creds:
                     self.bots[bot_creds['username']].login(
                         bot_creds['username'],
                         bot_creds['password'],
                         bot_creds['extra'],
                         proxies={'https': proxy.getRandom()},
                         timeout=15)
                 else:
                     self.bots[bot_creds['username']].login_with_authcode(
                         bot_creds['username'],
                         bot_creds['password'],
                         bot_creds['authcode'],
                         proxies={'https': proxy.getRandom()},
                         timeout=15)
                 break
             except:
                 # print(colored(exceptionTraceback(), 'red'))
                 print(
                     colored(
                         '[Comment Boost] Bot %s failed to log in, retrying in 10 seconds'
                         % bot_creds['username'], 'red'))
                 sleep(10)
         print(
             colored(
                 '[Comment Boost] Bot %s logged in' % bot_creds['username'],
                 'green'))
         self.bots[bot_creds['username']].steam64id = self.bots[
             bot_creds['username']].login_response.json(
             )['transfer_parameters']['steamid']
         Thread(target=self.keepAlive,
                args=(self.bots[bot_creds['username']], bot_creds)).start()
     except:
         print(
             colored(
                 '[Comment Boost] ' + bot_creds['username'] + ' ' +
                 exceptionTraceback(), 'red'))
Beispiel #34
0
def main():
    data = json.loads(request.data.decode('utf-8'))
    login, passwd, api_key = data['acc_data'][:3]
    volume = int(data['acc_data'][4])
    active_accs.setdefault(login, {})
    mafile = data['mafile']
    proxy_id = data['proxy_id']
    steam_client = active_accs[login].get('steam_client')
    if not steam_client:
        steam_client = SteamClient(api_key, proxy=proxy)
        r = steam_client.session.get('http://httpbin.org/ip')
        logger.info(r.text)
        steam_client.login(login, passwd, mafile)
        active_accs[login]['steam_client'] = steam_client

    offers = steam_client.get_trade_offers(
    )['response']['trade_offers_received']
    if offers:
        while True:
            resp = steam_client.accept_trade_offer(offers[0]['tradeofferid'],
                                                   proxy_id)
            logger.info(str(resp))
            error = resp.get('strError', None)
            if error:
                if '(28)' in error:
                    time.sleep(3)
                    continue
                elif '(25)' in error:
                    return '25'
            break

    sellm_thread = active_accs[login].get('sellm_thread')
    if not sellm_thread:
        sellm_thread = threading.Thread(target=sell_market,
                                        args=(steam_client, volume))
        active_accs[login]['sellm_thread'] = True
        sellm_thread.start()

    buygifts_thread = active_accs[login].get('buygifts_thread')
    if not buygifts_thread:
        buygifts_thread = threading.Thread(target=buy_gifts,
                                           args=(steam_client, volume))
        active_accs[login]['buygifts_thread'] = True
        buygifts_thread.start()

    return 'OK'
Beispiel #35
0
def main():
    print('This is the donation bot accepting items for free.')
    if not are_credentials_filled():
        print(
            'You have to fill credentials in storehouse.py file to run the example'
        )
        print('Terminating bot')
        return
    client = SteamClient(api_key)
    client.login(username, password, steamguard_path)
    print('Bot logged in successfully, fetching offers every 60 seconds')
    while True:
        offers = client.get_trade_offers()['response']['trade_offers_received']
        for offer in offers:
            if is_donation(offer):
                offer_id = offer['tradeofferid']
                num_accepted_items = len(offer['items_to_receive'])
                client.accept_trade_offer(offer_id)
                print('Accepted trade offer {}. Got {} items'.format(
                    offer_id, num_accepted_items))
        time.sleep(60)
Beispiel #36
0
def main():
    print('This is the donation bot accepting items for free.')
    if not are_credentials_filled():
        print('You have to fill credentials in storehouse.py file to run the example')
        print('Terminating bot')
        return
    client = SteamClient(api_key)
    client.login(username, password, steamguard_path)
    print('Bot logged in successfully, fetching offers every 60 seconds')
    while True:
        offers = client.get_trade_offers()['response']['trade_offers_received']
        for offer in offers:
            if is_donation(offer):
                offer_id = offer['tradeofferid']
                num_accepted_items = len(offer['items_to_receive'])
                client.accept_trade_offer(offer_id)
                print('Accepted trade offer {}. Got {} items'.format(offer_id, num_accepted_items))
        time.sleep(60)