Page 2 of 7

Re: PureTelegram (framework for using the Telegram API)

Posted: Tue Feb 02, 2021 1:48 pm
by Seymour Clufley
The framework is now too big to fit in a forum post so I have uploaded it to Mediafire. (Link in OP.) I have also given it the name PureTelegram - after all, why not?

Other changes:
Added: PostVenue()
Added: PostLocation()
Added: PostContact()
Renamed: CreatePoll() to PostPoll()
Changed: PostAlbum() now returns a 1-based array of "message ID" integers

Added: GetStickerSet()
Added: UploadStickerFile()
Added: CreateNewStickerSet()
Added: AddStickerToSet()
Added: SetStickerPositionInSet()
Added: DeleteStickerFromSet()
Added: SetStickerSetThumb()

Added: SetChatStickerSet()
Added: DeleteChatStickerSet()

Added: a system for handling updates
First, a note about Telegram's unusual ways for referring to users:
  • user_id
    An integer identifier which is unique and never changes. As such, this is the sensible way to refer to the user throughout your code, and the only way they can be referred to in API calls.
  • username (possibly blank)
    A string which the user can change whenever they want, and might choose to keep blank. If it is non-blank, then their Telegram profile has a URL which can be used on the Internet, for example https://t.me/username. Also, they can be linked to within Telegram like this: "Please welcome @username to the group."
  • first_name
    A string which the user can change whenever they want
  • last_name (possibly blank)
    A string which the user can change whenever they want, and might choose to keep blank.
Telegram combines first_name and last_name to create the person's display name. PureTelegram does the same thing with the Telegram_UserDisplayName() procedure.

Now, handling updates...

Some things you need to understand about Telegram's API.
  • An "update" describes a single event (a message has been posted, a message has been edited, etc.). Each time you ask the API for updates, it will deliver a maximum of 100. You can make multiple calls until the API runs out of updates to give you. All of this is wrapped into a single procedure in PureTelegram, which makes multiple calls to the server and then delivers all new available updates, in a structured list.
  • The Telegram API endpoint is called GetUpdates, but the PureTelegram procedure is called GetNewUpdates(). Here's why. The API might only deliver a particular update once, then immediately "forget" it and never pass it to you again. It is impossible to know how long an update will persist after being sent, so I've written this framework to assume that any updates sent have already been "forgotten" by the API and to only request updates newer than the last one sent. To clarify the situation, I have named the procedure GetNewUpdates().
  • An update will be one of eleven different types, depending on the type of event it is describing.
Now some things about PureTelegram:
  • PureTelegram uses two txt files in order to keep up with things. The first file is a bot-independent ledger of Telegram users and their names, so that you can work with that data outside of these GetNewUpdates() calls. Set this file using Telegram_InstantiateLedger(). The second file enables PureTelegram to "remember" the number of the last update it received from each bot. Set this file using Telegram_InstantiateBot(). You will need to call these two procedures once, before calling GetNewUpdates().
  • Telegram's API delivers all structured data as JSON, which results in very unwieldly structuring, with pointlessly repeated fields all over the place. It is NOT elegant. PureTelegram creates a few generic custom variables in an attempt to make the data handling a bit easier. For each update, regardless of the type, it will automatically fill in the following additional top-level fields:
    • id.i
    • type.s
    • group_or_channel.s (if the update relates to one)
    • user.i (if the update relates to a particular user) - this will be their unique, unchanging ID number, as described above
    With this info known, you can then proceed to deal with the update as you see fit. Learn what info is supplied for each type of update.
With all of that said, here is the full code for a program which gets updates from a bot every 30 seconds, then goes through the updates and reports to you if anyone has used the word "purebasic" in a message:

Code: Select all

