Warn command discord.py postgres sql error - sql

So i made a warn command from a youtube tutorial for my discord bot from https://www.youtube.com/channel/UCBwVvFWzp01YMD9ibqhSkEg
and i got this error
data = await self.bot.db.fetchrow("SELECT * FROM warnlogs WHERE
guild_id = $1 AND member_id = $2", guild_id, member_id)
AttributeError: 'Connection' object has no attribute 'fetchrow'
code:
import datetime
import discord
import asyncpg
from discord.ext import commands
class Warn(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.bot.loop.run_until_complete(self.create_db_pool())
#commands.Cog.listener()
async def on_ready(self):
await self.db.execute(
"CREATE TABLE IF NOT EXISTS warnlogs (guild_id BIGINT, member_id BIGINT, warns TEXT[], times DECIMAL[])")
print("warn system ready")
async def create_db_pool(self):
self.db = await asyncpg.create_pool(database="warn", user="postgres", password="")
#self.bot.db = await asyncpg.create_pool(database_url, ssl="require") when hosting the bot
async def warn_log(self, guild_id, member_id):
data = await self.bot.db.fetchrow("SELECT * FROM warnlogs WHERE guild_id = $1 AND member_id = $2", guild_id, member_id)
if not data:
return []
return data
async def warn_entry(self, guild_id, member_id, reason, times):
data = await self.warn_log(guild_id, member_id)
if data == []:
await self.bot.db.execute("INSERT INTO warnlogs (guild_id, member_id, warns, times) VALUES ($1, $2, $3, $4)", guild_id, member_id, [reason], [times])
return
warns = data[2]
times = data[3]
warns.append(reason)
times.append(times)
await self.bot.db.execute("UPDATE warnlogs SET times = $1, warns = $2 WHERE guild_id = $3 AND member_id = $4", times, warns, guild_id, member_id)
#commands.command()
async def warn(self, ctx, member: discord.Member, *, reason="No reason provided"):
if member == ctx.author or member == self.bot.user:
return await ctx.send("You cant mute yourself or the bot.")
await self.warn_entry(ctx.guild.id, member.id, reason, ctx.message.created_at.timestamp())
await ctx.send(f"{ctx.author.name} has warned {member.name} \nReason: {reason}")
data = await self.warn_log(ctx.guild.id, member.id)
count = len(data[3])
embed = discord.Embed(title=f"Warned by {ctx.author.name}", colour=discord.Colour.red(), timestamp=datetime.datetime.utcnow())
embed.add_field(name="Reason", value=reason)
embed.add_field(name="Total warns", value=f"**{count}** warns\n More than 5 warns a week can have serious consequences.")
embed.set_thumbnail(url=ctx.author.avatar_url)
try:
await member.send(embed=embed)
except:
pass
def setup(bot):
bot.add_cog(Warn(bot))
so is there any way to fix this error if so can you please send the rewritten code it would be very helpful.🙏 And thank you for your time.😊

From what I can see you create connection pool into 'self.db'.
self.db = await asyncpg.create_pool(database="warn", user="postgres", password="")
But then you are calling fetchrow function on 'self.bot.db', which doesn't contain your connection pool. You have to call 'self.db.fetchrow' instead of 'self.bot.db.fetchrow'.
Change this:
data = await self.bot.db.fetchrow("SELECT * FROM warnlogs WHERE guild_id = $1 AND member_id = $2", guild_id, member_id)
For this:
data = await self.db.fetchrow("SELECT * FROM warnlogs WHERE guild_id = $1 AND member_id = $2", guild_id, member_id)
And you should change 'self.bot.db.execute' to 'self.db.execute'.
Once you are hosting bot you will have to uncomment this part:
#self.bot.db = await asyncpg.create_pool(database_url, ssl="require") when hosting the bot
And use 'self.bot.db' instead of 'self.db'.

Related

Telethon "DestroySessionRequest" method not work

I try destoy every new session.
I run main script, save all exist session to variable
all_session = await client(functions.account.GetAuthorizationsRequest())
hash_list = [x.hash for x in all_session.authorizations]
after i run and search for new session
if i got new session - i try destroy it
while True:
await asyncio.sleep(15)
all_new = await client(functions.account.GetAuthorizationsRequest())
new_hashes = [x.hash for x in all_new.authorizations]
for h in new_hashes:
if h not in hash_list:
logger.debug(f"have a new hash {h}")
try:
result = await client(functions.DestroySessionRequest(
session_id=-h
))
logger.debug(f"DROP RESULT IS: {result.stringify()}")
except Exception as e:
logger.debug(
f"error - {e}")
Every time then i try i got as response
DestroySessionNone(
session_id=3806172788422661047
)
i also tried use this method without "-", same result
try:
result = await client(functions.DestroySessionRequest(
session_id=-h
))
logger.debug(f"DROP RESULT IS: {result.stringify()}")
except Exception as e:
logger.debug(
f"error - {e}")

telethon :A wait of 16480 seconds is required (caused by ResolveUsernameRequest)

i'm trying to use telethon to send messages to telegram groups. after some times runing, it reruens:
A wait of 16480 seconds is required (caused by ResolveUsernameRequest).
the code is:
async def main():
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
config = configparser.ConfigParser()
config.read("seetings.ini",encoding= 'utf-8')
message = config['Customer']['message']
internal = config['Customer']['internal']
count = 0
excel_data = pandas.read_excel('tg_groups.xlsx', sheet_name='Groups')
for column in excel_data['GroupUsername'].tolist():
try:
if str(excel_data['GroupUsername'][count]) == 'None':
count += 1
continue
else:
chat = await client.get_input_entity(str(excel_data['GroGroupUsernameupID'][count]))
await client.send_message(entity=chat, message=message)
except Exception as e:
print(e)
time.sleep(int(internal))
count = count + 1
continue
time.sleep(int(internal))
count = count + 1
if __name__ == '__main__':
if proxytype == 'HTTP':
print('HTTP')
client = TelegramClient('phone'+phone, api_id, api_hash, proxy=(socks.HTTP, 'localhost', int(proxyport))).start()
if proxytype == 'socks5':
print('SOCKS5')
client = TelegramClient('phone'+phone, api_id, api_hash, proxy=(socks.SCOKS5, 'localhost', int(proxyport))).start()
myself = client.get_me()
print(myself)
freqm = config['Customer']['freq']
print(int(freqm))
while True:
with client:
client.loop.run_until_complete(main())
time.sleep(int(freqm))`
`
from the 'Entity' guide, it says get_input_entity method will search the user info from session file cache, why it it still call the 'ResolveUsernameRequest'to get the user info? anything i missed?
thanks for any advice.
'Entity' guide, it says get_input_entity method will search the user info from session file cache, why it it still call the 'ResolveUsernameRequest'to get the user info? anything i missed or the session file didn't keep the user info cache?

how to run an external function with variables from State?

this function must be run in the file where the bot is located
def start_pars():
from mainaio import data
username_input = driver.find_element(By.XPATH,
'/html/body/div/div/main/div/div/div/div[1]/form/div[1]/div[1]/div/input')
username_input.clear()
username_input.send_keys(data["username"])
pass_input = driver.find_element(By.XPATH,
'/html/body/div/div/main/div/div/div/div[1]/form/div[1]/div[2]/div/input')
pass_input.clear()
pass_input.send_keys(data["password"])
driver.find_element(By.XPATH, '/html/body/div/div/main/div/div/div/div[1]/form/div[2]/button').click()
time.sleep(1)
username1 = driver.find_element(By.XPATH, '/html/body/div[1]/nav[2]/div[2]/div/div[2]/div[2]/div')
print(username1.text)
less1 = []
lessundscore = driver.find_elements(By.XPATH, '/html/body/div[1]/div/main/div/div[2]/div/div[3]/div[1]')
for value in zip(lessundscore):
less1 += value
for val in less1:
print(val.text)
return username1, less1
items from the state must be transferred to the sending keys
class Registration(StatesGroup):
username = State()
password = State()
username = message.text
await state.update_data(username=username)
assword = message.text
await state.update_data(password=password)
data = await state.get_data()
I tried to run in the last registration function start_pars(data['username'], data['password'])

the post sent by the bot telegram is not deleted for all users

I have a function which allows to send a message to all users who clicked the start button.
#dp.message_handler(commands=['Yes'], state=Post.send_post)
async def process_name(message: Message, state: FSMContext):
for admin in admins:
if message.from_user.id == admin:
async with state.proxy() as data:
data['send_post'] = message.text
conn = sqlite3.connect('data.db')
cur = conn.cursor()
cur.execute(f'SELECT * FROM users')
result = cur.fetchall()
await state.finish()
print(result)
try:
for z in range(len(result)):
print(result[z][0])
await dp.bot.send_photo(chat_id=result[z][0], photo=data['photo'], caption=data['CAPTHION'], reply_markup=kb)
print(z)
test = message.message_id + 1
await dp.bot.send_message(chat_id=result[z][0], text=f'id поста {test}')
except BotBlocked:
print('Пользователь заблокировал бота')
except ChatNotFound:
print('Пользователь не запускал бота')
Also, there is a function that allows you to delete messages by id. The administrator enters the deleted command, after which the bot asks to enter its id. When the Administrator enters an id, the bot deletes messages through a loop, iterating over the id. But for some reason, it only deletes a post from one user, then it throws an error
aiogram.utils.exceptions.MessageToDeleteNotFound: Message to delete not found
Please help me I can't figure out why
#dp.message_handler(commands=['deleted'], state=None)
async def send_id(message: Message):
for admin in admins:
if message.from_user.id == admin:
await Post.Sen_id.set()
await dp.bot.send_message(chat_id=admin, text='Введите ID поста, который нужно удалить.')
await Post.next()
#dp.message_handler(state=Post.del_mess)
async def deleted_post(message: Message, state: FSMContext):
for admin in admins:
if message.from_user.id == admin:
async with state.proxy() as data:
data['sen_id'] = message.text
try:
conn = sqlite3.connect('data.db')
cur = conn.cursor()
cur.execute(f'SELECT * FROM users')
result = cur.fetchall()
#message_ids = int(data['sen_id'])
for z in range(len(result)):
print('/////////////deleted/////////////')
print(result)
print(z)
await dp.bot.delete_message(chat_id=result[z][0], message_id=data['sen_id'])
print('Сообщение удалено')
#chat_id = message.chat.id
#await dp.bot.delete_message(message.chat.id, message_ids)
await dp.bot.send_message(chat_id=admin, text='пост удален')
except BotBlocked:
print('Пользователь заблокировал бота')
except ChatNotFound:
print('Пользователь не запускал бота')
This is a code that does what you wish for - deleting message with given message_id in every chat where that message exist. Later I'll explain why this is actually not a good solution.
The problem is with the placing of the try-except block. In your code, if deleting the message fails for a single user, for all users that are past him in the database the deletion will not be even attempted. Solution would be to place the try-except block in the for loop.
...
if message.from_user.id == admin:
async with state.proxy() as data:
data['sen_id'] = message.text
conn = sqlite3.connect('data.db')
cur = conn.cursor()
cur.execute(f'SELECT * FROM users')
result = cur.fetchall()
#message_ids = int(data['sen_id'])
for z in range(len(result)):
try:
print('/////////////deleted/////////////')
print(result)
print(z)
await dp.bot.delete_message(chat_id=result[z][0], message_id=data['sen_id'])
print('Сообщение удалено')
#chat_id = message.chat.id
#await dp.bot.delete_message(message.chat.id, message_ids)
await dp.bot.send_message(chat_id=admin, text='пост удален')
except BotBlocked:
print('Пользователь заблокировал бота')
except ChatNotFound:
print('Пользователь не запускал бота')
except Exception as e:
print(e)
...
However, after testing this approach, I believe you will realise that there is a problem: if you send a "post" to multiple users, it may have a different message_id for different users! So you would have to use a different approach.

telethon how to request call with code for login

Since I am writing a client, my friends from the USA noticed that the code does not go through SMS, but only through a call. but I don’t understand how to do it, how to request a call(
await client.connect()
code_settings = types.CodeSettings(
current_number=True,
allow_flashcall=False,
allow_app_hash=False
)
result = await client(functions.auth.SendCodeRequest(
phone_number=phone,
api_id=api_id,
api_hash=api_hash,
settings=code_settings
))
# time.sleep(10)
result = await client(functions.auth.ResendCodeRequest(
phone_number=phone,
phone_code_hash=result.phone_code_hash
))
# time.sleep(20)
result = await client(functions.auth.ResendCodeRequest(
phone_number=phone,
phone_code_hash=result.phone_code_hash
))
# result = await client(SentCodeTypeCall(5))
# result = await client(functions.auth.)
while not isinstance(result.type, SentCodeTypeCall):
# time.sleep(10)
result = await client(functions.auth.ResendCodeRequest(
phone_number=phone,
phone_code_hash=result.phone_code_hash
))
# time.sleep(20)
# await client(functions.auth.SendCodeRequest(
# phone_number=phone,
# api_id=api_id,
# api_hash=api_hash,
# settings=code_settings
# ))
def code_callback():
code = input('Please enter the code you received: ')
return code
time.sleep(5)
await client.start(phone=phone, code_callback=code_callback)
I assume this is not the correct code.
can I tell the SendCode Request method to call immediately without sending SMS?