Telegram Bot - how to get a group chat id? - telegram

I've been using telegram_bot, and trying to get groupChat id to send notifications to group chat, but don't know which methods I have to use for it.
For getting chat id I use to message.chat.id when the bot participated in the chat but which I have to use for getting group chat id can't find/

In order to get the group chat id, do as follows:
Add the Telegram BOT to the group.
Get the list of updates for your BOT:
https://api.telegram.org/bot<YourBOTToken>/getUpdates
Ex:
https://api.telegram.org/bot123456789:jbd78sadvbdy63d37gda37bd8/getUpdates
Look for the "chat" object:
{"update_id":8393,"message":{"message_id":3,"from":{"id":7474,"first_name":"AAA"},"chat":{"id":<group_ID>,"title":""},"date":25497,"new_chat_participant":{"id":71,"first_name":"NAME","username":"YOUR_BOT_NAME"}}}
This is a sample of the response when you add your BOT into a group.
Use the "id" of the "chat" object to send your messages.
(If you created the new group with the bot and you only get {"ok":true,"result":[]}, remove and add the bot again to the group)
Private chart only works in image argoprojlabs/argocd-notifications:v1.1.0 or above.

Here is the sequence that worked for me after struggling for several hours:
Assume the bot name is my_bot.
1- Add the bot to the group.
Go to the group, click on group name, click on Add members, in the searchbox search for your bot like this: #my_bot, select your bot and click add.
2- Send a dummy message to the bot. You can use this example: /my_id #my_bot
(I tried a few messages, not all the messages work. The example above works fine. Maybe the message should start with /)
3- Go to following url: https://api.telegram.org/botXXX:YYYY/getUpdates
replace XXX:YYYY with your bot token
4- Look for "chat":{"id":-zzzzzzzzzz,
-zzzzzzzzzz is your chat id (with the negative sign).
5- Testing: You can test sending a message to the group with a curl:
curl -X POST "https://api.telegram.org/botXXX:YYYY/sendMessage" -d "chat_id=-zzzzzzzzzz&text=my sample text"
If you miss step 2, there would be no update for the group you are looking for. Also if there are multiple groups, you can look for the group name in the response ("title":"group_name").

As of May 2021, simply:
Invite #RawDataBot to your group.
Upon joining it will output a JSON file where your chat id will be located at message.chat.id.
"message": {
"chat": {
"id": -210987654,
"title": ...,
"type": "group",
...
}
...
}
Be sure to kick #RawDataBot from your group afterwards.

After mid-2018:
1:) Invite #getidsbot or #RawDataBot to your group and get your group id from the chat id field.
Message
├ message_id: 338
├ from
┊ ├ id: *****
┊ ├ is_bot: false
┊ ├ first_name: 사이드
┊ ├ username: ******
┊ └ language_code: en
├ chat
┊ ├ id: -1001118554477 // This is Your Group id
┊ ├ title: Test Group
┊ └ type: supergroup
├ date: 1544948900
└ text: A
2:) use an unofficial Messenger like Plus Messenger and see your group id in group/channel info.
Before mid-2018: (don't Use)
1: Goto (https://web.telegram.org)
2: Goto your Gorup and Find your link of Gorup(https://web.telegram.org/#/im?p=g154513121)
3: Copy That number after g and put a (-) Before That -154513121
4: Send Your Message to Gorup
bot.sendMessage(-154513121, "Hi")
I Tested Now and Work like a Charm

the simplest way i found using only telegram-web :
open web.telegram in browser ( chrome in my case )
right click on the group name on the left menu
click 'inspect' button
you will see the group id in the attribute
data-peer-id="-xxxxxxxxxx" or peer="-xxxxxxxxxx"
group chat id : -xxxxxxxxxx
channel chat id : -100xxxxxxxxxx
(for some channels/groups you need to add -100 prefix)
Edit :
in some cases the ID is shown in the browsers address bar when you click a group name
https://web.telegram.org/z/#-xxxxxxxxxx

You can get Chat ID in this way.
On private chat with your bot, send a random message. You will search this message later.
Get Your API-token from bot_father : XXXXXXXXX:YYYYYYY-YYYYYYYYYYYYYYYYY_YY
Then, on your browser make a request with that url :
https://api.telegram.org/botXXXXXXXXX:YYYYYYY-YYYYYYYYYYYYYYYYY_YY/getUpdates
The request returns a json response, in json text search your random message and get chat id in that object.

Using python and telethon it's very easy to get chat id. This solution is best for those who work with telegram API.
If you don't have telethon, run this:
pip install telethon
If you don't have a registered app with telegram, register one:
The link is this: https://my.telegram.org/
Then run the following code:
from telethon import InteractiveTelegramClient
from telethon.utils.tl_utils import get_display_name
client = InteractiveTelegramClient('session_id', 'YOUR_PHONE_NUMBER', api_id=1234YOURAPI_ID, api_hash='YOUR_API_HASH')
dialog_count = 10
dialogs, entities = client.get_dialogs(dialog_count)
for i, entity in enumerate(entities):
i += 1 # 1-based index
print('{}. {}. id: {}'.format(i, get_display_name(entity), entity.id))
You may want to send a message to your group so the group show up in top of the list.

You can retrieve the group ID the same way. It appears in the message body as message.chat.id and it's usually a negative number, where normal chats are positive.
Group IDs and Chat IDs can only be retrieved from a received message, there are no calls available to retrieve active groups etc. You have to remember the group ID when you receive the message and store it in cache or something similar.

My second Solution for the error {"ok":true,"result":[]}
Go in your Telegram Group
Add new User (Invite)
Search for "getidsbot" => #getidsbot
Message: /start#getidsbot
Now you see the ID. looks like 1068773197, which is -1001068773197 for bots (with -100 prefix)!!!
Kick the bot from the Group.
Now go to the Webbrowser an send this line (Test Message):
https://api.telegram.org/botAPITOKENNUMBER:APITOKENKEYHERE/sendmessage?chat_id=-100GROUPNUMBER&text=test
Edit the API Token and the Group-ID!

go on the group of choice
add #rose bot
type the command /id
type the command /id

create a bot, or if already created set as follows:
has access to messages
apparently, regardless of how old/new the Telegram group is:
add a bot to the group
remove bot from the group
add bot again to the group
create a script file and run getUpdates method
example:
var vApiTokenTelegram = "1234567890:???>yg5GeL5PuItAOEhvdcPPELAOCCy3jBo"; // #?????Bot API token
var vUrlTelegram = "https://api.telegram.org/bot" + vApiTokenTelegram;
function getUpdates() {
var response = UrlFetchApp.fetch(vUrlTelegram + "/getUpdates");
console.log(response.getContentText());
}
function shall log to the console the following:
[20-04-21 00:46:11:130 PDT] {"ok":true,"result":[{"update_id":81329501,
"message":{"message_id":975,"from":{"id":962548471,"is_bot":false,"first_name":"Trajano","last_name":"Roberto","username":"TrajanoRoberto","language_code":"en"},"chat":{"id":-1001202656383,"title":"R\u00e1dioRN - A voz da na\u00e7\u00e3o!","type":"supergroup"},"date":1587454914,"left_chat_participant":{"id":1215098445,"is_bot":true,"first_name":"MediaFlamengoRawBot","username":"MediaFlamengoRawBot"},"left_chat_member":{"id":1215098445,"is_bot":true,"first_name":"MediaFlamengoRawBot","username":"MediaFlamengoRawBot"}}},{"update_id":81329502,
"message":{"message_id":976,"from":{"id":962548471,"is_bot":false,"first_name":"Trajano","last_name":"Roberto","username":"TrajanoRoberto","language_code":"en"},"chat":{"id":-1001202656383,"title":"R\u00e1dioRN - A voz da na\u00e7\u00e3o!","type":"supergroup"},"date":1587454932,"new_chat_participant":{"id":1215098445,"is_bot":true,"first_name":"MediaFlamengoRawBot","username":"MediaFlamengoRawBot"},"new_chat_member":{"id":1215098445,"is_bot":true,"first_name":"MediaFlamengoRawBot","username":"MediaFlamengoRawBot"},"new_chat_members":[{"id":1215098445,"is_bot":true,"first_name":"MediaFlamengoRawBot","username":"MediaFlamengoRawBot"}]}}]}
Telegram group chat_id can be extracted from above message
"chat":{"id":-1001202656383,"title"

Group chat id should start with - (minus) is essential
This is wrong
10540154212
This is correct
-10540154212

You can get your id by sending a /start message to the bot userinfobot
Note: once u search for userinfobot in telegram u get many responses.
Makesure u choose the one with #bot tag

I tested now 4h but it dont work 2021 with the group-chat-id. All the time the error {"ok":true,"result":[]}
But now i found a Solution:
1:) install the "Plus Messenger" (https://play.google.com/store/apps/details?id=org.telegram.plus)
2:) go in the Group => Tap now on the "Group-Name" in the Head => Double Tap now on the Headline from the Group. A Info is comming: ID123456789 is copy in the clipboard
3:) go in the Group an paste the clipboard text. It´s you Groud-ID
4:) looks like 1068773197, which is -1001068773197 for bots (with -100 prefix)!!!
btw, you see the user-id too, on your profil.
5:) Now go to the Webbrowser an send this line (Test Message):
https://api.telegram.org/botAPITOKENNUMBER:APITOKENKEYHERE/sendmessage?chat_id=-100GROUPNUMBER&text=test
Edit the API Token and the Group-ID!

