How to change a particular char in a string? - python

I am creating a discord bot that gives me gif when I say !gif in a particular channel. The problem I am facing is when I type # it cannot change itself to %23 as it is used in links. I just want a way to change # in the string to %23. Please help me for that. The whole code is given below. I am very new to python so if you want any other errors please fix it and also clean up the code.I am using the tenor API Thank you
Code :
import discord
import os
import json
import requests
import random
client = discord.Client()
global search_term_public
global url
search_term_public = "Rick Roll"
def tenor():
global url
# set the apikey
apikey = (os.getenv("TENORAPIKEY"))
# our test search
search_term = search_term_public
# get the GIFs for the search term
r = requests.get("https://g.tenor.com/v1/search?q=%s&key=%s&contentfilter=high" % (search_term, apikey))
if r.status_code == 200:
# load the GIFs using the urls for the smaller GIF sizes
top_8gifs = json.loads(r.content)
g = len(top_8gifs['results'])
i = random.randint(0,g)
if(i == g):
i = g-1
h = str(g)
f = str(i)
url = top_8gifs['results'][i]['media'][0]['gif']['url']
print("The number picked is " + f +" out of " + h + ". Search Term : " + search_term + ". Url : " +url)
else:
top_8gifs = None
return url
#client.event
async def on_ready():
print("Bot has successfully logged in as {0.user}".format(client))
#client.event
async def on_message(message):
global search_term_public
if message.author == client:
return
if message.content.startswith("!gif") and message.channel.id == 831789159587774504:
# put the search term into the public variable. split the content with space and the second or more than second word should be in a variable
tokens = message.content.split(' ')
if tokens.__contains__(""):
tokens.remove("!gif")
tokens.remove("")
elif tokens.__contains__("#"):
# I want to change # in the token and change it to %23
print()
else :
tokens.remove("!gif")
search_term_public = ("".join(tokens))
if search_term_public == "":
search_term_public = "Rick Roll"
await message.channel.send("You got rick rolled!")
url = tenor()
await message.channel.send(url)
client.run(os.getenv("DISCORDTOKEN"))

Try this, it might work
You can just use the "replace" as follows
elif tokens.__contains__("#"):
token=token.replace("#","%23")

You want to look at
url encoding probably.
However, to directly answer the question as a hotfix, I think you can do this directly after the .split() line
tokens = [token.replace('#', '%23') for token in tokens]

Related

Cant reply json on discord.py

Im making a cripto price tracker and i cant make it reply the json that im making with the coin decko URL and Arg1 for example Eternal or SLP, etc.
# bot = scrt.bot
bot = commands.Bot(command_prefix = "!")
login = 0
tokens_dict = {
'morw' : '0x6b61b24504a6378e1a99d2aa2a5efcb1f5627a3a',
'slp' : '0xcc8fa225d80b9c7d42f96e9570156c65d6caaa25',
'pvu' : '0x31471e0791fcdbe82fbf4c44943255e923f1b794',
'eternal' : '0xd44fd09d74cd13838f137b590497595d6b3feea4'
}
# Login
#bot.event
async def on_ready():
global login
print('We have logged in as {0.user}'.format(bot))
login = 1
#bot.command()
async def coin(ctx, arg1):
global tokens_dict
if(arg1 in tokens_dict.keys()):
url = 'https://api.pancakeswap.info/api/v2/tokens/' + tokens_dict[arg1]
response = request.get(url)
responseDict = json.loads(response.text)
await ctx.reply(responseDict)
else:
await ctx.reply("The token " + str(arg1) + " is not in the token list, if you want to add " + str(arg1) + " to the list please use the command : " + '\n' + "!add_token")
In the coin function im trying to reply the json that ive created but i dont know how to.
response = request.get(url)
responseDict = json.loads(response.text)
await ctx.reply(responseDict)
I'm assuming this is the part you're talking about.
You actually don't need to call json.loads(response.text) if you're going to send it anyway. If the raw response is unformatted then you can do this
response_dict = json.loads(response.text)
formatted_dict = json.dumps(response_dict, indent=4)
await ctx.reply(formatted_dict)
This should send the json as a string with indents.
The reason discord.py wasn't letting you send the message was because it wasn't a string.

