Simple Python Script For Crypto On Google Sheets


Python Rest Requests



About the project

Obtaining crypto-related data for Google Sheets can be frustrating. If you're like me, you might have attempted Google's built-in IMPORTXML feature, only to encounter infrequent data updates, leading to constant errors. Alternatively, there are add-ons available, initially promising, but often end up introducing a paywall that users are unwilling to pay for. This simple project I undertook enabled me to bypass the add-on paywall and the unreliability of Google's built-in features.

 

Potential Solutions

Personally, I lacked experience in developing Google Sheets add-ons and didn't find it necessary to learn for a straightforward task like a crypto price scraper. I explored several options to determine the most effective solution and settled on one that I believe would yield the best results and be scalable. Initially, I considered the following ideas:

 

  • Using Requests with xPath: Unfortunately, this approach worked to a certain extent but eventually failed after numerous requests, leading to being blocked.
  • Using Selenium with a browser: While functional, this method proved to be significantly slow.
  • Using Binance's API: Although it provides simplified data for each coin, it lacked support for all the required cryptocurrencies.
  • Using Coin Market Cap's API: Although slightly more effort was required compared to Binance's API, it covered all the cryptocurrencies I needed and offered greater scalability for future projects.

 

The approach I eventually chose was employing the Coin Market Cap API. It was relatively easy to set up and retrieve the desired data. The final result, which you will see later, is somewhat hardcoded because, for my specific purpose, scalability wasn't a primary concern during its initial development.

 

Using Coin Market Caps API

 

This process involved only a few necessary steps. Firstly, I needed a library to establish an interface between Google Sheets and my script.

 

Step 1: Setting up Google

 