IMHO the best way to do this is using TeleThon, but given that the answer by apadana is outdated beyond repair, I will write the working solution here:
import os
import sys
from telethon import TelegramClient
from telethon.utils import get_display_name
import nest_asyncio
nest_asyncio.apply()
session_name = "<session_name>"
api_id = <api_id>
api_hash = "<api_hash>"
dialog_count = 10 # you may change this
if f"{session_name}.session" in os.listdir():
os.remove(f"{session_name}.session")
client = TelegramClient(session_name, api_id, api_hash)
async def main():
dialogs = await client.get_dialogs(dialog_count)
for dialog in dialogs:
print(get_display_name(dialog.entity), dialog.entity.id)
async with client:
client.loop.run_until_complete(main())
this snippet will give you the first 10 chats in your Telegram.
Assumptions:
you have telethon and nest_asyncio installed
you have api_id and api_hash from my.telegram.org

I don't understand why the most obvious (and probably the simplest) answer isn't here.
As you are writing a bot, you can get the id with these three simple lines:
bot.on('message', (msg) => {
console.log(msg)
})
Then just check the groupId from the console :D
And as you are probably trying to look the groupId to be able to send message to a group with your bot, the correct answer is probably this:
You don't use anymore the groupId. You use the group name (the one with https://t.me/careless_whisper) prefixed with #. And remember that your group has to be public. Source: Telegram API
So if your group name is careless_whisper the recipient will be #careless_whisper