"Invalid Form Body In embed.fields.0.value: This field is required", however I am fairly certain the field is not empty

import os
from keep_alive import keep_alive
from discord.ext import commands
import time
import requests
from bs4 import BeautifulSoup
from datetime import datetime
import discord
bot = commands.Bot(
command_prefix="!", # Change to desired prefix
case_insensitive=True # Commands aren't case-sensitive
)
bot.author_id = 581512730343637083 # Change to your discord id!!!
channelID = "688698168996921368"
#bot.event
async def on_ready(): # When the bot is ready
print("I'm in")
print(bot.user) # Prints the bot's username and identifier
while True:
time.sleep(2)#
updateEmbedSaved = check_update()
if channelID != None and updateEmbedSaved != None:
try:
channel = bot.get_channel(int(channelID))
await channel.send(embed=updateEmbedSaved)
except Exception as e:
print(e)
pass
def check_update():
todayDate = datetime.today().strftime('%Y.%m.%d')
todayDate = "2021.06.08"
csgoPage = requests.get("https://blog.counter-strike.net/index.php/category/updates/")
html = csgoPage.text
soup = BeautifulSoup(html, 'html.parser')
dateElems = soup.find_all('p', class_="post_date")
if dateElems[0].text[:10] == todayDate:
with open("detected.txt") as f:
data = f.readline()
if data != todayDate:
print("True")
todayDateSplice = f"/{todayDate[:4]}/{todayDate[5:7]}/"
linkElems = soup.find_all('a', href=True)
for index, linkElem in enumerate(linkElems):
link = linkElem['href']
if todayDateSplice in link:
correctLink = link
break
csgoPage = requests.get(correctLink)
html = csgoPage.text
soup = BeautifulSoup(html, 'html.parser')
titleElems = soup.find_all('h2')
updateEmbed = discord.Embed(title=f"Update Detected: {titleElems[0].text}", color=0x00ff55)
updateEmbed.set_thumbnail(url='https://cdn.akamai.steamstatic.com/steam/apps/730/capsule_616x353.jpg?t=1623182945')
updateEmbed.set_author(name="CS:GO Update Detected")
updateEmbed.set_footer(text="CS:GO Update Checker Bot | Information from https://blog.counter-strike.net/")
paraElems = soup.find_all('p')
paraElems = paraElems[:len(paraElems)-4]
for elem in paraElems:
print(elem.text, "\n-------------")
body = "\n".join(elem.text.split("\n")[1:])
if body != None and elem.text.split("\n")[0] != None:
try:
updateEmbed.add_field(name=elem.text.split("\n")[0], value=body, inline=False)
except:
pass
with open('detected.txt', 'w') as file:
file.writelines(todayDate)
return updateEmbed
else:
print("False")
print(dateElems[0].text[:10])
print(todayDate)
keep_alive() # Starts a webserver to be pinged.
token = os.environ.get("DISCORD_BOT_SECRET")
bot.run(token) # Starts the bot
Can someone please help me, the error is called when the embed is being sent, and the try except catches it, but the embed is not sent. I have checked that the values going into fields are not empty, yet I still get the error:
"400 Bad Request (error code: 50035): Invalid Form Body
In embed.fields.0.value: This field is required"
Can someone help?
I don't know if it works but try this
Change line 78 with this:
updateEmbed.add_field(name=elem.text.split("\n"), value=body, inline=False)
I deleted the specific index brackets, but if you want a specific index from it, I really don't know.

How to make a loop for API calls Constantly?

