Screenshot command Discord.py rewrite - python

First of all, I'm a new guy here and this is my first question, so I'd like to request y'all to ignore any flaws or unexpected details in this question.
So I'm trying to make a screenshot command for my Discord.py bot and currently I'm struck with the following code fragment:
async def ss(ctx, site):
embed=discord.Embed(colour = discord.Colour.orange(), timestamp=ctx.message.created_at)
embed.set_image(url=(f"https://image.thum.io/get/width/1920/crop/675/maxAge/1/noanimate/{site}"))
await ctx.send(embed=embed)
However, the bot just sends an empty embed even for a valid URL. Currently, what seems the most obvious to me is that Discord isn't able to recognize this as a valid image as it doesn't end in a image extension like .png or .jpeg, and hence the empty embed.
TBH I don't know any alternate code for what I'm trying to achieve. I searched a lot and I think it's something to do with BytesIO but I don't have the slightest idea on how to achieve this using the module.
What I'm expecting at this point of time is two things:
Fix the current flaw so that I'm able to send the screenshot of the desired website.
Report to the message author if the website is invalid, in the sense that there's no website on the specified domain, or that the request timed out due to delayed response on the website's end.
Thus, I'd like to request the community to help me out with my goal on this command. I'm not asking to be spoon-fed, but this is the only command in my bot till now, for which I don't have the slightest idea how to fix it. I'd like to thank everyone for their considerate reply in advance.
Hearty regards,
Sayan Bhattacharyya.