I'd like to note very specific case made me monkey around it.
I've got the chat_id with above steps in the format like -1001379XXXXXX. So I just supposed the real id is 1001379XXXXXX, and left it in a such format to the grafana admin page. But in fact the id got this - as the integral part. If was really needed to be copied together with numbers.

function adminCheck( chat_id, name ) {
var bAdminCheck = false;
var contents = JSON.parse( getAdmin( chat_id ) );
var i = 0;
while( !bAdminCheck && (i < contents.result.length ) ) {
if( name == (contents.result[i].user.first_name + " " + contents.result[i].user.last_name) ) {
bAdminCheck = true;
}
i++;
}
return bAdminCheck;
}

If you are implementing your bot, keep stored a group name -> id table, and ask it with a command. Then you can also send per name.

Related

How to improve antispam function discord.py?

I'm making a discord bot and I have antispam function build in, but I want to improve it. I don't want this function to react to certain roles, like admin or moderator (so I want this function NOT to react to certain roles, so admins can spam). Also I have spam channel where I don't want this function to work, how do I do that? And last, but not least: how do I delete the same (spammed) messages? Because what my bot does is: it says "Stop spamming". But I want to delete the same message. Thank you very much! I hope you can help me!
THE CODE:
import os
import discord
import datetime
intents = discord.Intents.all()
bot = commands.Bot(command_prefix='$', intents=intents)
time_window_milliseconds = 5000
max_msg_per_window = 5
author_msg_times = {}
#bot.event
async def on_message(ctx): #spam allowed in channel and for admins? How to make?
global author_msg_counts
author_id = ctx.author.id
curr_time = datetime.datetime.now().timestamp() * 1000
if not author_msg_times.get(author_id, False):
author_msg_times[author_id] = []
author_msg_times[author_id].append(curr_time)
expr_time = curr_time - time_window_milliseconds
expired_msgs = [
msg_time for msg_time in author_msg_times[author_id]
if msg_time < expr_time
]
for msg_time in expired_msgs:
author_msg_times[author_id].remove(msg_time)
if len(author_msg_times[author_id]) > max_msg_per_window:
await ctx.delete(ctx)
await ctx.send("Stop Spamming")
else:
print("You are good to go!")
bot.run(os.getenv('token'))
For your first question about roles, you should add at the start of your spam check:
if ctx.author.guild_permissions.manage_messages:
return
This will make it not affect any member who has the permission to delete messages (this would be moderators or admins).
You can also do
if ctx.channel.id == [id here]:
return
replacing [id here] with the id of your spam channel.
Lastly, put await ctx.send("Stop Spamming") before await ctx.delete(ctx), and make sure your bot has permission to delete messages.