#BotAPIToken = ""
Telegram_InstantiateLedger("D:\tg_user_ledger.txt")
Telegram_InstantiateBot(@MyTG.TG_BotInstance,#BotAPIToken,"D:\tgbot_update_counter.txt")

Repeat
  Telegram_GetNewUpdates(@MyTG)
  ForEach MyTG\update()
    With MyTG\update()
      If \type = #TU_Type_MessagePosted
        ss.s = "purebasic"
        If FindString(\message\text+" "+\message\caption,ss,#PB_String_NoCase)
          txt.s = Telegram_UserDisplayName(\user)+" said "+Chr(34)+ss+Chr(34)+"."+Chr(13)+Chr(10)+Telegram_MessageURLFromStructure(@\message)
          MessageRequester("Telegram Report",txt)
        EndIf
      EndIf
    EndWith
  Next
  Delay(30000) ; wait 30 seconds
ForEver
Another way to use it is to call GetNewUpdates() with a maximum wait time, in which case it will "long poll" Telegram and get updated as soon as an event occurs. Obviously, long polling is something you only want to do in a threaded program.

Code: Select all

Telegram_GetNewUpdates(@MyTG,60) ; wait a maximum of 1 minute for Telegram to send updates
Note that you could interact with multiple bots in the same program:

Code: Select all

Telegram_InstantiateLedger("D:\tg_user_ledger.txt")
Telegram_InstantiateBot(@MyBot1.TG_BotInstance,#Bot1APIToken,"D:\bot1_update_counter.txt")
Telegram_InstantiateBot(@MyBot2.TG_BotInstance,#Bot2APIToken,"D:\bot2_update_counter.txt")
Telegram_InstantiateBot(@MyBot3.TG_BotInstance,#Bot3APIToken,"D:\bot3_update_counter.txt")
This will probably be the final version of this framework, unless Telegram expand their API with more functions that I want to use. I haven't coded for everything that is already in the API, just what I personally felt like doing. If anyone who uses PureTelegram feels that something important is missing, let me know and I'll see about adding it. Likewise, if you write any generic components that could be useful, please post them here and I will add them to the PBI.

Anyway, this little project has been a pleasure to work on, and I hope that the framework gives people ideas for new ways they could interact with what seems to be very much an up-and-coming messaging platform.

Re: PureTelegram (framework for using the Telegram API)

Posted: Fri Feb 05, 2021 5:30 pm
by Caronte3D
Very useful, I'll use it for my next project for sure :D
Thank you very much, Seymour Clufley!

Re: PureTelegram (framework for using the Telegram API)

Posted: Fri Feb 05, 2021 7:08 pm
by Seymour Clufley
Thank you, Caronte3D.

A new version is linked in the OP. I have fixed a bug that affected ForwardMessage() and CopyMessage(). Also, some more "data-tidying" now takes place in the GetNewUpdates() procedure, splitting system notification messages out of the update type "message posted" into a set of new custom update types:
#TU_Type_LeftChatMember
#TU_Type_NewChatMember
#TU_Type_GroupCreated
#TU_Type_SupergroupCreated
#TU_Type_ChannelCreated
#TU_Type_ChatPhotoDeleted
#TU_Type_ChatTitleChanged

Re: PureTelegram (framework for using the Telegram API)

Posted: Mon Feb 22, 2021 6:21 am
by Seymour Clufley
A few changes:
Added: PostOnlineImage()
Changed: PostText() now passes the text as a multi-part data field, rather than as a URL parameter. This prevents failures due to special characters in the text, etc.
Changed: PostItem(), PostItemWithThumbnail() and PostPBImage() - as above, re. the caption

Re: PureTelegram (framework for using the Telegram API)

Posted: Mon Feb 22, 2021 12:49 pm
by vwidmer
Seymour Clufley wrote:The framework is now too big to fit in a forum post so I have uploaded it to Mediafire. (Link in OP.) I have also given it the name PureTelegram - after all, why not?
Why not put it on github or other git server? that way as well people can submit any changes fixes etc?

Just idea.
Thanks for the great code though.

Re: PureTelegram (framework for using the Telegram API)

Posted: Thu Feb 25, 2021 6:01 pm
by morosh
Thank you very much for sharing!!
I like to command a esp8266 from my phone. Using telegram no problem: I created a bot and there I type /led_on or /led_off to turn the led on and off. the esp8266 is already programmed for that.

My question: is it possible to command the led by httpRequest()? I like to create an application with SpiderBasic and move it to phone for that, what httpRequest() is sent after type /led_on from the bot?

Can this be done?

Thanks in advance

Re: PureTelegram (framework for using the Telegram API)

Posted: Fri Feb 26, 2021 11:39 pm
by Seymour Clufley
Morosh... unfortunately I have never used SpiderBasic so I don't know what can/can't be done with it. I'm sorry I can't help you.

Re: PureTelegram (framework for using the Telegram API)

Posted: Sun Apr 11, 2021 1:28 pm
by ruslanx
"The chat_id passed can be username or integer ID " - how to use integer ID ? or only comment "PrepareChatID"

Code: Select all

Telegram_PostText("token", "chatID", "text")

Re: PureTelegram (framework for using the Telegram API)

Posted: Sun Apr 11, 2021 4:27 pm
by Seymour Clufley
Just pass the integer ID as a string - eg. Str(my_integer_id.i)

Re: PureTelegram (framework for using the Telegram API)

Posted: Sun Apr 11, 2021 9:16 pm
by ruslanx
not work ... only if I remove PrepareChatID ... it add "@" in front of ID..
or this code is old from first post ?


my ID is without "-" sign ... like 614331292

Code: Select all

Macro PrepareChatID
  EnsureThisNotStart(chat_id,"@")
;   If Left(chat_id,1)<>"-"
;     chat_id = "@"+chat_id
;   EndIf
EndMacro
u must check for number or ...

Code: Select all

chat_id.s = "614331292"
;chat_id.s = "username"


Macro EnsureThisNotStart(t,start)
  If Left(t,Len(start)) = start
    t = Mid(t,Len(start)+1,Len(t))
  EndIf
EndMacro

Macro PrepareChatID
  EnsureThisNotStart(chat_id,"@")
  If Val(chat_id) = 0
    chat_id = "@"+chat_id
  EndIf
EndMacro


PrepareChatID

Debug chat_id

How can I receive mess from Telegram Bot .. example ?

Re: PureTelegram (framework for using the Telegram API)

Posted: Sun Apr 11, 2021 10:19 pm
by Seymour Clufley
ruslanx wrote:my ID is without "-" sign ... like 614331292
That is your own personal profile ID, not a chat ID (eg. for a group or channel). All of these procedures require a chat ID, not a personal profile ID.

Re: PureTelegram (framework for using the Telegram API)

Posted: Mon Apr 12, 2021 8:13 pm
by ruslanx
is chat ID

Re: PureTelegram (framework for using the Telegram API)

Posted: Tue Apr 13, 2021 12:31 am
by Seymour Clufley

Re: PureTelegram (framework for using the Telegram API)

Posted: Tue Oct 19, 2021 10:56 pm
by zikitrake
:D Autosolved
#TelegramTargetID must be "channel Name" not "chat ID"

Hello,
I'm trying to use it but I'm getting "Bad Request: chat not found" error.

The channel is public, and I created the bot with @Botfather.
I take the id from the url that Telegram web gives me (in the image I have deleted the last 2 digits, but it matches in the program and in the original url).

Have you changed anything or am I missing something?

Thanks for your labour.... and for your time!

Image

PS: I Just added mi User Bot to administrators of the channel without luck :oops:

Re: PureTelegram (framework for using the Telegram API)

Posted: Tue Nov 02, 2021 7:02 pm
by Seymour Clufley
Somebody has asked for a demo of using the API function GetChatMember.

In order for this code to work, you have to:
  • create a Telegram group
  • create a Telegram bot
  • add that bot as an admin to your group
  • either know the ID number for your group, or have its @username (either of these will do for the chat_id string variable)
  • know the unique ID number for the member of your group whose details you want. This is the difficult bit. You will either obtain someone's ID number manually, or programmatically by harvesting messages using GetUpdates

Code: Select all

#BotAPIToken = "716306084:AAGUrvMNGzddZ2CkN_MbCLBv7ra3RORJ-cF"
chat_id.s = Str(-1001212492478)
;chat_id.s = "@mygroupusername"
user_id.i = 808415027
Debug Telegram_GetChatMember(#BotAPIToken,chat_id,user_id,@cp.TG_ChatMemberStructure)
Debug cp\user\first_name+" "+cp\user\last_name
All of the user's details are now in the TG_ChatMemberStructure structure, specifically in its "user" field, which is of type TG_UserStructure.