Is there any method to send stickers using the id attribute of event.file? The documentation points out to send it using the id and the access_hash of a particular sticker set and then finally using index with sticker_set to send the sticker. Since there's unique id for particular sticker stored in telegram servers, I was wondering if there's any method of using that to send stickers?
from telethon.tl.functions.messages import GetAllStickersRequest
sticker_sets = await client(GetAllStickersRequest(0))
# Choose a sticker set
from telethon.tl.functions.messages import GetStickerSetRequest
from telethon.tl.types import InputStickerSetID
sticker_set = sticker_sets.sets[0]
# Get the stickers for this sticker set
stickers = await client(GetStickerSetRequest(
stickerset=InputStickerSetID(
id=sticker_set.id, access_hash=sticker_set.access_hash
)
))
# Stickers are nothing more than files, so send that
await client.send_file('me', stickers.documents[0])
You must send the sticker as an InputDocument, specifying the sticker id, access_hash and file_reference.
from telethon import types
# some code here
await event.reply(
file = types.InputDocument(
id = YOUR_STICKER_ID,
access_hash = YOUR_STICKER_ACCESS_HASH,
file_reference = YOUR_STICKER_FILE_REFERENCE
)
)
# more code
For example, reply to "/sticker" new message:
from telethon import events, types
# Reply to new message /sticker
#client.on(events.NewMessage(pattern=r'/sticker'))
await event.reply(
file = types.InputDocument(
id = YOUR_STICKER_ID,
access_hash = YOUR_STICKER_ACCESS_HASH,
file_reference = YOUR_STICKER_FILE_REFERENCE
)
)
Related
I am currently working on a system that deletes a channel when the user leaves. This system works by, when a user asks for it, a command is used to create the channel and the member id and channel id are stored in mongodb, as shown in the picture below:
My current code for this is:
#commands.Cog.listener()
async def on_member_remove(self, member):
channelfind = cluster["Channels"]["info"]
if member.guild.id == testid:
joinedat = diskord.utils.utcnow() - member.joined_at
time = humanize.precisedelta(joinedat, format="%0.0f")
embed = diskord.Embed(title="\u200b", color=0xfc8eac)
embed: Embed = diskord.Embed(
description= f'**{member.mention} left the server**\n:timer: **Joined:**\n{time} ago',
color=0xfc8eac
)
embed.set_author(name=member, icon_url=member.avatar.url)
embed.set_thumbnail(url=member.avatar.url)
embed.timestamp = datetime.datetime.utcnow()
embed.set_footer(text=f'ID: {member.id} \u200b ')
memberid = channelfind.find_one({"member_id": member.id})
if memberid is not None:
log = testlog
await self.bot.get_channel(log).send(embed=embed)
else:
pass
However, I am not sure how I can find the channel_id that is with the member_id of the user who has left
Any help would be appreciated thank you!
.find_one() returns a dictionary representing the document. So, you can do
memberid = channelfind.find_one({"member_id": member.id})
print(memberid['channel_id'])
to get the channel_id.
Im trying to make a ticket bot, and this is currently what i have. Now that i can make the bot create a channel after detecting a reaction, i need to be able to make it close the ticket on another reaction, as well as other features iw ant to add. But this reaction is in the channel created so i dont know how to get that channel id created. Someone suggested me to use cogs, but have no idea where to start.
async def on_raw_reaction_add(payload):
channel = payload.channel_id
if channel == 862711339298455563:
guildid = payload.guild_id
guild = client.get_guild(guildid)
channel = guild.get_channel(payload.channel_id)
message = channel.get_partial_message(payload.message_id)
emoji = '🎟️'
member = payload.member
payloaduserid = payload.user_id
clientuserid = client.user.id
if payloaduserid != clientuserid:
await message.remove_reaction(emoji, member)
category = client.get_channel(861003967000215583)
channel1 = await guild.create_text_channel(f'ticket {payload.user_id}', category = category )
ticketembed = discord.Embed(
title = f'Ticket - {payload.user_id}',
description = '- If you want to tag the admins please react with :telephone: \n - To report this message please react with :warning: \n - To close the ticket react this mesaage with :x: ',
color = discord.Color.red())
ticketembed.set_footer(text = 'All of the conversation will be held in the archives, eventhought a moderator can delete a message in this channel, a copy of it will be held in a location where only the owner can access.')
user = client.get_user(payload.user_id)
await channel1.set_permissions(target=user, read_messages=True , send_messages=True)
ticketembed1 = await channel1.send(embed= ticketembed)
await ticketembed1.add_reaction('☎️')
await ticketembed1.add_reaction('⚠️')
await ticketembed1.add_reaction('❌')
await channel1.send(f'{user.mention}', delete_after = 0.1) ```
One method is checking the channel name format. sometimes getting the channel from cache is not an option so we might need to fetch it.
async def on_raw_reaction_add(payload):
channel = client.get_channel(payload.channel_id)
# if channel is not in cache then fetch is using a API request
if not channel:
channel = await client.fetch_channel(channel_id)
# The user is the owner of the ticket since it is his id
if channel.name == f"ticket {payload.user_id}":
emoji = payload.emoji.name
# delete
if emoji == "❌":
await channel.delete()
It is better to save channel id and then use it since channel name can be changed. You can get the id like this.
channel1 = await guild.create_text_channel(f'ticket {payload.user_id}', category = category )
print(channel1.id)
I'm new to python and i'm making discord bot. So here i have twitch notification function, but when someone is live bot just starts spamming, i think because idk how to get content out of an embed. please help me. the code:
import os
import json
import discord
import requests
from discord.ext import tasks, commands
from discord.utils import get
intents = discord.Intents.all()
bot = commands.Bot(command_prefix='$', intents=intents)
TOKEN = os.getenv('token')
# Authentication with Twitch API.
client_id = os.getenv('client_id')
client_secret = os.getenv('Dweller_token')
body = {
'client_id': client_id,
'client_secret': client_secret,
"grant_type": 'client_credentials'
}
r = requests.post('https://id.twitch.tv/oauth2/token', body)
keys = r.json()
headers = {
'Client-ID': client_id,
'Authorization': 'Bearer ' + keys['access_token']
}
'''user_info = twitch.get_users(logins=['turb4ik'])
user_id = user_info['data'][0]['id']
print(user_info)'''
# Returns true if online, false if not.
def checkuser(streamer_name):
stream = requests.get('https://api.twitch.tv/helix/streams?user_login=' + streamer_name, headers=headers)
stream_data = stream.json()
if len(stream_data['data']) == 1:
return True, stream_data
else:
return False, stream_data
# Executes when bot is started
#bot.event
async def on_ready():
# Defines a loop that will run every 10 seconds (checks for live users every 10 seconds).
#tasks.loop(seconds=10)
async def live_notifs_loop():
# username = stream_data['data'][0]['user_name']
# stream_title = stream_data['data'][0]['title']
# game_being_played = stream_data['data'][0]['game_name']
# Opens and reads the json file
with open('streamers.json', 'r') as file:
streamers = json.loads(file.read())
# Makes sure the json isn't empty before continuing.
if streamers is not None:
# Gets the guild, 'twitch streams' channel, and streaming role.
guild = bot.get_guild(690995360411156531)
channel = bot.get_channel(798127930295058442)
role = get(guild.roles, id=835581408272580649)
# Loops through the json and gets the key,value which in this case is the user_id and twitch_name of
# every item in the json.
for user_id, twitch_name in streamers.items():
print("checking" + " " + str(twitch_name))
# Takes the given twitch_name and checks it using the checkuser function to see if they're live.
# Returns either true or false.
status, stream_data = checkuser(twitch_name)
# Gets the user using the collected user_id in the json
user = bot.get_user(int(user_id))
# Makes sure they're live
if status is True:
# Checks to see if the live message has already been sent.
async for message in channel.history(limit=200):
print("yes")
twitch_embed = discord.Embed(
title=f":red_circle: **LIVE**\n{user.name} is now streaming on Twitch! \n \n {stream_data['data'][0]['title']}",
color=0xac1efb,
url=f'\nhttps://www.twitch.tv/{twitch_name}'
)
twitch_embed.add_field(
name = '**Game**',
value = stream_data['data'][0]['game_name'],
inline = True
)
twitch_embed.add_field(
name = '**Viewers**',
value = stream_data['data'][0]['viewer_count'],
inline = True
)
twitch_embed.set_author(
name = str(twitch_name),
icon_url = stream_data['data'][0]['thumbnail_url']
)
twitch_embed.set_image(url = f'https://www.twitch.tv/{twitch_name}')
print("yes2")
try:
embed_title = twitch_embed.title
embed_description = twitch_embed.description
except Exception as e:
break
print("yes3")
# If it has, break the loop (do nothing).
if embed_title == True:
break
# If it hasn't, assign them the streaming role and send the message.
else:
# Gets all the members in your guild.
async for member in guild.fetch_members(limit=None):
# If one of the id's of the members in your guild matches the one from the json and
# they're live, give them the streaming role.
if member.id == int(user_id):
await member.add_roles(role)
# Sends the live notification to the 'twitch streams' channel then breaks the loop.
await channel.send(
content = f"Hey #everyone! {user.name} is now streaming on Twitch! Go check it out: https://www.twitch.tv/{twitch_name}", embed=twitch_embed)
print(f"{user} started streaming. Sending a notification.")
break
# If they aren't live do this:
else:
# Gets all the members in your guild.
async for member in guild.fetch_members(limit=None):
# If one of the id's of the members in your guild matches the one from the json and they're not
# live, remove the streaming role.
if member.id == int(user_id):
await member.remove_roles(role)
# Checks to see if the live notification was sent.
async for message in channel.history(limit=200):
try:
embed_title = message.embeds[0].title
embed_description = message.embeds[0].description
except Exception as e:
break
# If it was, delete it.
if user.mention in embed_title and "is now playing" in embed_title:
print(f"{user} stopped streaming. Removing the notification.")
await message.delete()
# Start your loop.
live_notifs_loop.start()
# Command to add Twitch usernames to the json.
#bot.command(name='addtwitch', help='Adds your Twitch to the live notifs.', pass_context=True)
async def add_twitch(ctx, twitch_name):
# Opens and reads the json file.
with open('streamers.json', 'r') as file:
streamers = json.loads(file.read())
# Gets the users id that called the command.
user_id = ctx.author.id
# Assigns their given twitch_name to their discord id and adds it to the streamers.json.
streamers[user_id] = twitch_name
# Adds the changes we made to the json file.
with open('streamers.json', 'w') as file:
file.write(json.dumps(streamers))
# Tells the user it worked.
await ctx.send(f"Added {twitch_name} for {ctx.author} to the notifications list.")
print('Server Running')
bot.run(TOKEN)
Just for others context, he had shown me the error on discord, so I am answering him through this question!
So mate, I found the error.
The line 106 in your code is:
await message.channel.send(msg)
Now this msg variable send all the details but we just want the content of it and not anything else.
So change that to:
await message.channel.send(msg.content)
Thank You! :D
So I'm working on a bot, and I'd like it to have it's own ticket support system.
What I'd like it to do is that, upon receiving a DM it:
- Creates a new channel named after the DM author (such as #David0001) in a "ticket" category
- Sets up permissions for that channel to be only accessible to read and write by the DM author (and admins ofc)
- Restranscribes whatever the DM author wrote in his DM
I'm currently using the latest Async discord.py branch (I know I should probably be using rewrite but oh well)
#client.event
async def on_message(message):
if message.server is None and message.author != client.user:
server = client.get_server("serverid")
for channel in server.channels:
if channel.name == str(message.author):
await client.send_message(message.author, "Hey you already have a support ticket open!")
break
else:
await client.create_channel(server, str(message.author), type=discord.ChannelType.text)
overwrite = discord.PermissionOverwrite()
overwrite.read_messages = True
overwrite.send_messages = True
overwrite.ban_members = False
for channel in server.channels:
if channel.name == str(message.author):
await client.edit_channel_permissions(channel.id, message.author, overwrite)
await client.send_message(channel.id, message.content)
break
else:
break
break
await client.process_commands(message)
I'd also like it to verify first if a support channel with the users name doesn't already exist and if so to send a little message like "hey you already have a support ticket channel open"
This code seems to work at first but not well, it does create a "david0001" channel upon DM, however it doesn't set up the permissions properly, doesn't set it up in a pre-existing ticket catgeory (cause I don't know how to do that), it does not retranscribe whatever the user wrote in the DMs and it does not verify if the user has a open channel, it just keeps making a new one
There is multiple solutions that can be proposed for your situation :
As the old async branch is depreciated, here is the up to date code.
Through a command :
I assume you're using a cog system :
This is a command designed for your request, when the user uses it, it inspect the support server, if there is no Support category, it creates one, and creates a channel for the user. If the requirement already exist it just send the message stored in request into the correct channel.
import asyncio, discord
from discord.ext import commands
from discord.utils import get
class Cmd_support(commands.Cog):
def __init__(self, client):
self.client = client
#commands.command()
async def support(self, ctx, *, request: str):
user = ctx.message.author
guild_id = 000000000000000000 # fill it up with your support guild id
support_server = self.client.get_guild(guild_id)
# try to match with a channel name
match = False
for channel in support_server.text_channels:
await asyncio.sleep(0)
if channel.name == user.name.lower(): # it's a match
match = True
user_support = get(support_server.text_channels, name = user.name.lower()) # get the user support channel as lower case, just like channels name
break
# end for
if not match: # if the channel doesn't exist, we create it
support_category_name = 'Support' # defines the Support category name, case sensitive
support_category = get(support_server.categories, name = support_category_name) # get the support category
user_support = get(support_server.text_channels, name = user.name.lower()) # get the user support channel as lower case, just like channels name
if support_category == None: # if the category is not found, we create it
# setting up the category permissions
support_category_permissions = {
support_server.default_role : discord.PermissionOverwrite(send_messages = False)
}
await support_server.create_category(name = support_category_name, overwrites = support_category_permissions)
support_category = get(support_server.categories, name = support_category_name) # redefine the variable with the new category
if user_support == None: # if the channel doesn't exist
# setting up the permissions for the channel
user_channel_permissions = {
support_server.default_role : discord.PermissionOverwrite(read_messages = False, send_messages = False), # othe users cannot see the channels
support_server.me : discord.PermissionOverwrite(read_messages = True, send_messages = True),
user : discord.PermissionOverwrite(read_messages = True, send_messages = True)
}
# now we create the channel
await support_server.create_text_channel(name = user.name, overwrites = user_channel_permissions, category = support_category)
user_support = get(support_server.text_channels, name = user.name.lower()) # redefine the support channel
# now send the message to the new channel
await user_support.send(request) # sends what the user sent to the command
def setup(client):
client.add_cog(Cmd_support(client))
Using DMs :
It's slightly different from the command solution, request is just replaced by message.content and we add the condition :
Please note that it will create a channel and send message into it no matter the message content. You can filter it by using a condition like : if message.content.startswith("something"):
if type(message.channel) == discord.DMchannel:
Here's the code :
#commands.Cog.listener() # equivalent to discord.Event
async def on_message(self, message):
if type(message.channel) == discord.DMChannel:
user = message.author
guild_id = 000000000000000000 # fill it up with your support guild id
support_server = self.client.get_guild(guild_id)
# try to match with a channel name
match = False
for channel in support_server.text_channels:
await asyncio.sleep(0)
if channel.name == user.name.lower(): # it's a match
match = True
user_support = get(support_server.text_channels, name = user.name.lower()) # get the user support channel as lower case, just like channels name
break
# end for
if not match: # if the channel doesn't exist, we create it
support_category_name = 'Support' # defines the Support category name, case sensitive
support_category = get(support_server.categories, name = support_category_name) # get the support category
user_support = get(support_server.text_channels, name = user.name.lower()) # get the user support channel as lower case, just like channels name
if support_category == None: # if the category is not found, we create it
# setting up the category permissions
support_category_permissions = {
support_server.default_role : discord.PermissionOverwrite(send_messages = False)
}
await support_server.create_category(name = support_category_name, overwrites = support_category_permissions)
support_category = get(support_server.categories, name = support_category_name) # redefine the variable with the new category
if user_support == None: # if the channel doesn't exist
# setting up the permissions for the channel
user_channel_permissions = {
support_server.default_role : discord.PermissionOverwrite(read_messages = False, send_messages = False), # othe users cannot see the channels
support_server.me : discord.PermissionOverwrite(read_messages = True, send_messages = True),
user : discord.PermissionOverwrite(read_messages = True, send_messages = True)
}
# now we create the channel
await support_server.create_text_channel(name = user.name, overwrites = user_channel_permissions, category = support_category)
user_support = get(support_server.text_channels, name = user.name.lower()) # redefine the support channel
# now send the message to the new channel
await user_support.send(message.content) # sends what the user sent to the command
def setup(client):
client.add_cog(Event_on_message(client))
As you can see it's not that different from the first solution I've proposed.
Get the latest discord.py
Well, you should really update your discord.py version to the latest, the old async branch doesn't exist anymore and has been replaced by the rewrite version they were working on.
Try this little script in your terminal :
>>> import discord
>>> discord.__version__
'1.2.3'
If your version is like 0.X.X you're not up to date !
Think about pip install discord.py --upgrade to get the latest version (it's so much better than the old async one)
Usefull link : discord.py - Migrating to v1.0 (I've migrated to the new version in few hours, it wasn't too long. You should better migrate now, before your code becomes too big)
Hope it helped !
Have a nice day !
I would like to get all the messages from a chat that have been sent today.
import sys,datetime
from telethon import TelegramClient
api_id = 1234567
api_hash = "0986asdgshjfag"
client = TelegramClient('session_name', api_id, api_hash)
client.start()
dialogs = client.get_dialogs()
chat = client.get_input_entity('username')
filter = InputMessagesFilterEmpty()
result = client(SearchRequest(
peer=chat, # On which chat/conversation
q='', # What to search for
filter=filter, # Filter to use (maybe filter for media)
min_date=datetime.date.today(), # Minimum date
max_date=None, # Maximum date
offset_id=0, # ID of the message to use as offset
add_offset=0, # Additional offset
limit=5, # How many results
max_id=0, # Maximum message ID
min_id=0, # Minimum message ID
from_id=None, # Who must have sent the message (peer)
hash=0 # Special number to return nothing on no-change
))
for message in client.iter_messages(chat,filter=result):
print(message.message)
The filter doesn't work at all, I can see more than 5 messages (the whole chat) and it doesn't care about the time.
Why?
You can use 'message.date'.
If you want to get the message from today you need to check the sent day. and this would be like :
if datetime.datetime.now().strftime('%Y-%m-%d') == message.date.strftime('%Y-%m-%d')