How to disconnect a discord bot from voice channel after user left?

I would like to add an event that my music bot leaves the voice channel immediately if the user leaves while the song is still playing. If there are multiple users in the channel, the bot should of course stay in the channel. I only have one approach there, but would need help. I would try the following:
async def check_member(self, ctx):
channel = ctx.author.voice.channel
member_count = len(voice_channel.members)
if member_count == 1:
await channel.disconnect
but somehow this doesn't seem to work.
I know for fact that there is a similar post but this did not work for me too as I defined some things different.
My second attempt was:
async def check_member(self, ctx):
channel = ctx.author.voice.channel
member_count = len(channel.members)
client = ctx.guild.voice_client
if member_count == 1:
await client.disconnect()
(Did not work either.)
To define does not work: I build the function in a different way now:
#tasks.loop(seconds=2)
async def check(self, ctx):
voice_channel = ctx.author.voice.channel
member_count = len(voice_channel.members)
client = ctx.guild.voice_client
if member_count == 1:
await client.disconnect()
This is now a total different count. What I am trying to do is loop the commands.Cog.listener() function every 2 seconds. For tests I played a song and left instantly after the bot started playing. I thought the bot would leave the channel too but it did not. There was no output in my log that I defined something wrong.
A loop is kinda unefficient, you can simply use the on_voice_state_update event
async def on_voice_state_update(member, before, after):
voice_state = member.guild.voice_client
# Checking if the bot is connected to a channel and if there is only 1 member connected to it (the bot itself)
if voice_state is not None and len(voice_state.channel.members) == 1:
# You should also check if the song is still playing
await voice_state.disconnect()
Reference:
on_voice_state_update

How can I get group details by #link using Telebot library