In this step, you only need to complete a few tasks to gain access to your sheets.

 

  1. Create a GCP Account:
  2. Create a New Project:
    • Create a new project without any special configurations.
  3. Navigate to Google APIs Dashboard:
  4. Enable Google Drive API:
    • Search for "Google Drive API," select it, and enable it.
  5. Enable Google Sheets API:
    • Similarly, search for "Google Sheets API," select it, and enable it.
  6. Access Credentials:
    • Navigate to the APIs of the project. On the left sidebar, select "Credentials," then choose "Manage Service Accounts."
  7. Create a Service Account:
    • Click the "Create Service Account" button, provide a name (the name isn't crucial), and proceed without additional configurations.
  8. Obtain the Service Account Email:
    • Copy the email associated with this service account.
  9. Grant Access in Google Sheets:
    • Use the copied email to grant access to the specific Google Sheet where the script will be running.
  10. Generate and Save Keys:
    • Return to the service account in Google. Click on the three dots for action and select "Manage Keys." Add a key, choose JSON format, and create it. Save this file to your computer.

 

Step 2: The Code

 

I prefer to use a virtual environment. The first step I take is to create the project folder, and then I set up a virtual environment using the following step:

python -m venv venv

The provided command will create a folder named 'venv' within the project directory, generating a virtual environment for your project.

 

Additionally, you'll need to create a Coin Market Cap account and obtain an API key. I opted for the free basic plan since I anticipate making fewer than 10,000 requests per month. The script is configured to make a request every 30 minutes, resulting in approximately 1400-1500 requests monthly. To set up your account and acquire the API key, visit https://pro.coinmarketcap.com/account.

 

To proceed, install the necessary libraries. You'll require 'gspread' and 'requests'. A few others are typically included with Python by default. The code is provided below, and you can also view it on GitHub at https://github.com/the-jolley-boy/python_google_sheet_crypto.

 

import gspread
from requests import Request, Session
from requests.exceptions import ConnectionError, Timeout, TooManyRedirects
import json
import time

# This part takes the service account that grants access (this is the file that you got from google api, I renamed it and put it in the same directory I run the code from)
sa = gspread.service_account(filename="service_account.json")
# The sheet to edit
sh = sa.open("TableName")
# The worksheet to edit
wks = sh.worksheet("WorksheetName")

# The symbols I want info on
symb = 'LRC,HNT,ETH,PLANETS,SOL,GST,GMT,IOT'

# This code was taken from Coin Market Caps docs with some slight alteration.
# The url is adjusted to get the quotes of specific suymbols you want to get data for, in my case the ones in the symb string.
url = 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest'
# Parameters so you get only what you want
parameters = {
  'symbol': symb,
  'convert': 'USD'
}
# In here you'll need to add your own key
headers = {
  'Accepts': 'application/json',
  'Accept-Encoding': 'deflate, gzip',
  'X-CMC_PRO_API_KEY': 'key_goes_here',
}

# I set the code to run indefinitely since I want the data to be updated and since I run a server I can just leave it running all the time.
# I have hard codded the data being pulled since for now I have no need to make it more versatile but if I need to in the future I will
while True:

    session = Session()
    session.headers.update(headers)

    try:
      response = session.get(url, params=parameters)
      data = json.loads(response.text)
      lrc = data['data']['LRC']['quote']['USD']['price']
      hnt = data['data']['HNT']['quote']['USD']['price']
      eth = data['data']['ETH']['quote']['USD']['price']
      planets = data['data']['PLANETS']['quote']['USD']['price']
      sol = data['data']['SOL']['quote']['USD']['price']
      gst = data['data']['GST']['quote']['USD']['price']
      gmt = data['data']['GMT']['quote']['USD']['price']
      iot = data['data']['IOT']['quote']['USD']['price']
    except (ConnectionError, Timeout, TooManyRedirects) as e:
      print(e)

    # This part updates the desired cells.
    wks.update('H29', lrc)
    wks.update('H30', hnt)
    wks.update('H31', eth)
    wks.update('H32', planets)
    wks.update('H33', sol)
    wks.update('H34', gst)
    wks.update('H35', gmt)
    wks.update('H36', iot)

    time.sleep(1800)

 

Update

I've recently introduced several new features for data scraping.

 

The 'skinport' function now scrapes data from a website's REST API, updating my spreadsheet accordingly. This simple addition pulls necessary data from the site and populates the associated cells. You can find the new code for the entire script below.

 

Regarding the 'csfloat' functions, they scrape data from the site every three minutes. The retrieved data is then either directed to a Google Sheet or sent as webhooks to various Discord channels.

 

In the code, I've utilized threading to enable concurrent function running. This enhances execution speed, shaving off a few seconds from each run.

import gspread
from requests import Request, Session
from requests.exceptions import ConnectionError, Timeout, TooManyRedirects
import requests
import json
import time
import discord
from discord import Webhook
import asyncio
import aiohttp
import threading
import datetime

terminate_flag = False

################################################################
#
# Gets the service account for spreadsheet read/write
#
################################################################

def get_service_account():
    # This part takes the service account that grants access (this is the file that you got from google api, I renamed it and put it in the same directory I run the code from)
    return gspread.service_account(filename="service_account.json")

discord_webhook_cs = 'REDACTED'
wanted_sticker_guns = "REDACTED"
low_price_webhook = 'REDACTED'

################################################################
#
# Gets the crypto prices for specific crypto and writes to cells
#
################################################################

def crypto():
    try:
        sa = get_service_account()
        # The sheet to edit
        sh = sa.open("Current Shoe/Clothing List & Bots")
        # The worksheet to edit
        wks = sh.worksheet("Total Value")
        # The symbols I want info on
        slug = 'loopring,helium,ethereum,planetwatch,helium-iot'
        # This code was taken from Coin Market Caps docs with some slight alteration.
        # The url is adjusted to get the quotes of specific suymbols you want to get data for, in my case the ones in the symb string.
        url = 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest'
        # Parameters so you get only what you want
        parameters = {
            'slug': slug,
            'convert': 'USD'
        }
        # In here you'll need to add your own key
        headers = {
            'Accepts': 'application/json',
            'Accept-Encoding': 'deflate, gzip',
            'X-CMC_PRO_API_KEY': 'REDACTED',
        }

        session = Session()
        session.headers.update(headers)

        #Grabs Crypto prices
        try:
            response = session.get(url, params=parameters)
            data = json.loads(response.text)
            lrc = data['data']['1934']['quote']['USD']['price']
            hnt = data['data']['5665']['quote']['USD']['price']
            eth = data['data']['1027']['quote']['USD']['price']
            planets = data['data']['11861']['quote']['USD']['price']
            iot = data['data']['24686']['quote']['USD']['price']
        except (ConnectionError, Timeout, TooManyRedirects) as e:
            print(e)
            return

        # This part updates the desired cells.
        wks.update('H29', lrc)
        wks.update('H30', hnt)
        wks.update('H31', eth)
        wks.update('H32', planets)
        wks.update('H33', iot)

        print(f"Run complete Crypto. Completed: {datetime.datetime.now()}")

    except Exception as e:
        print("Error in Crypto Function: " + str(e))

################################################################
#
# Gets the recommended prices from SkinPort and writes to cells
#
################################################################

def skinport():
    try:
        sa = get_service_account()
        # The sheet to edit
        sh = sa.open("Current Shoe/Clothing List & Bots")
        # The worksheet to edit
        wks = sh.worksheet("CSGO")

        items = requests.get("https://api.skinport.com/v1/items", params={
            "app_id": "730",
            "currency": "CAD",
        }).json()

        n = wks.get("A5:A124")
        names = [item for sublist in n for item in sublist]
        v = wks.get("E5:E124")
        values = [item for sublist in v for item in sublist]

        myitems = names

        for item in items:
            name = item.get('market_hash_name')
            name = name.replace("'","")

            if name in myitems:
                if "Case Hard" in name or "Marble" in name:
                    print(item)
                sugg = item.get('suggested_price')
                
                index = names.index(name)
                values[index] = '=' + str(sugg) + '*B' + str(index+5)

        res = []
        for el in values:
            res.append([el])

        wks.update('E5:E124', res, raw=False)

        print(f"Run complete Skinport. Completed: {datetime.datetime.now()}")

    except Exception as e:
        print("Error in SkinPort Function: " + str(e))

################################################################
#
# Gets the recommended prices from CSFloat and writes to cells
#
################################################################
passval = 1

def csfloatsheet():
    try:
        global passval
        sa = get_service_account()
        # The sheet to edit
        sh = sa.open("Current Shoe/Clothing List & Bots")
        # The worksheet to edit
        wks = sh.worksheet("CSGO")

        if passval == 1:
            n = wks.get("A2:A45")
            v = wks.get("F2:F45")
        if passval == 2:
            n = wks.get("A46:A85")
            v = wks.get("F46:F85")
        if passval == 3:
            n = wks.get("A86:A126")
            v = wks.get("F86:F126")
        if passval == 4:
            n = wks.get("A127:A133")
            v = wks.get("F127:F133")

        names = [item for sublist in n for item in sublist]
        values = [item for sublist in v for item in sublist]

        try:
            for name in names:
                time.sleep(10)
                params = {
                    "sort_by": "lowest_price",
                    "market_hash_name": name
                }

                items = requests.get("https://csfloat.com/api/v1/listings", params=params).json()

                i = 0
                pxtotal = 0
                for item in items:
                    if i != 3:
                        pxtotal = pxtotal + item.get("price")
                        i = i + 1
                    else:
                        break

                pxstring = str(pxtotal)
                pxtotaldecimal = pxstring[:-2] + "." + pxstring[-2:]
                price = str(round((float(pxtotaldecimal)/3)*1.3, 2))

                index = names.index(name)
                if passval == 1:
                    values[index] = '=' + str(price) + '*B' + str(index+2)
                if passval == 2:
                    values[index] = '=' + str(price) + '*B' + str(index+46)
                if passval == 3:
                    values[index] = '=' + str(price) + '*B' + str(index+86)
                if passval == 4:
                    values[index] = '=' + str(price) + '*B' + str(index+127)
        except Exception as e:
            print("Either got throttled a little or error: " + str(e))

        res = []
        for el in values:
            res.append([el])

        if passval == 1:
            wks.update('F2:F45', res, raw=False)
        if passval == 2:
            wks.update('F46:F85', res, raw=False)
        if passval == 3:
            wks.update('F86:F126', res, raw=False)
        if passval == 4:
            wks.update('F127:F133', res, raw=False)

        passval = passval + 1
        if passval == 5:
            passval = 1

        print(f"Run complete CSFloat Sheet. Completed: {datetime.datetime.now()}")

    except Exception as e:
        print("Error in CSFloat Sheet Function: " + str(e))

################################################################
#
# Sends the webhooks for CSFloat price checks for items
#
################################################################

async def send_to_webhook(listtopost, title, webhook):
    async with aiohttp.ClientSession() as session:
        webhook = Webhook.from_url(webhook, session=session)
        s = ""
        for i in listtopost:
            s = s + i
        if len(listtopost) != 0:
            embed = discord.Embed(title=title, description=s, color=0x54bedd)
            await webhook.send(embed=embed)

################################################################
#
# Gets new listed Case Hardened AK-47 for specific patterns
#
################################################################

oldlist = []

async def csfloat():
    try:
        other = [1, 5, 14, 16, 35, 57, 72,  93, 98, 104, 116, 127, 132, 177, 
                196, 213, 217, 225, 226, 255, 262, 265, 271, 282, 288, 303, 
                333, 348, 378, 385, 389, 417,  421, 423, 425, 434, 475, 485, 
                510, 537, 539, 584, 628, 634, 637, 641, 672, 675, 685, 705, 
                710, 727, 746, 762, 768, 776, 787, 794, 796, 811, 822, 830, 
                831, 853, 886, 903]
        blueMag = [6, 56, 111, 342, 376, 379, 581, 761, 778]
        blueTop = [37, 48, 55, 62, 63, 65, 78, 125, 142, 149, 163, 178, 200, 
                    209, 215, 227, 235, 281, 287, 312, 319, 325, 349, 350, 
                    365, 397, 401, 454, 456, 467, 468, 470, 541, 558, 566, 
                    632, 634, 676, 678, 681, 700, 724, 728, 758, 814, 819, 
                    894, 1000]
        blueBackTop = [11, 19, 68, 106, 128, 130, 170, 194, 259, 284, 308, 
                        322, 332, 352, 453, 493, 494, 507, 517, 522, 580, 
                        608, 644, 664, 693, 694, 782, 793, 803, 838, 856, 
                        857, 891, 906, 913, 917, 919, 965]
        veryBlue = [95, 101, 129, 135, 162, 166, 182, 251, 261, 269, 334, 
                    337, 403, 611, 631, 652, 704, 806, 979]
        topFavs = [49, 118, 230, 248, 314, 73, 81, 82, 169, 173, 174, 192, 
                    202, 207, 236, 369, 390, 396, 424, 458, 472, 479, 574, 
                    585, 586, 604, 605, 610, 711, 721, 842, 847]

        allseed = [1, 5, 14, 16, 35, 57, 72,  93, 98, 104, 116, 127, 132, 177, 
                    196, 213, 217, 225, 226, 255, 262, 265, 271, 282, 288, 303, 
                    333, 348, 378, 385, 389, 417,  421, 423, 425, 434, 475, 485, 
                    510, 537, 539, 584, 628, 634, 637, 641, 672, 675, 685, 705, 
                    710, 727, 746, 762, 768, 776, 787, 794, 796, 811, 822, 830, 
                    831, 853, 886, 903, 6, 56, 111, 342, 376, 379, 581, 761, 778,
                    37, 48, 55, 62, 63, 65, 78, 125, 142, 149, 163, 178, 200, 
                    209, 215, 227, 235, 281, 287, 312, 319, 325, 349, 350, 
                    365, 397, 401, 454, 456, 467, 468, 470, 541, 558, 566, 
                    632, 634, 676, 678, 681, 700, 724, 728, 758, 814, 819, 
                    894, 1000, 11, 19, 68, 106, 128, 130, 170, 194, 259, 284, 308, 
                    322, 332, 352, 453, 493, 494, 507, 517, 522, 580, 
                    608, 644, 664, 693, 694, 782, 793, 803, 838, 856, 
                    857, 891, 906, 913, 917, 919, 965, 95, 101, 129, 135, 162, 166, 
                    182, 251, 261, 269, 334, 337, 403, 611, 631, 652, 704, 806, 979,
                    49, 118, 230, 248, 314, 73, 81, 82, 169, 173, 174, 192, 
                    202, 207, 236, 369, 390, 396, 424, 458, 472, 479, 574, 
                    585, 586, 604, 605, 610, 711, 721, 842, 847]

        params = {
            "sort_by": "most_recent",
            "paint_index": "44",
            "collection": "set_weapons_i",
        }

        items = requests.get("https://csfloat.com/api/v1/listings", params=params).json()

        newlist = []

        global oldlist

        otherlisted = []
        blueMaglisted = []
        blueToplisted = []
        blueBackToplisted = []
        veryBluelisted = []
        topFavslisted = []

        for item in items:
            idd = item.get("id")
            if idd not in oldlist:
                paint_seed = item["item"]["paint_seed"]
                if paint_seed in allseed:
                    name = item["item"]["market_hash_name"]
                    float_value = round(item["item"]["float_value"], 6)
                    wear_name = item["item"]["wear_name"]
                    link = "https://csfloat.com/item/" + item.get("id")
                    p = str(item.get("price"))
                    price = p[:-2] + "." + p[-2:]
                    sp = str(item["item"]["scm"]["price"])
                    steam_price = sp[:-2] + "." + p[-2:]
                    deal = round((1 - (int(item.get("price"))/int(item["item"]["scm"]["price"]))) * 100, 2)
                    if paint_seed in other:
                        otherlisted.append("[" + name + "](" + link + ") | Price: " + str(price) + " (" + str(deal) + ")\nFloat: " + str(float_value) + " | Pattern: " + str(paint_seed) + "\n")
                        newlist.append(item.get("id"))
                    if paint_seed in blueMag:
                        blueMaglisted.append("[" + name + "](" + link + ") | Price: " + str(price) + " (" + str(deal) + ")\nFloat: " + str(float_value) + " | Pattern: " + str(paint_seed) + "\n")
                        newlist.append(item.get("id"))
                    if paint_seed in blueTop:
                        blueToplisted.append("[" + name + "](" + link + ") | Price: " + str(price) + " (" + str(deal) + ")\nFloat: " + str(float_value) + " | Pattern: " + str(paint_seed) + "\n")
                        newlist.append(item.get("id"))
                    if paint_seed in blueBackTop:
                        blueBackToplisted.append("[" + name + "](" + link + ") | Price: " + str(price) + " (" + str(deal) + ")\nFloat: " + str(float_value) + " | Pattern: " + str(paint_seed) + "\n")
                        newlist.append(item.get("id"))
                    if paint_seed in veryBlue:
                        veryBluelisted.append("[" + name + "](" + link + ") | Price: " + str(price) + " (" + str(deal) + ")\nFloat: " + str(float_value) + " | Pattern: " + str(paint_seed) + "\n")
                        newlist.append(item.get("id"))
                    if paint_seed in topFavs:
                        topFavslisted.append("[" + name + "](" + link + ") | Price: " + str(price) + " (" + str(deal) + ")\nFloat: " + str(float_value) + " | Pattern: " + str(paint_seed) + "\n")
                        newlist.append(item.get("id"))
            else:
                newlist.append(item.get("id"))

        oldlist = newlist

        await send_to_webhook(otherlisted, "Case Hardened Other Category by percent discount.", discord_webhook_cs)
        await send_to_webhook(blueMaglisted, "Case Hardened Blue Mag Category by percent discount.", discord_webhook_cs)
        await send_to_webhook(blueToplisted, "Case Hardened Blue Top Category by percent discount.", discord_webhook_cs)
        await send_to_webhook(blueBackToplisted, "Case Hardened Blue Back Top Category by percent discount.", discord_webhook_cs)
        await send_to_webhook(veryBluelisted, "Case Hardened Very Blue Category by percent discount.", discord_webhook_cs)
        await send_to_webhook(topFavslisted, "Case Hardened Top Favs Category by percent discount.", discord_webhook_cs)

        print(f"Run complete CSFloat. Completed: {datetime.datetime.now()}")

        await csfloatother()
        await csfloatstickers()

    except Exception as e:
        print("Error in CSFloat CH Function: " + str(e))

################################################################
#
# Gets new listed items on CSFloat given criteria to filter
#
################################################################

oldlistother = []

async def csfloatother():
    try:
        # value = ["low float low", "low float high", "sticker value (most exp needed, 0 you don't care)", "deal % (> than)"...]
        names = {
            "M4A4 | Radiation Hazard (Minimal Wear)":[0.07, 0.15, 20000, -200],
            "M4A1-S | Imminent Danger (Field-Tested)":[0.15, 0.3, 0, 0],
            "M4A4 | Eye of Horus (Field-Tested)":[0.15, 0.23, 0, -10],
            "P250 | Apep's Curse (Field-Tested)":[0.15, 0.2, 0, 0],
            "P250 | Apep's Curse (Minimal Wear)":[0.07, 0.15, 0, 0],
            "Glock-18 | Brass (Minimal Wear)":[0.07, 0.15, 0, 0],
            "Glock-18 | Brass (Field-Tested)":[0.15, 0.2, 0, 0],
            "P250 | Vino Primo (Minimal Wear)":[0.07, 0.15, 0, 0],
        }

        global oldlistother

        listtopost = []
        newlist = []

        i = 0
        while i < len(names):

            params = {
                "sort_by": "most_recent",
                "market_hash_name": list(names)[i],
            }

            items = requests.get(
                "https://csfloat.com/api/v1/listings", 
                params=params
            ).json()

            for item in items:
                idd = item.get("id")
                if idd not in oldlistother:
                    name = item["item"]["market_hash_name"]
                    float_value = round(item["item"]["float_value"], 6)
                    wear_name = item["item"]["wear_name"]
                    link = "https://csfloat.com/item/" + item.get("id")
                    p = str(item.get("price"))
                    price = p[:-2] + "." + p[-2:]
                    sp = str(item["item"]["scm"]["price"])
                    steam_price = sp[:-2] + "." + p[-2:]
                    deal = round((1 - (int(item.get("price"))/int(item["item"]["scm"]["price"]))) * 100, 2)
                    stickerprices = [0]
                    stickertotal = 0
                    if "stickers" in item["item"]:
                        j = 0
                        while j < len(item["item"]["stickers"]):
                            stickerprices.append(item["item"]["stickers"][j]["scm"]["price"])
                            stickertotal = stickertotal + item["item"]["stickers"][j]["scm"]["price"]
                            j = j + 1
                    if list(names.values())[i][0] < float_value <= list(names.values())[i][1] and any(s >= list(names.values())[i][2] for s in stickerprices) and deal > list(names.values())[i][3]:
                        listtopost.append("[" + name + "](" + link + ") | Price: " + str(price) + " (" + str(deal) + ")\nFloat: " + str(float_value) + " | Sticker Total: " + str(stickertotal) + "\n")
                        newlist.append(idd)
                else:
                    newlist.append(idd)

            i = i + 1

        oldlistother = newlist

        await send_to_webhook(listtopost, "Wanted items from CSFloat", discord_webhook_cs)

        print(f"Run complete CSFloat Other. Completed: {datetime.datetime.now()}")

    except Exception as e:
        print("Error in CSFloat Other Function: " + str(e))

oldliststickers = []

async def csfloatstickers():
    STICKER_ON_GUNS = [
        "Katowice 2014", "(Holo) | Cologne 2014", "(Blue) | Cologne 2014", "(Red) | Cologne 2014", "(Foil) | DreamHack 2014", "(Holo) | DreamHack 2014",
        "(Foil) | Katowice 2015", "(Holo) | Katowice 2015", "(Foil) | Cologne 2015", "(Holo) | Cologne 2015", "(Foil) | Cluj-Napoca 2015", 
        "(Holo) | Cluj-Napoca 2015", "(Foil) | MLG Columbus 2016", "(Holo) | MLG Columbus 2016", "(Foil) | Cologne 2016", "(Holo) | Cologne 2016",
        "(Foil) | Atlanta 2017", "(Holo) | Atlanta 2017", "(Gold) | Krakow 2017", "(Foil) | Krakow 2017", "(Gold) | Boston 2018", "(Foil) | Boston 2018",
        "(Gold) | London 2018", "(Gold) | Katowice 2019", "Crown (Foil)", "Howling Dawn"
    ]

    params = {
        "sort_by": "most_recent",
    }

    items = requests.get(
        "https://csfloat.com/api/v1/listings", 
        params=params
    ).json()

    global oldliststickers

    listtopost = []
    newlist = []

    for item in items:
        idd = item.get("id")
        if idd not in oldliststickers:
            if "stickers" in item["item"]:
                j = 0
                stickertotal = 0
                stickernames = []
                stickernamesstring = ""
                while j < len(item["item"]["stickers"]):
                    if "scm" in item["item"]["stickers"][j]:
                        stickertotal = stickertotal + item["item"]["stickers"][j]["scm"]["price"]
                    stickernames.append(item["item"]["stickers"][j]["name"])
                    stickernamesstring = stickernamesstring + item["item"]["stickers"][j]["name"] + "\n"
                    j = j + 1
                done = 0
                for i in stickernames:
                    if any(stickers in i for stickers in STICKER_ON_GUNS) and done != 1:
                        idd = item.get("id")
                        name = item["item"]["market_hash_name"]
                        float_value = round(item["item"]["float_value"], 6)
                        wear_name = item["item"]["wear_name"]
                        link = "https://csfloat.com/item/" + item.get("id")
                        p = str(item.get("price"))
                        price = p[:-2] + "." + p[-2:]
                        sp = str(item["item"]["scm"]["price"])
                        steam_price = sp[:-2] + "." + p[-2:]
                        deal = round((1 - (int(item.get("price"))/int(item["item"]["scm"]["price"]))) * 100, 2)
                        st = str(stickertotal)[:-2] + "." + str(stickertotal)[-2:]
                        if (float(p) - float(sp)) < (float(stickertotal)*0.1) and "Souvenir" not in name and float(price) < 750 and deal > -10 and float(st) > 100:
                            listtopost.append("[" + name + "](" + link + ") | Price: " + str(price) + " (" + str(deal) + ")\nFloat: " + str(float_value) + "\nSticker Names:\n" + stickernamesstring + "\n")
                        done = 1
                        newlist.append(idd)

    oldliststickers = newlist

    await send_to_webhook(listtopost, "Sticker items from CSFloat", wanted_sticker_guns)

    print(f"Run complete CSFloat Stickers. Completed: {datetime.datetime.now()}")

oldlistdeals = []

async def csfloatdeals():
    params = {
        "sort_by": "most_recent",
    }

    items = requests.get(
        "https://csfloat.com/api/v1/listings", 
        params=params
    ).json()

    global oldlistdeals

    listtopost = []
    newlist = []

    for item in items:
        idd = item.get("id")
        if idd not in oldlistdeals:
            try:
                if "float_value" in item["item"]:
                    idd = item.get("id")
                    name = item["item"]["market_hash_name"]
                    float_value = round(item["item"]["float_value"], 6)
                    wear_name = item["item"]["wear_name"]
                    link = "https://csfloat.com/item/" + item.get("id")
                    p = str(item.get("price"))
                    price = p[:-2] + "." + p[-2:]
                    sp = str(item["item"]["scm"]["price"])
                    steam_price = sp[:-2] + "." + p[-2:]
                    deal = round((1 - (int(item.get("price"))/int(item["item"]["scm"]["price"]))) * 100, 2)
                    if deal > 40 and float(price) > 5:
                        listtopost.append("[" + name + "](" + link + ") | Price: " + str(price) + " (" + str(deal) + ")\nFloat: " + str(float_value) + "\n")
                    newlist.append(idd)
            except Exception as e:
                print("Steam price issue, skipping item: " + str(name))

    oldlistdeals = newlist

    await send_to_webhook(listtopost, "Low cost items for CSFloat", low_price_webhook)

    print(f"Run complete CSFloat Deals. Completed: {datetime.datetime.now()}")

################################################################
#
# Runs each function one after another every 10 minutes
#
################################################################

def async_functions():
    while True:
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)

        loop.run_until_complete(csfloatother())
        loop.run_until_complete(csfloatstickers())
        loop.run_until_complete(csfloatdeals())
        loop.close()

        time.sleep(180)

def run_other():
    while True:
        crypto()
        skinport()
        time.sleep(1800)

run_event = threading.Event()
run_event.set()

t1 = threading.Thread(target = run_other)
t2 = threading.Thread(target = async_functions)
t1.daemon = True
t2.daemon = True

t1.start()
t2.start()

try:
    input("Hit enter or ctrl-c to terminate.")
except KeyboardInterrupt:
    pass
# To gracefully shut off the threads.
# terminate_flag = True
# t1.join()
# t2.join()
# t4.join()