This code:
usr = await app.resolve_peer(uid)
udata = InputUser(user_id=usr.user_id, access_hash=usr.access_hash)
r = await app.invoke(functions.messages.DeleteChatUser(chat_id=chan, user_id=udata))
print(r)
Returns:
AttributeError: 'InputPeerChannel' object has no attribute 'to_bytes'
In docs:
class pyrogram.raw.functions.messages.DeleteChatUser**
Deletes a user from a chat and sends a service message on it.
Parameters:
chat_id (int 64-bit) – Chat ID.
user_id (InputUser) – User ID to be deleted.
revoke_history (bool, optional) – Remove the entire chat history of the specified user in this chat.
What`s wrong?
Maybe my udata in the wrong type?
I'm not sure, but "DeleteChatUser" it seems to only work for groups, not channels.
For groups maybe working code:
cid = -10083757838484 # Example group_id
usr = await app.resolve_peer(uid)
if cid < 0:
cid = cid * (-1) # Removing a minus from group_id
udata = InputUser(user_id=usr.user_id, access_hash=usr.access_hash)
r = await app.invoke(functions.messages.DeleteChatUser(chat_id=cid, user_id=udata))
print(r)
But I needed a solution for the channel, so I used:
r = await app.ban_chat_member(int(cid), int(usr))
Related
I have made a telegram member scraper and inviter with Python. It was successful on some tests, but there are times my accounts get banned with upon seeing this error message:
AttributeError: 'ChatForbidden' object has no attribute 'access_hash'
I'm not sure why would it show ChatForbidden if I am already an admin of a group. It's hard to test these as I had to buy new phone numbers every time.
Here's a sample and explanation of my code to invite members to a group:
# Log in into the telegram account
client = TelegramClient('Tg_scraper', api_id, api_hash)
chats = []
last_date = None
chunk_size = 200
groups = []
hash_list = []
# Get all the groups/channel of the account
result = client(GetDialogsRequest(
offset_date=last_date,
offset_id=0,
offset_peer=InputPeerEmpty(),
limit=chunk_size,
hash=0
))
chats.extend(result.chats)
# Puts all the group/channel into a list
i = 0
print('Enter a NUMBER to choose a group where the members will be invited into:')
for chat in chats:
try:
groups.append(chat)
hash_list.append(chat.access_hash)
print(f"({i})" + ' - ' + chat.title)
i += 1
except:
continue
g_index = input("Enter a Number: ")
target_group = groups[int(g_index)]
target_group_entity = InputPeerChannel(target_group.id, target_group.access_hash)
Upon the last line, target_group_entity = InputPeerChannel(target_group.id, target_group.access_hash) is where I encounter the error I have stated above. Upon receiving that error, I get banned.
Does this have something to do with permissions? Do new accounts get banned for botting? It works on my first few tests, but then now I can't invite. Thank you so much for anyone who could help in advance.
I am already an admin of a group
This error is unrelated to your permission level.
Upon the last line is where I encounter the error
Wrong. you encounter this error because you're not coding it right with types in mind, expecting all your .chats are groups. Telegram doesn't tell you what fields exactly have, as you see in this error.
You must use type checking to limit your chats objects to only what you expect, your try block is appending then erroring, so, rather than a plain:
except:
continue
you need to actually confirm it won't error when accessing fields.
print('Enter a NUMBER to choose a group where the members will be invited into:')
i = 0
for chat in chats:
if isinstance(chat, telethon.types.Channel):
if chat.broadcast: continue # ignore non-group
groups.append(chat)
hash_list.append(chat.access_hash)
print(f"({i})" + ' - ' + chat.title)
i += 1
g_index = input("Enter a Number: ")
target_group = groups[int(g_index)]
In telegram when I click Subscribers it shows me about 50 last users and about 150-200 deleted users.
I tried this:
async for user in client.iter_participants(chat_id):
if user.deleted:
print(user)
This gives me only last 50 users and 6-8 deleted users. I need all 150-200 deleted users. How can I get them?
I solved this problem using GetParticipantsRequest with offset parameter somehow like this:
from telethon.tl.functions.channels import GetParticipantsRequest
from telethon.tl.types import ChannelParticipantsSearch
chat_id = -123456
offset = 0
while True:
participants = await client(GetParticipantsRequest(
channel=chat_id,
filter=ChannelParticipantsSearch(''),
offset=offset,
limit=10000,
hash=0
))
deleted_users = []
for user in participants:
if user.deleted:
deleted_users.append(user)
if not deleted_users:
break
# doings with deleted_users
Not sure about iter_participants, but get_participants works in my case.
channel_id = -1234567890 # TODO: add channel id
users = client.get_participants(client.get_input_entity(channel_id))
for user in users:
if user.deleted:
print(user)
Here is the code I am doing and unable to find a way to put a message in a live broadcast.
from instabot import Bot
bot = Bot ()
bot.login(username = "XXXXXXX" , password = "XXXXXXXX")
Here is an example of a live broadcast :
example of the live broad cast
You just need to use the bot.send_message() function; e.g.,
bot = Bot()
bot.login(username=botusername, password=botpassowrd)
id = bot.get_user_id_from_username('Username')
text = 'This is a testing message by a bot made by Mr.troll_54'
bot.send_message(text, id)
If you want to sent messages to more than one account, use:
Username_list = ['name1','name2',....]
Id_list = []
for name in Username_list:
id = bot.get_user_id_from_username('Username')
Id_list.append(id)
bot.send_messages(text, Id_list)
I'm stuck on a pretty simple issue with peewee-async regarding JOINs, or perhaps I need to use a subquery, or prefetch... I can't figure it out what kind of query I need to do.
I have 2 database tables (parent/child):
class Group(PeeweeModel):
id = peewee.AutoField()
name = peewee.TextField()
class Channel(PeeweeModel):
id = peewee.AutoField()
name = peewee.TextField()
group = peewee.ForeignKeyField(Group, backref="channels")
I need to fetch 1 group object, and this object has multiple channel objects.
I tried:
q = Group.select(Group, Channel).join(Channel)
But my backref 'channels' is always a ModelQuery instance, not the actual resultset.
Full code
import asyncio
import peewee
import peewee_async
from peewee_async import Manager, PooledPostgresqlDatabase
database = PooledPostgresqlDatabase('test', max_connections=4, user='postgres', password='', host='127.0.0.1')
objects = peewee_async.Manager(database)
class PeeweeModel(peewee.Model):
class Meta:
database = database
class Group(PeeweeModel):
id = peewee.AutoField()
name = peewee.TextField()
class Channel(PeeweeModel):
id = peewee.AutoField()
name = peewee.TextField()
group = peewee.ForeignKeyField(Group, backref="channels")
Group.create_table()
Channel.create_table()
database.set_allow_sync(False)
async def handler():
# create 1 group object
group = await objects.create(Group, name="TestGroup")
# create 2 channel objects, assign to group
await objects.create(Channel, name="TestName1", group=group)
await objects.create(Channel, name="TestName2", group=group)
# Query 1 group, and hopefully it will have the channels
q = Group.select(Group, Channel).join(Channel)
results = await objects.execute(q)
for result in results:
print(result.channels) # problem: Channels is not a list of channel objects, but a `ModelSelect` instead
with objects.allow_sync():
Channel.drop_table(True)
Group.drop_table(True)
loop = asyncio.get_event_loop()
loop.run_until_complete(handler())
loop.close()
I was able to get help from an expert™ and the solution is to use prefetch():
async def handler():
# create 1 group object
group = await objects.create(Group, name="TestGroup")
# create 2 channel objects, assign to group
await objects.create(Channel, name="TestName", group=group)
await objects.create(Channel, name="TestName", group=group)
# Query 1 group, and hopefully it will have the channels
q = Group.select(Group)
groups = await objects.prefetch(q, Channel.select(Channel))
for group in groups:
print(group, group.channels) # channels is a list of channels.
with objects.allow_sync():
Channel.drop_table(True)
Group.drop_table(True)
Peewee will figure out the relationship (backref) by itself.
I have a requirement to create an automated password reset script. I created a custom field in order to try and track this and also hope I can access some of the standard fields. This script should find users with the following criteria:
The latest of any of the following 3 dates that are >= 90 days ago : Sign_Up, Forgot_Password, or custom:pwdCreateDate
I can't seem to find any boto3 cognito client ways of getting the information on this except for forgot password which shows up in admin_list_user_auth_events and that response doesn't include username in the response. I suppose since you provide username to get the events you can figure out a way to find the latest forgot password from the events and tie it to the username.
Has anyone else implemented any boto3 automation to set the account to force password reset based on any of these fields?
here is where i landed, take it with the understanding that coginito has some limitations which make true flawless password rotation difficult. Also know if you can make the script more efficient you should because in lambda you probably time out with more than about 350 users due to the 5RPS on the admin API.
Prerequisites : set the lambda function to 5 concurrency or you will exceed the limit of 5RPS. 1 mutable field in your cognito userpool attributes to put a date in. a custom lambda zip file that includes pandas saved to s3.
import os
import sys
# this adds the parent directory of bin so we can find the module
parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))
sys.path.append(parent_dir)
#This addes venv lib/python2.7/site-packages/ to the search path
mod_path = os.path.abspath(parent_dir+"/lib/python"+str(sys.version_info[0])+"."+str(sys.version_info[1])+"/site-packages/")
sys.path.append(mod_path)
import boto3
import datetime
import pandas as pd
import time
current_path = os.path.dirname(os.path.realpath(__file__))
# Use this one for the parent directory
ENV_ROOT = os.path.abspath(os.path.join(current_path, os.path.pardir))
# Use this one for the current directory
#ENV_ROOT = os.path.abspath(os.path.join(current_path))
sys.path.append(ENV_ROOT)
#if __name__ == "__main__":
def lambda_handler(event, context):
user_pool_id = os.environ['USER_POOL_ID']
idp_client = boto3.client('cognito-idp')
users_list = []
page_token = None
dateToday = datetime.datetime.today().date()
def update_user(user) :
idp_client.admin_update_user_attributes(
UserPoolId = user_pool_id,
Username = user,
UserStatus = 'RESET_REQUIRED',
UserAttributes = [
{
'Name': 'custom:pwdCreateDate',
'Value': str(dateToday)
}
]
)
users = idp_client.list_users(
UserPoolId = user_pool_id
)
for user in users['Users']: users_list.append(user['Username'])
page_token = users['PaginationToken']
while 'PaginationToken' in users :
users = idp_client.list_users(
UserPoolId = user_pool_id,
PaginationToken = page_token
)
for user in users["Users"]: users_list.append(user["Username"])
if 'PaginationToken' in users :
page_token = users['PaginationToken']
attrPwdDates = []
for i in range(len(users_list)) :
userAttributes = idp_client.admin_get_user(
UserPoolId = user_pool_id,
Username = users_list[i]
)
for a in userAttributes['UserAttributes'] :
if a['Name'] == 'custom:pwdCreateDate' :
attrPwdDates.append(datetime.datetime.strptime(a['Value'], '%Y-%m-%d %H:%M:%S.%f').date())
time.sleep(1.0)
list_of_userattr_tuples = list(zip(users_list, attrPwdDates))
df1 = pd.DataFrame(list_of_userattr_tuples,columns = ['Username','Password_Last_Set'])
authPwdDates = []
for i in range(len(users_list)) :
authEvents = idp_client.admin_list_user_auth_events(
UserPoolId = user_pool_id,
Username = users_list[i]
)
for event in authEvents['AuthEvents'] :
if event['EventType'] == 'ForgotPassword' and event['EventResponse'] == 'Pass' :
authPwdDates.append(event['CreationDate'].date())
break
time.sleep(1.0)
list_of_userauth_tuples = list(zip(users_list, authPwdDates))
df2 = pd.DataFrame(list_of_userauth_tuples,columns = ['Username','Password_Last_Forgot'])
df3 = df1.merge(df2,how='left', on = 'Username')
df3[['Password_Last_Set','Password_Last_Forgot']] = df3[['Password_Last_Set','Password_Last_Forgot']].apply(pd.to_datetime)
cols = ['Password_Last_Set','Password_Last_Forgot']
df4 = df3.loc[df3[cols].max(axis=1)<=pd.Timestamp.now() - pd.Timedelta(90, unit='d'), 'Username']
for i,r in df4.iterrows() :
update_user(r['Username'])