Discord.py Variables

im creating a Discordbot, that let me find out Informations about a IP-Adress using a jsonapi. However i definied the ip within my configfile (ip = config.get("IP"). now i want to do, that sues can pass the IP as a Argument after the command, then the given IP shuld be temporaly stored into the variable as long as the process is running and afterwards after the embed has been sent it should remove the ip from the variable. It would be nice, if anyone could help me with that.

import discord
import requests
import json
from discord.ext import commands

with open("config.json") as config:
    config = json.load(config)
    developer = config.get("Developer")
    token = config.get("Token")
    appid = config.get("ApplicationID")
    prefix = config.get("Prefix")
    apikey = config.get("API-KEY")
    ipadress = config.get("IP-Adress")

    bot = commands.Bot(command_prefix=prefix, Intents=discord.Intents.all(), help_command=None)
    response = requests.get(f"https://api.ipgeolocation.io/ipgeo?apiKey={apikey}&ip={ipadress}")


    def jprint(obj):
        # create a formatted string of the Python JSON object
        text = json.dumps(obj, sort_keys=True, indent=4)
        print(text)

    # jprint(response.json())
call_code = response.json()["calling_code"]
city = response.json()["city"]
connection_type = response.json()["connection_type"]
continent_code = response.json()["continent_code"]
continent_name = response.json()["continent_name"]
country_capital = response.json()["country_capital"]
country_code2 = response.json()["country_code2"]
country_code3 = response.json()["country_code3"]
country_name = response.json()["country_name"]
country_tld = response.json()["country_tld"]
currency = response.json()["currency"]
currency_code = response.json()["currency"]["code"]
currency_name = response.json()["currency"]["name"]
currency_symbol = response.json()["currency"]["symbol"]
district = response.json()["district"]
geoname_id = response.json()["geoname_id"]
ip = response.json()["ip"]
is_eu = response.json()["is_eu"]
isp = response.json()["isp"]
languages = response.json()["languages"]
latitude = response.json()["latitude"]
longitude = response.json()["longitude"]
organization = response.json()["organization"]
state_prov = response.json()["state_prov"]
time_zone = response.json()["time_zone"]
time_zone_name = response.json()["time_zone"]["name"]
time_zone_offset = response.json()["time_zone"]["offset"]
time_zone_current_time = response.json()["time_zone"]["current_time"]
time_zone_current_time_unix = response.json()["time_zone"]["current_time_unix"]
time_zone_is_dst = response.json()["time_zone"]["is_dst"]
time_zone_dst_savings = response.json()["time_zone"]["dst_savings"]
zipcode = response.json()["zipcode"]


@bot.command(name="location")
async def geolookup(ctx, args: ip):
    embed = discord.Embed(
        title="Location Lookup:",
        description="Outputs a lot of Infos about  a IP",
        color=0xFF0C93)

    embed.add_field(
        name="Calling-Code: ",
        value=f"{call_code}",
        inline=True)

    embed.add_field(
        name="City: ",
        value=f"{city}",
        inline=True)

    embed.add_field(
        name="Continent-Code: ",
        value=f"{continent_code}",
        inline=True)

    embed.add_field(
        name="Continent-Name: ",
        value=f"{continent_name}",
        inline=True)

    embed.add_field(
        name="Country-Capital: ",
        value=f"{country_capital}",
        inline=True)

    embed.add_field(
        name="Country-Code2: ",
        value=f"{country_code2}",
        inline=True)

    embed.add_field(
        name="Country-Code3: ",
        value=f"{country_code3}",
        inline=True)

    embed.add_field(
        name="Country-Name: ",
        value=f"{country_name}",
        inline=True)

    embed.add_field(
        name="Country-TLD: ",
        value=f"{country_tld}",
        inline=True)

    embed.add_field(
        name="Currency: ",
        value=f"Code: {currency_code} \n"
              f"Name: {currency_name} \n"
              f"Symbol: {currency_symbol}", inline=True)

    embed.add_field(
        name="District: ",
        value=f"{district}",
        inline=True)

    embed.add_field(
        name="Geoname-ID: ",
        value=f"{geoname_id}",
        inline=True)

    embed.add_field(
        name="IP: ",
        value=f"{args}",
        inline=True)

    embed.add_field(
        name="IS-EU: ",
        value=f"{is_eu}",
        inline=True)

    embed.add_field(
        name="ISP: ",
        value=f"{isp}",
        inline=True)

    embed.add_field(
        name="Languages: ",
        value=f"{languages}",
        inline=True)

    embed.add_field(
        name="Latitude: ",
        value=f"{latitude}",
        inline=True)

    embed.add_field(
        name="Longitude: ",
        value=f"{longitude}",
        inline=True)

    embed.add_field(
        name="Organization: ",
        value=f"{organization}",
        inline=True)

    embed.add_field(
        name="State-Prov: ",
        value=f"{state_prov}",
        inline=True)

    embed.add_field(
        name="Time-Zone: ",
        value=f"Name: {time_zone_name} \n"
              f"Offset: {time_zone_offset} \n"
              f"Current Time: {time_zone_current_time} \n"
              f"Current Time Unix: {time_zone_current_time_unix} \n"
              f"is_dst: {time_zone_is_dst}\n"
              f"dst_savings: {time_zone_dst_savings}", inline=True)

    embed.add_field(
        name="Zipcode: ",
        value=f"{zipcode}",
        inline=True)

    embed.set_footer(text=f"Created by {developer}")
    embed.set_thumbnail(url=ctx.author.avatar_url)
    await ctx.channel.send(embed=embed)


@bot.event
async def on_ready():
    print("Ready!")


bot.run(token, reconnect=True)

1 answer

  • answered 2021-04-21 15:54 Ron

    The discord.ext.commands extension that you are using can easily add commands with arguments.

    Reference for parameters in commands : discord.py docs

    from discord.ext import commands
    
    bot = commands.Bot(command_prefix='$')
    
    @bot.command(name="greet")
    async def test(ctx, arg1):
        # Do something with arg1
        embed = Embed(
                title=f"Hello {arg1}",
                color=0x00A61D,
            )
    
        await ctx.send(embed=embed)
    
    

    Put the request code into a function, and call the function from the discord command.

    def get_ip_details(ip_address):
        response = requests.get(
            f"https://api.ipgeolocation.io/ipgeo",
            params={"apiKey":"apikey", "ip":"ip_address"}
        )
        # Check if response
        response.check_for_status()
        ip_data = {
            "call_code": response["calling_code"],
            "city": response["city"],
            "connection_type": response["connection_type"],
            "continent_code": response["continent_code"],
            "continent_name": response["continent_name"],
            "country_capital": response["country_capital"],
            "country_code2": response["country_code2"],
            "country_code3": response["country_code3"],
            "country_name": response["country_name"],
            "country_tld": response["country_tld"],
            "currency": response["currency"],
            "currency_code": response["currency"]["code"],
            "currency_name": response["currency"]["name"],
            "currency_symbol": response["currency"]["symbol"],
            "district": response["district"],
            "geoname_id": response["geoname_id"],
            "ip": response["ip"],
            "is_eu": response["is_eu"],
            "isp": response["isp"],
            "languages": response["languages"],
            "latitude": response["latitude"],
            "longitude": response["longitude"],
            "organization": response["organization"],
            "state_prov": response["state_prov"],
            "time_zone": response["time_zone"],
            "time_zone_name": response["time_zone"]["name"],
            "time_zone_offset": response["time_zone"]["offset"],
            "time_zone_current_time": response["time_zone"]["current_time"],
            "time_zone_current_time_unix": response["time_zone"]["current_time_unix"],
            "time_zone_is_dst": response["time_zone"]["is_dst"],
            "time_zone_dst_savings": response["time_zone"]["dst_savings"],
            "zipcode": response["zipcode"],
        }
    
    
    
    

    Now you can call the ip_address function from your command function

    @bot.command(name="location")
    async def get_ip_location(ctx, ip_address):
        try:
            ip_details = get_ip_details(ip_address)
    
            <ip_details is a dict with all the data>
            <add details to embed here>
    
            await ctx.send(embed=embed)
        except Exception:
            await ctx.send("Error fetching details")    
    
    

    You can also specify int or bool or any other callable function as the type of the argument, and it will try to convert the argument into that type.

    You can get more details with the Converters section of the docs


    Other advice

    1. You can use the pprint module to pretty print stuff. You won't need the jprint function.
    2. You can save response.json() into a variable and then get all those values out of it. You don't need to call response.json() everytime.
    3. Use aiohttp instead of requests so that you can make requests asynchronously.
    4. You can directly pass the strings into the embed, instead of using f-strings for just the string.