PureTelegram (framework for using the Telegram API)

Share your advanced PureBasic knowledge/code with the community.
Seymour Clufley
Addict
Addict
Posts: 1233
Joined: Wed Feb 28, 2007 9:13 am
Location: London

PureTelegram (framework for using the Telegram API)

Post by Seymour Clufley »

This framework enables you to programmatically work with any Telegram channels/groups that you administer. You can post messages (text, HTML, media, files, polls, etc.), edit messages, delete messages, moderate members and receive info about activity, along with a host of other functions. I have implemented almost the entire API.

PBI files and help file

The included help file contains a quickstart section and many code examples showing how to use each command.

Legacy version of the .pbi

Minimal demo:

Code: Select all

XIncludeFile "PureTelegram.pbi"
#ChatID = ""
#BotAPIToken = ""

txt.s = "Random message ("+Str(Random(9999,1000))+") from a <a href='https://www.purebasic.com'>PureBasic</a> program using the <b>PureTelegram</b> framework."
Telegram_PostText(#BotAPIToken,#ChatID,txt)
I hope this framework is useful for people.
Last edited by Seymour Clufley on Fri Apr 29, 2022 2:03 am, edited 44 times in total.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
Seymour Clufley
Addict
Addict
Posts: 1233
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Re: Post things on Telegram

Post by Seymour Clufley »

Each "posting" procedure returns the unique integer ID of the submitted message, or zero if there was an error in posting it.

That integer ID can then be used to edit or delete the message later.

Example:

Code: Select all

messagenum.i = Telegram_PostText(#TelegramBotAPIToken,#TelegramTargetID,"Random "+Str(Random(9999,1000)))
Delay(10000) ; delete message after 10 seconds
Telegram_DeleteMessage(#TelegramBotAPIToken,#TelegramTargetID,messagenum)
The Telegram_StopPoll() procedure is used in exactly the same way.
Last edited by Seymour Clufley on Wed Feb 23, 2022 12:59 pm, edited 1 time in total.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
Seymour Clufley
Addict
Addict
Posts: 1233
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Re: Telegram API

Post by Seymour Clufley »

Some new procedures added:
Telegram_DeleteMessage()
Telegram_ForwardMessage()
Telegram_CopyMessage()

Telegram_EditMessageText()
Telegram_EditMessageCaption()

Telegram_PinMessage()
Telegram_UnpinMessage()
Telegram_UnpinAllMessages()

Telegram_StopPoll()

Telegram_SetTitle()
Telegram_SetDescription()

Telegram_MessageURL()
I have also written a procedure for sending a video with a thumbnail, Telegram_PostItemWithThumbnail(), and while I'm pretty sure the code is correct, the thumbnail never seems to actually show on Telegram.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
dige
Addict
Addict
Posts: 1240
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: Telegram API

Post by dige »

Thanks Seymour Clufley! It can become very handy for me in the future.
How do I get the group ID? Where it's displayed in the app?

Ciao Dige
"Daddy, I'll run faster, then it is not so far..."
Seymour Clufley
Addict
Addict
Posts: 1233
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Re: Telegram API

Post by Seymour Clufley »

dige wrote:Thanks Seymour Clufley! It can become very handy for me in the future.
Good! I'm very glad that somebody will have a use for this.
How do I get the group ID? Where it's displayed in the app?
A Telegram channel always has an ID. It forms the channel's URL - https:/t.me/MyChannelID
A Telegram group is exactly the same, but will only have an ID if it is a public group. Private groups don't have IDs and therefore can't be interacted with by this code library.
The ID is also how the group/channel is hyperlinked within Telegram, using the @ symbol - @MyChannelID

You need to either admin the group/channel yourself, or get someone who does to create a bot and make it an admin of the group/channel. You can then communicate with the bot using this code library.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
dige
Addict
Addict
Posts: 1240
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: Telegram API

Post by dige »

Just saw, the web client (https://web.telegram.org) shows the ID in the URL
"Daddy, I'll run faster, then it is not so far..."
Seymour Clufley
Addict
Addict
Posts: 1233
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Re: Telegram API

Post by Seymour Clufley »

I have tidied up the code and added a new procedure, Telegram_PostAlbum(). It seems to work perfectly. Demo of how to use it:

Code: Select all

NewList albumitem.Telegram_AlbumItemStructure()
AddElement(albumitem()) : albumitem()\fn="D:\BHJIDM.jpg" : albumitem()\caption="album item 1 caption"
AddElement(albumitem()) : albumitem()\fn="D:\FGSIDW.jpg" : albumitem()\caption="album item 2 caption"
AddElement(albumitem()) : albumitem()\fn="D:\ERGGIR.jpg" : albumitem()\caption="album item 3 caption"
AddElement(albumitem()) : albumitem()\fn="D:\GHIXNR.jpg" : albumitem()\caption="album item 4 caption"
n.i = Telegram_PostAlbum(#TelegramBotAPIToken,#TelegramTargetID,#TelegramMessageType_Image,albumitem())
Debug n
The procedure was tricky to write, as it involves a multipart form data request. The same is true of the Telegram_PostItemWithThumbnail() procedure, where the main file and the thumbnail file are sent together. While I think I'm doing everything correctly, the thumbnail never appears on Telegram. I don't know why this is. If other people want to look into it, that would be good.

In the meantime I am working on the next part of this API, which is handling updates from a bot.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
User avatar
Caronte3D
Addict
Addict
Posts: 1014
Joined: Fri Jan 22, 2016 5:33 pm
Location: Some Universe

Re: Telegram API

Post by Caronte3D »

Thanks, Seymour Clufley
When the "GetUpdates" implemented it will be awesome! :wink:
Seymour Clufley
Addict
Addict
Posts: 1233
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Re: Telegram API

Post by Seymour Clufley »

Thanks, Caronte3D. It's good to know this API will be used. :)

I have pretty much finished the GetUpdates code, but in the meantime have added some more procedures:
Telegram_SetChatPhoto() ; uses an image file on the computer
Telegram_SetChatPhotoPBImage()
Telegram_DeleteChatPhoto()
Those ones are very straightforward. The next ones aren't. Each of these requires a user_id integer variable, so you need to obtain someone's user_id number in order to use these. Telegram's API does not provide a way to obtain an arbitrary user's number; you can only obtain it via a message that the person has posted in your group. This will be possible with the GetUpdates functionality.
Telegram_GetChatMembersCount()
Telegram_GetChatMember()
Telegram_BanChatMember()
Telegram_RemoveChatMemberWithoutBanning()
Telegram_UnbanChatMember()
Telegram_SetChatMemberPermissions()
Telegram_SetChatMemberPermission()
Telegram_SetChatMemberPermissionsMap()
The final three functions all contact the same endpoint on Telegram's API, but work in different ways. Telegram_SetChatMemberPermissions() is for revising all of a member's permissions, so it requires a structure variable with all permission statuses set. By contrast, Telegram_SetChatMemberPermission() is for revising just one permission, so it requires only a simple byte variable. With Telegram_SetChatMemberPermissionsMap(), you pass a byte map containing whichever permissions you want to set, whether #True or #False, and permissions missing from the map will be unaffected.

To revise just one permission:

Code: Select all

Telegram_SetChatMemberPermission(TelegramBotAPIToken,#TelegramTargetID,"the_user_id",#TG_Permission_SendPolls,#False)
To revise several permissions:

Code: Select all

NewMap cmp.b()
cmp(#TG_Permission_SendMessages)=#True
cmp(#TG_Permission_SendOtherMessages)=#False
cmp(#TG_Permission_ChangeInfo)=#True
Telegram_SetChatMemberPermissionsMap(#TelegramBotAPIToken,#TelegramTargetID,"the_user_id",cmp())
To revise all permissions:

Code: Select all

perms.TG_ChatPermissionsStructure
perms\can_send_messages = #True
perms\can_send_media_messages = #False
perms\can_send_polls = #False
perms\can_send_other_messages = #True
perms\can_add_web_page_previews = #True
perms\can_change_info = #False
perms\can_invite_users = #False
perms\can_pin_messages = #False
Telegram_SetChatMemberPermissions(#TelegramBotAPIToken,TelegramTargetID,"the_user_id",@perms)
The GetUpdates functionality will be added very soon. I might build into it optional automatic harvesting of member ID numbers, because that is data that most people who use this API will end up needing.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: Telegram API

Post by Lunasole »

Nice, would be interesting to play with it. Thanks
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
Seymour Clufley
Addict
Addict
Posts: 1233
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Re: Telegram API

Post by Seymour Clufley »

Some more new functions added:
Telegram_GetFile()
Telegram_GetFileToMemory()
Telegram_DownloadUserProfilePhotos()
Telegram_GetUserProfilePhotos() ; requires UseJPEGImageDecoder()
The first two functions enable you to download files that are in Telegram's database. You need the file_id variable in each case, and that can be obtained in numerous ways. One use case is accommodated by the other two functions. Those can be used like this:

Code: Select all

images.i = Telegram_DownloadUserProfilePhotos(#TelegramBotAPIToken,user_id,folder$)
; the user's profile photos have been downloaded into the named folder$, as JPEG files

Dim img.i(10)
images.i = Telegram_GetUserProfilePhotos(#TelegramBotAPIToken,user_id,img())
; the user's profile photos are now in the PB image array img(), and can be worked with
Last edited by Seymour Clufley on Mon Feb 01, 2021 10:22 am, edited 1 time in total.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
dige
Addict
Addict
Posts: 1240
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: Telegram API

Post by dige »

By the way, here it only works without the @ sign in front of the chatid..
"Daddy, I'll run faster, then it is not so far..."
Seymour Clufley
Addict
Addict
Posts: 1233
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Re: Telegram API

Post by Seymour Clufley »

dige wrote:By the way, here it only works without the @ sign in front of the chatid..
Yes, I should have made clear: the @ symbol should always be omitted from the chatid variable in this.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
dige
Addict
Addict
Posts: 1240
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: Telegram API

Post by dige »

Unfortunately, we have misunderstood each other. I meant that it only works, in generell without the @ sign. Also not automatically added in the respective procedure.

Does not work:

Code: Select all

 curl -X POST "https://api.telegram.org/myBotID/sendMessage?chat_id=@-1234567&text='Message Text'"
Works:

Code: Select all

 curl -X POST "https://api.telegram.org/myBotID/sendMessage?chat_id=-1234567&text='Message Text'"
When I get ChatIDs via getUpdates, no @ characters are displayed there either.
"Daddy, I'll run faster, then it is not so far..."
Seymour Clufley
Addict
Addict
Posts: 1233
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Re: Telegram API

Post by Seymour Clufley »

Okay, I understand now. You are using the integer chat_id, rather than chat_username. That makes sense, although I always prefer to use the username, but I suspect many people will prefer to use chat_id. I will build this in.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
Post Reply