Reputation: 49
When the user inputs the command '!gif ' (where is the gif they want), I want the bot to return a gif of that name.
The code that I am trying is based on the API from Tenor, but I don't mind using any other site to get gifs as well. The current code I have doesn't work, and I'm slightly clueless on how I can go about doing this.
Note: I'm doing this as a personal project. I don't mind if you give me the answer, but if you can, please explain why you are doing what you did.
Here's my code so far:
import discord
import requests
import json
from constants import (TenorToken, DiscordToken)
client = discord.Client()
embedColour = 0xff0000
#Retrieves GIF from site
def getGIF(searchTerm):
response = requests.get("https://g.tenor.com/v1/search?q=%s&key=%s&limit=1" %(searchTerm, TenorToken))
gif = json.loads(response.content)
print(gif)
@client.event
async def on_ready():
print(f"{client.user}"[:-5] + " is now Online!")
@client.event
async def on_message(message):
if (message.author == client.user):
return
if (message.content.lower().startswith(f"{CommandKey}gif")):
getGIF(message.content.lower()[5:]) #Collects word after !gif
client.run(DiscordToken)
Thank you for any help!
Upvotes: 0
Views: 3818
Reputation: 143097
I checked your code and Tensor
doesn't send GIF data but only urls to images.
This code gives me url
for gif
in first result`
def get_gif(searchTerm): # PEP8: lower_case_names for functions
response = requests.get("https://g.tenor.com/v1/search?q={}&key={}&limit=1".format(searchTerm, TenorToken))
data = response.json() # `requests` doesn't need `json.loads()`
return data['results'][0]['media'][0]['gif']['url']
I get it by manually digging in JSON
and creating this code
# see urls for all GIFs
for result in data['results']:
print('- result -')
#print(result)
for media in result['media']:
print('- media -')
#print(media)
#print(media['gif'])
print('url:', media['gif']['url'])
And when I get url
then I can use Embed
to send url
and discord will download it and display - I don't have to download it.
if (message.content.lower().startswith(f"{CommandKey}gif")):
gif_url = get_gif(message.content.lower()[5:]) #Collects word after !gif
embed = discord.Embed()
embed.set_image(url=gif_url)
await message.channel.send(embed=embed)
Full working code
import discord
import requests
from constants import (TenorToken, DiscordToken)
#import os
#DiscordToken = os.getenv('DISCORD_TOKEN')
#TenorToken = os.getenv('TENOR_TOKEN')
client = discord.Client()
embedColour = 0xff0000
CommandKey = '!'
# --- functions ---
#Retrieves GIF from site
def get_gif(searchTerm): # PEP8: lower_case_names for functions
response = requests.get("https://g.tenor.com/v1/search?q={}&key={}&limit=1".format(searchTerm, TenorToken))
data = response.json()
'''
# see urls for all GIFs
for result in data['results']:
print('- result -')
#print(result)
for media in result['media']:
print('- media -')
print(media)
print(media['gif'])
print('url:', media['gif']['url'])
'''
return data['results'][0]['media'][0]['gif']['url']
@client.event
async def on_ready():
print(f"{client.user}"[:-5] + " is now Online!")
@client.event
async def on_message(message):
if message.author == client.user: # `if/else` doesn't need `()`
return
if message.content.lower().startswith(f"{CommandKey}gif"):
gif_url = get_gif(message.content.lower()[5:]) #Collects word after !gif
embed = discord.Embed()
embed.set_image(url=gif_url)
await message.channel.send(embed=embed)
# --- main ---
client.run(DiscordToken)
EDIT:
The same with downloading gif
to local computer memory (using io.BytesIO
) and sending as normal file.
import io
@client.event
async def on_message(message):
if (message.author == client.user):
return
if (message.content.lower().startswith(f"{CommandKey}gif")):
gif_url = get_gif(message.content.lower()[5:]) #Collects word after !gif
# download image from url
response = requests.get(gif_url)
# put it in file-like object in memory
file_like_object = io.BytesIO(response.content)
#file_name = 'image.gif'
file_name = gif_url.split('/')[-1]
# send it as normal file
# it needs filename with extension `.gif` to display it as GIF image
await message.channel.send(file=discord.File(file_like_object, filename=file_name))
It need longer time to display because it have to get it to local computer and then send it to internet.
It could be used to edit image (ie. add text, change color, draw figures) using pillow, wand, gizeh, detect faces/peoples/object with opencv
, genererate videos with moviepy, etc.
BTW:
In answer to question How to make a canvas profile card in discord python bot? I use pillow
to add elements to image. But it is static image, not animated GIF which would need more work (with every frame separatelly)
Upvotes: 4