Exporting specific json data from api with python - python

First time here, I am making a small discord.py bot as a project to experiment with python/apis a little. My goal is to print in discord specific data from an api when asked. here is the code in question.
#client.command()
async def otherusers(ctx, player):
rs = requests.get(apiLink + "/checkban?name=" + str(player))
if rs.status_code == 200:
rs = rs.json()
embed = discord.Embed(title="Other users for" + str(player), description="""User is known as: """ + str(rs["usedNames"]))
await ctx.send(embed=embed)
here is an example of the API request
{"id":1536171865,"avatar":"https://secure.download.dm.origin.com/production/avatar/prod/userAvatar/41472001/208x208.PNG","name":"_7cV","vban":{"A1 Army of One":{"bannedUntil":null,"reason":"ping >1000"}},"ingame":[],"otherNames":{"updateTimestamp":"2022-07-08T10:10:50.939000","usedNames":["ABCDE123","ABCDE1234","ABCDE12345","ABCDE1234567"]}}
If I change the string to str(rs["otherNames"]) it does function but I would like to only include the usernames, if I put str(rs["usedNames"]) and request on discord it gives me an error on PyCharm.
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: KeyError: 'usedNames'
Thanks in advance :)

Alright so as far as I can tell, the return from your API request where the "usedNames" key is located is nested. Try:
str(rs["otherNames"]["usedNames"])
I should note this will return ["ABCDE123","ABCDE1234","ABCDE12345","ABCDE1234567"] in the example which you gave. You might want to format the list of other usernames for your final product.
I hope that helped:)

Related

Is there a way to access every website's data through discord.py

Hi stalkers
Is there a way to access a site's data directly?
I need it for my code :
#commands.command(aliases = ['isitsafe','issafe','scanlink'])
async def isthissafe(self, ctx, link: str):
try:
link = 'https://transparencyreport.google.com/safe-browsing/search?url='+ link.replace('/','%2F')
embed=discord.Embed(
color = discord.Color.dark_red(),
title = '',
description = f"[Transparency Report verification]({link})")
await self.emb(embed, ctx.author.name, 'https://cwatch.comodo.com/images-new/check-my-site-security.png')
await ctx.send(embed=embed)
except:
await ctx.send('An error has occured')
print('\nERROR')
Basically I made, a command which should tell if a link is safe or not, I did it using google's verification report site, but.. the problem is I only reformatted the link so the bot sens it in an embed and you access it from there.
My question is, now that you understood what I need, is there some way in which I could directly let the bot output the message from the website that indicates if the site is malicious/safe ??
Please help me.
I provided an image as well with the message I want to get from the site.
You might want to try scraping the site with bs4, or just look for the string "No unsafe content found". However, it looks like google populates the field based on a request.
Your best bet would be to use transparencyreport.google.com/transparencyreport/api/v3/safebrowsing/status?site=SITE_HERE. It returns a JSON response, but I don't understand it, so play around and figure out what the keys mean

Discord-Bot fails to message Users

I'm currently working on a bot that, messages Users in a given json-file in certain time intervals. I tried this code but it doesn't do what it's supposed to nor does it give me an error I could work with.
#tasks.loop(seconds=10)
async def dm_loop():
with open("users.json" "r") as file:
users = json.load(file)
for stgru in users:
for i in users[stgru]:
user = await client.fetch_user(i)
await user.send("hello")
And just in case you're wondering: the short time Intervals and the unnecessary message: "hello", ist just for testing purposes. The "users.json"-file, mentioned in the code, has a format like this:
{
"724": ["name1#2819", "name2#2781", "name3#2891"],
"727": [],
"986": ["name4#0192"],
"840": ["name5#1221", "name6#6652"],
"798": ["name7#3312", "name8#8242", "name9#1153", "name10#3318"]
}
I already added the "dm_loop.start()"-method to my "on_ready()" but it's not working at all.
I'd be so glad if anyone could help me out here. Thanks
According to the docs, fetch_user looks up users by their ID, so you need to store the user ID instead of the user name.
https://discordpy.readthedocs.io/en/master/ext/commands/api.html?highlight=fetch_user#discord.ext.commands.Bot.fetch_user
Otherwise you can create your own UserConverter. Here's an example on how you would do that.
from discord.ext import commands
[...]
user_name = "some_tag#1234"
user = await commands.converter.UserConverter().convert(ctx, argument=user_name)
await user.send("Hello")
I do really recommend the first option though, it is a lot simpler. Since you would have to create a custom context if you are not using this in a command i believe.

Discord - Send messages from a channel to my website in real time