I am wondering how do u make a loop for an api call that will keep calling that API, but when I tried making one it didn't work here is the code:
while True:
api_requesting = requests.get("https://api.battlemetrics.com/servers/3411152?include=player", headers=headers)
time.sleep(5)
jsoned_api = api_requesting.json()
function = jsoned_api["included"]
names = []
for person in function:
names.append(person['attributes']['name'])
And this is for e to call upon the request, and parsed it to give me the names of each player etc
#client.command(name='players')
async def createEmbed(ctx):
await ctx.send(f"{len(names)} players are online currently")
urString = ""
for name in names:
urString = urString + "> " + name + "\n"
urString = "```" + urString + "```"
await ctx.send(urString)
So I am wondering how will I make a loop for my request it's all the way at the beginning where it says while true: but when I run it the bot doesn't respond, and doesn't do anything.
If you want your code to stop when the bot does not respond:
success = True
while success:
api_requesting = requests.get("https://api.battlemetrics.com/servers/3411152?include=player", headers=headers)
# Success is True when the response status code is 200
success = api_requesting.status_code==200
But if you want to keep making requests, you can try:
while True:
api_requesting = requests.get("https://api.battlemetrics.com/servers/3411152?include=player", headers=headers)
if api_requesting.status_code == 200:
# Do something when the bot responds
else:
time.sleep(5)
# Do something else when the bot does not respond

Problem with importing discord.py modules

StackOverflow.
I've been having a problem with a discord bot, here's the script:
def send():
url = "https://discordapp.com/api/webhooks/762125650546131005/lgYkjh-ILrag2sb3nzqUZfF1sg2mN2a0QeABaUq9dwl7qBTNL4EqWV00K62xWZ8_sNQ5"
data = {}
data["content"] = ""
data["username"] = "Suggestions"
data["embeds"] = []
embed = {}
embed["description"] = "**Author** » <#" + str(message.author.id) + ">\n **Suggestion** » " + str(args)
embed["title"] = "**New Suggestion!**"
data["embeds"].append(embed)
result = requests.post(url, data=json.dumps(data), headers={"Content-Type": "application/json"})
send()
await message.author.send("Thank you for your suggestion! We will look into it as soon as possible and will message you if it will be used.")
When I do ";suggestion fix bugs" it just sends to the webhook "fix" which is only the first word and I am struggling to fix this. Please may someone help?
Don't use requests with discord.py, it is sync and will block your bot, use a discord.Webhook with aiohttp to send a discord.Embed
Example:
from aiohttp import ClientSession
async with ClientSession() as session:
wh = discord.Webhook.from_url("<webhook url>", adapter=discord.AsyncWebhookAdapter(session))
e = discord.Embed()
e.title = "Hello I am an Embed"
...
await wh.send(embed=e)

Calling with discord to write in a fileI have aa

I have a script, a discord bot such that when I write !add --insert link here-- it would add text line of link in products.txt file, and !remove would remove existing one.
Problem happens when I try to add something, it sometimes adds multiple lines of the same thing. Such as !add www.google.com writes three lines of it, sometimes one.
Here's my code:
#bot.event
async def on_message(message):
if message.author == bot.user: return
author = message.author
content = message.content
channel = message.channel
if "!add" in content:
content = str(content)
url = content.strip("!add")
url = url.replace(" ", "")
botmessage = "Added URL: " + url
with open("products.txt", "a") as txtfile:
txtfile.write(url+"\n")
print(botmessage)
await message.channel.send(botmessage)
elif "!remove" in content:
content = str(content)
print(content)
urls = content.split(" ")
url = urls[1]
print(url)
txtfile = open("products.txt", "r")
url_links = txtfile.readlines()
txtfile.close()
with open("products.txt", "w") as txt:
for link in url_links:
if url != link:
txt.write(link)
else:
print("found it")
botmessage = "Removed URL: " + url
print("remove")
await message.channel.send(botmessage)

Categories