I did some research and debugging on my end and found that the thing doesn't work with URLs that don't have HTTPS:// or HTTP:// in front of them. If I use a link that has them, it works fine
So now what you have to do
See if user has used http:// or https:// in the start of the link
if not site.startswith("https://", "http://"):
# site doesn't start with http:// or https://
site = "https://" + site # we add https in front of the URL
See if the link is valid
# add this at the top of your file
import re
# define this variable somewhere outside of the command
URL_REGEX = re.compile(r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_#.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+")
# then in your command, use
if not re.fullmatch(URL_REGEX, site):
# URL is invalid, send a message here
await ctx.send("Invalid URL")
return
# the `return` here stops the command from running after sending the message

Your site does not redirect to a valid image file and doesn't end with a good image extension.
So this is not a Discord problem.

Related

how to download a video from a twitch clip in python [duplicate]

I have been trying to download past broadcasts for a streamer on twitch using python. I found this python code online:
https://gist.github.com/baderj/8340312
However, when I try to call the functions I am getting errors giving me a status 400 message.
Unsure if this is the code I want to download the video (as an mp4) or how to use it properly.
And by video I mean something like this as an example: www(dot)twitch.tv/imaqtpie/v/108909385 //note cant put more than 3 links since I don't have 10 reputation
Any tips on how i should go about doing this?
Here's an example of running it in cmd:
python twitch_past_broadcast_downloader.py 108909385
After running it, it gave me this:
Exception API returned 400
This is where i got the information on running it:
https://www.johannesbader.ch/2014/01/find-video-url-of-twitch-tv-live-streams-or-past-broadcasts/
Huh it's not as easy at it seems ... The code you found on this gist is quite old and Twitch has completely changed its API. Now you will need a Client ID to download videos, in order to limit the amount of video you're downloading.
If you want to correct this gist, here are simple steps you can do :
Register an application : Everything is explained here ! Register you app and keep closely your client id.
Change API route : It is no longer '{base}/api/videos/a{id_}' but {base}/kraken/videos/{id_} (not sure about the last one). You will need to change it inside the python code. The doc is here.
Add the client id to the url : As said in the doc, you need to give a header to the request you make, so add a Client-ID: <client_id> header in the request.
And now I think you will need to start debugging a bit, because it is old code :/
I will try myself to do it and I will edit this answer when I'm finished, but try yourself :)
See ya !
EDIT : Mhhh ... It doesn't seem to be possible anyway to download a video with the API :/ I was thinking only links to API changed, but the chunks section of the response from the video url disappeared and Twitch is no longer giving access to raw videos :/
Really sorry I told you to do that, even with the API I think is no longer possible :/
You can download past broadcasts of Twitch videos with Python library streamlink.
You will need OAuth token which you can generate with the command
streamlink --twitch-oauth-authenticate
Download VODs with:
streamlink --twitch-oauth-token <your-oauth-token> https://www.twitch.tv/videos/<VideoID> best -o <your-output-folder>

Open another Telegram chat/group/channel using Bot

I suspect it may be rather kid question – but anyway.
How to open another Telegram chat or group or channel using pyTelegramBotAPI? I want to forward the user (not message, the user himself) to another channel if he clicks certain button.
I saw content type migrate_to_chat_id in Message class declaration. Should I use it? If so, how to get an id of channel I need? It won't send any message to my bot.
I would better use "t.me/..." url.
Partly solved.
Speaking about the buttons, it is indeed easy. You just use named parameter url= in InlineKeyboardButton() method.
For other cases. You need to open another channel(s) from function depending on several conditions for instance. Still don't know. Import requests and make GET request? I suspect that something for it should already be in pyTelegramBotAPI, but searching in lib files wasn't successful.

How do you make a discord bot respond without commands (but in python)?

I want to make a bot in discord that, when you send it a string of some sort, or an event happens, it'll send a message to a discord channel. However, when I tried adding an "input" function (the simplest there is), it couldn't work at all. What other ways are there to input strings into programs like this?
You can use webhooks to do this.
First, you should install the discord_webhook module by running pip install discord_webhook into the terminal.
Now, you can write your program. This is a very simple example:
from discord_webhook import DiscordWebhook
url = # Put webhook url here...
webhook = DiscordWebhook(url=f'{url}', content=input('Enter a message: '))
response = webhook.execute()
You should replace the url variable with your webhook link. In case you don't know how to get a webhook link, this is an example on how to do it:
If you don't know anything about discord bots, freeCodeCamp did an amazing video on it. Look that up. They are amazing.

How can I get the number of messages sent by a user in a discord server without discord.py?

Using discord's search function manually, you can enter something like from:user#3456 and it will show you how many messages they've sent on the server (at least, messages you have access to).
I've been told there is no way to get this information through discord.py, but is there really no way to get that data at all? Would I have to resort to a web scraping tool?
To be clear, I have looked at history() already. What I'm looking for is a way to access the search function that Discord already has.
This is actually possible using discord.TextChannel.history. Here is an example:
userMessages = []
userID = 1234567890 # Change this to the ID of the user you are looking messages for
channelID = 1234567890 # Change this to the channel ID of the messages you want to check for
channel = client.get_channel(channelID)
user = discord.utils.find(lambda m: m.id== userID, channel.guild.members)
async for message in channel.history():
if message.author == user:
userMessages.append(message.content)
print(len(userMessages)) # Outputs total user messages
Make sure you replace 1234567890 with the corresponding IDs.
I've added an array which also shows all the user messages, if you prefer you can remove that and have it increment a counter instead.
I solved this in a kind of hacky way by searching with a from:username query in the Discord app, looking at the http request with Chrome DevTools, and finally recreating the request with the python module requests.
In Discord in a browser, you can open DevTools with the f12 key.
In DevTools, navigate to the Network tab.
I'd suggest to fill in the search query (but don't hit enter), then open devtools, then hit enter on the search. Otherwise there will be a lot of http requests that pop up as you type.
Then, you find the request with a name that looks like "search?author_id=1234567890". If you click on that request, you can see the details necessary to recreate it.
The key parts of the http request you need to use are the Request Headers section and the Request URL under the General section, all in the Headers tab that pops up when you first click on the request, and the Response tab to see what your response will look like.
The accept-encoding attribute of the Request Headers includes br, but this seems to jumble the result. Keeping it to just gzip, deflate works for me.
Using the requests python module this should be pretty easy to set up. So long as br is not listed in accepted-encoding, you should be able to use the json() method of requests, and for the particular problem of finding the total messages sent by the user (whose id you must insert into the request URL), it's simply accessible with my_request_variable.json()['total_results'].
The main thing to watch out for is the authorization request header. This is unique to the user (you, unless you do all this from someone else's account) and you can't substitute in a discord bot's token, unfortunately.

telegram bot image from url - undesired cache

I am working on a telegram bot that displays images from several webcams upon request. I fetch the images from urls and then send to the user (using bot.sendPhoto() ) My problem is that for any given webcam the filename does not change and it seems that the photo is sent from telegram's cache. So it will display the image from the first time that image was requested.
I have thought about downloading the image from the url, saving with a variable name (like a name with a timestamp in it) then sending it to the chat, this seems like an inelegant solution and was hoping for something better. Like forcing the image not to be cached on the telegram server.
I am using the python-telegram-bot wrapper, but I am not sure that it's specific to that.
Any ideas? I have tried searching but so far am turning up little.
Thanks in advance.
I had the same problem too, but i've found the simplest solution.
When you call the image, you have to add a parameter with timestamp to the image link.
Example:
http://www.example.com/img/img.jpg?a=TIMESTAMP
Where TIMESTAMP is the timestamp function based on the language you are using.
Simple but tricky ;)
I think the best way is to do the same as we do in React where also, same URL calls are first checked in the cache.
If you are using Python the best way is:
timestamp = datetime.datetime.now().isoformat()
# Above statement returns like: '2013-11-18T08:18:31.809000'
pic_url = '{0}?a={1}'.format(img_url, timestamp)
Hope that helps!
I had the same problem. I wanted to create a bot which sends an image taken by a webcam of a ski slope (webcam.example.com/image.jpg). Unfortunately, the filename and so the url never updates and telegram always sends the cached image. So I decided to alter the url passed to the api. In order to achieve this, I wrote a simple php site (example.com/photo.php) which redirects to the original url of the photo. After that, I created a folder (example.com/getphoto/) on my webspace with a .htaccess file inside. The .htaccess redirects all request in this folder to the photo.php site which redirects to the image (webcam.example.com/image.jpg). So you could add everything to the url of the folder and still get the picture (e. g. example.com/getphoto/42 or example.com/getphoto/hrte8437g). The telegram api seems to cache photos by url, so if you add always another ending to the url passed to the api, telegram doesnt use the cached version and sends the current image instead. The easiest way to always change the url is by adding the current date to it.
example.com/photo.php
<?php
header("Location: http://webcam.example.com/image.jpg");
die();
?>
example.com/getphoto/.htaccess
RewriteEngine on
RewriteRule ^(.*)$ http://example.com/photo.php
in python:
bot.sendPhoto(chat_id, 'example.com/getphoto/' + strftime("%Y-%m-%d_%H-%M-%S", gmtime()))
This workaround should also work in other languages like java or php. You just need to change the way to get the current date.

Categories

Resources