I currently have a python/django platform and a discord community. On my discord server there is a channel "announcements". I would just like that when a message is published in this channel, it goes up to my website in real time. This is in order to convert it into a notification.
Currently I managed to upload the messages from the channel to my site in a simple way but not in real time:
def discord_get_last_message_id():
message_id = 0
try:
message_id = Notification.objects.latest('id').discord_message_id
except:
pass
return message_id
def get_channel_messages():
#load last id discord message in DB
last_message_id = discord_get_last_message_id()
#Base route
route = "/channels/"+ DISCORD_CHANNEL_ANNONCES_ID +"/messages"
#if first time to DB, load just one item
if last_message_id == 0:
add = "?limit=1"
else:
add = "?after="+last_message_id
route = route + add
data,error_message = request_discord('GET',route)
print(data)
def request_discord(method,url_access,body={}):
data =''
#Call token
error_message = ''
access_token = discord_get_token()
#Call request
headers = {'Authorization': access_token}
body = body
if method=="GET":
result = requests.get(DISCORD_BASE_URI + url_access, headers=headers)
else:
result = requests.post(DISCORD_BASE_URI + url_access, headers=headers,data=body)
#Check result
if result.status_code != 200 and result.status_code != 201:
error_message = "Impossible de d'obtenir un resultat erreur: " + str(result.status_code)
else:
data = result.json()
return data,error_message
def discord_get_token():
return DISCORD_ANNONCES_CHANNEL_TOKEN
I'm trying to understand how discord websockets work but I have the impression that it's made to communicate with a bot only.
My question is, which way should I go to get the messages from my discord channel to my website in real time? Do I have to go through a bot?
NOTE: the goal is to get his messages to make notifications on my platform.
Thanks for your answers !
To answer your question:
My question is, which way should I go to get the messages from my discord channel to my website in real time? Do I have to go through a bot?
The best way would be to use a bot. This is the simplest, yet best way to do accomplish what you want. You could use a on_message event to get messages when they are sent. Then you could use that message and update your website. An example of how to do this is:
#bot.event
async def on_message(message):
message_content = message.content
return
You can do whatever you want with message_content. For your purpose you might want to store it in a database.
For the website side, you could use JavaScript to get the messages from the DB and update the HTML accordingly.

discord python bot api call with input error?

I'm trying to use an api call with user input and I have got an error that hasn't been solved in about 30 minutes of trying. I'm completely stuck, I used an api call before but without user input (showed bitcoin current price) and it worked perfect so I'm not sure what has gone wrong here.
If you can fix this, it would be very grateful, but if possible also explain what was wrong so I'll learn for next time thanks.
#client.command()
async def ipinfo(ctx, ip):
url = ('http://ip-api.com/json/' + ip)
response = requests.get(url)
country = response.json()['country']
city = response.json()['city']
embed = discord.Embed(color=discord.Color.red(), title="IP info for " + ip)
embed.add_field(name="Country", value=f'{country}', inline=False)
embed.add_field(name="City", value=f"{city}", inline=False)
await ctx.send(embed=embed)
I can provide the error message I get if needed, thanks for any help!
i worked it out i needed to add ip and ipinfo as aliases thank you.

how to send photo by telegram bot using multipart/form-data

I have a telegram bot (developed in python) and i wanna to send/upload photo by it from images that are in my computer.
so i should do it via multi part form data.
but i don't know ho to do it. also i didn't find useful source for this on Internet and on telegram documentation .
i tried to do that by below codes. but it was wrong
data = {'chat_id', chat_id}
files = {'photo': open("./saved/{}.jpg".format(user_id), 'rb')}
status = requests.post("https://api.telegram.org/bot<TOKEN>/sendPhoto", data=data, files=files)
can anyone help me?
Try this line of code
status = requests.post("https://api.telegram.org/bot<TOKEN>/sendPhoto?chat_id=" + data['chat_id'], files=files)
Both answers by Delimitry and Pyae Hlian Moe are correct in the sense that they work, but neither address the actual problem with the code you supplied.
The problem is that data is defined as:
data = {'chat_id', chat_id}
which is a set (not a dictionary) with two values: a string 'chat_id' and the content of chat_id, instead of
data = {'chat_id' : chat_id}
which is a dictionary with a key: the string 'chat_id' and a corresponding value stored in chat_id.
chat_id can be defined as part of the url, but similarly your original code should work as well - defining data and files as parameters for requests.post() - as long as both data and files variables are dictionaries.
You need to pass chat_id parameter in URL:
files = {'photo': open('./saved/{}.jpg'.format(user_id), 'rb')}
status = requests.post('https://api.telegram.org/bot<TOKEN>/sendPhoto?chat_id={}'.format(chat_id), files=files)
Your problem already solved by aiogram python framework.
This is full example. Just edit TOKEN and PHOTO_PATH, run the code and send /photo command to the bot :)
from aiogram import Bot, Dispatcher, executor
from aiogram.types import InputFile, Message
TOKEN = "YourBotToken"
PHOTO_PATH = "img/photo.png"
bot = Bot(TOKEN)
dp = Dispatcher(bot)
#dp.message_handler(commands=["photo"])
async def your_command_handler(message: Message):
photo = InputFile(PHOTO_PATH)
await message.answer_photo(photo)
if __name__ == '__main__':
executor.start_polling(dp)

Categories