I want to create a bot that posts messages on channels / groups,
the user sends the group address for example: #group_name, and I need to get the ID, title
I work with telebot library
#bot.message_handler(commands=['addgroup'])
def add_group(message):
msg = bot.send_message(message.chat.id, 'Send group link without #')
bot.register_next_step_handler(msg, add)
def add(message):
url = "telegram.me/" + message.text
keyboard = types.InlineKeyboardMarkup()
keyboard.add(types.InlineKeyboardButton("##HERE I NEED GROUP NAME##", url=url))
msg = bot.send_message(message.chat.id, "Add this group?", reply_markup=keyboard)
bot.register_next_step_handler(msg, check_group)
....
How can I get this information?
Let's read telegram docs...
getChat
Use this method to get up to date information about the chat (current name of the user for one-on-one conversations, current username of a user, group or channel, etc.).
Returns a Chat object on success.
Parameters:
chat_id - unique identifier for the target chat or username of the target supergroup or channel (in the format #channelusername).
So,
chat = bot.get_chat('#username')
P.S.: register_next_step_handler is antipattern, use aiogram's FSM instead.

How can I check the database of phone numbers for the presence of the Telegram messenger?

I have the numbers of the residents of my village - how can I check for the presence of installed Telegram on these numbers? I googled, but I couldn't find any solutions.
Here is one approach using telethon in python and a regular user account
import random
from telethon import TelegramClient
from telethon import functions, types
api_id = ...
api_hash = ' ... '
client = TelegramClient('session', api_id, api_hash)
async def main():
phone_number = '+ ... '
result = await client(functions.contacts.ImportContactsRequest(
contacts=[types.InputPhoneContact(
client_id=random.randrange(-2**63, 2**63),
phone=phone_number,
first_name='Some Name',
last_name=''
)]
))
if len(result.users):
print(f"{phone_number} has a telegram account")
await client(functions.contacts.DeleteContactsRequest(result.users))
else:
print(f"couldn't find an account for {phone_number}")
client.start()
client.loop.run_until_complete(main())
Here we are trying to add a new Contact (by using ImportContactsRequest) with the phone number and if that succeeds we get the users back inside the users field of the result (ImportedContacts) and an empty list otherwise. So we can just check the length of that field to determine whether the user has a telegram account or not.
And finally we remove the newly created contact at the end by executing DeleteContactsRequest.

Firebase Chat - Get messages just for 2 users [duplicate]

In my main page I have a list of users and i'd like to choose and open a channel to chat with one of them.
I am thinking if use the id is the best way and control an access of a channel like USERID1-USERID2.
But of course, user 2 can open the same channel too, so I'd like to find something more easy to control.
Please, if you want to help me, give me an example in javascript using a firebase url/array.
Thank you!
A common way to handle such 1:1 chat rooms is to generate the room URL based on the user ids. As you already mention, a problem with this is that either user can initiate the chat and in both cases they should end up in the same room.
You can solve this by ordering the user ids lexicographically in the compound key. For example with user names, instead of ids:
var user1 = "Frank"; // UID of user 1
var user2 = "Eusthace"; // UID of user 2
var roomName = 'chat_'+(user1<user2 ? user1+'_'+user2 : user2+'_'+user1);
console.log(user1+', '+user2+' => '+ roomName);
user1 = "Eusthace";
user2 = "Frank";
var roomName = 'chat_'+(user1<user2 ? user1+'_'+user2 : user2+'_'+user1);
console.log(user1+', '+user2+' => '+ roomName);
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>
A common follow-up questions seems to be how to show a list of chat rooms for the current user. The above code does not address that. As is common in NoSQL databases, you need to augment your data model to allow this use-case. If you want to show a list of chat rooms for the current user, you should model your data to allow that. The easiest way to do this is to add a list of chat rooms for each user to the data model:
"userChatrooms" : {
"Frank" : {
"Eusthace_Frank": true
},
"Eusthace" : {
"Eusthace_Frank": true
}
}
If you're worried about the length of the keys, you can consider using a hash codes of the combined UIDs instead of the full UIDs.
This last JSON structure above then also helps to secure access to the room, as you can write your security rules to only allow users access for whom the room is listed under their userChatrooms node:
{
"rules": {
"chatrooms": {
"$chatroomid": {
".read": "
root.child('userChatrooms').child(auth.uid).child(chatroomid).exists()
"
}
}
}
}
In a typical database schema each Channel / ChatGroup has its own node with unique $key (created by Firebase). It shouldn't matter which user opened the channel first but once the node (& corresponding $key) is created, you can just use that as channel id.
Hashing / MD5 strategy of course is other way to do it but then you also have to store that "route" info as well as $key on the same node - which is duplication IMO (unless Im missing something).
We decided on hashing users uid's, which means you can look up any existing conversation,if you know the other persons uid.
Each conversation also stores a list of the uids for their security rules, so even if you can guess the hash, you are protected.
Hashing with js-sha256 module worked for me with directions of Frank van Puffelen and Eduard.
import SHA256 from 'crypto-js/sha256'
let agentId = 312
let userId = 567
let chatHash = SHA256('agent:' + agentId + '_user:' + userId)

Resources