B4J Library [BETA] jTelegramBot - Create your own Telegram Bot

DonManfred

Expert
Licensed User
jTelegramBot is a partially wrapper build on this github project.
This project is licensed under The MIT License (MIT). See LICENSE for more details.
Note that the development has stopped. If you miss something in the lib you need to add it by yourself. The Source is attached to this post.

links about Telegram Bots

JTelegramBot
Author:
DonManfred (Wrapper)
Version: 0.31

Setup:
- To get the Example running you first need to adapt the Initialize line with your Bots Name and ApiToken.
B4X:
Sub AppStart (Args() As String)
    jtb.Initialize("JTB","yourbotname","youtbottoken")
    glmap.Initialize
    jtb.startAsync
    StartMessageLoop
End Sub
- The Example is using Static Filenames for the Document, MP3, Photo, Sticker send.
Make sure to adapt the path and Filenames to match Files you want to use.

B4X:
    If message.Text = "/buttons" Then
        Dim mark As InlineKeyboardMarkup
        mark.initialize(jtb.CreateDummyKeyboard)
        Dim buttons As Message = jtb.sendMessage(jtb.byId(from.Id),"Click the Button!","MARKDOWN",False,False,message.MessageId,mark)
        glmap.Put(buttons.MessageId,buttons)
    else If message.Text = "/location" Then
        jtb.sendChatAction(jtb.byId(from.Id),jtb.ChatActionFIND_LOCATION)
        jtb.sendLocation(jtb.byId(from.Id),50.8337006,6.441118,False,message.MessageId,Null)
    else If message.Text = "/url" Then
        jtb.sendMessage(jtb.byId(from.Id),"[jTelegramBot Thread](https://www.b4x.com/android/forum/threads/jtelegrambot.103778/#post-650611)","MARKDOWN",False,False,message.MessageId,Null)
    else If message.Text = "/plainurl" Then
        bld.sendMessage(chat.Id,"Link without Preview [jTelegramBot Thread](https://www.b4x.com/android/forum/threads/jtelegrambot.103778/#post-650611)",message.MessageId,False,True,Null,jtb.parsemodeMARKDOWN)
    else If message.Text = "/text" Then
        jtb.sendMessage(jtb.byId(from.Id),$"Testtext <b>Bold</b>, <i>Italic</i>
    new row..."$,"HTML",True,False,message.MessageId,Null)
    else If message.Text = "/document" Then
        jtb.sendChatAction(jtb.byId(from.Id),jtb.ChatActionUPLOAD_DOCUMENT)
        jtb.sendDocument(jtb.byId(from.Id),jtb.MediaByFile(File.DirApp,"mydocument.zip"),"DocumentCaption",False,message.MessageId,Null)
    else If message.Text = "/photo" Then
        jtb.sendChatAction(jtb.byId(from.Id),jtb.ChatActionUPLOAD_PHOTO)
        jtb.sendPhoto(jtb.byId(from.Id),jtb.MediaByFile(File.DirApp,"myimage.png"),"DocumentCaption",False,message.MessageId,replbld.forceReply)
    else If message.Text = "/audio" Then
        jtb.sendChatAction(jtb.byId(from.Id),jtb.ChatActionUPLOAD_VIDEO)
        jtb.sendAudio(jtb.byId(from.Id),jtb.MediaByFile(File.DirApp,"myaudio.mp3"),223,"Fleedwood Mac","Eyes of the World",False,message.MessageId,replbld.forceReply)
    else If message.Text = "/sticker" Then
        jtb.sendSticker(jtb.byId(from.Id),jtb.MediaByFile(File.DirApp,"mysticker.webp"),False,message.MessageId,Null)
    else If message.Text = "/start" Then
        jtb.sendMessage(jtb.byId(from.Id),$" Hello ${chat.Username}
`Command   | Result
----------|-------------------------
/location | Returns a Locationobject
/document | Returns a Document
/photo    | Returns a Photo
/audio    | Returns a Audiofile
/url      | Returns a URL with Preview
/plainurl | Returns a URL without Preview
/buttons  | Shows some buttons To Click on
`
Thank you For choosing Me :-)"$,"MARKDOWN",False,False,message.MessageId,Null)
In this example you need to replace the following Filereferences:
- mydocument.zip
- myimage.png
- myaudio.mp3
- mysticker.webp

Due to the Size of the needed Additional JARs they can be downloaded
HERE.

For any Question/Issue you have please Create a new Thread in the B4J Questionsforum.
 

Attachments

Last edited:

Blueforcer

Active Member
Licensed User
Hello again:)
Get this error while compiling
B4X:
\jtelegrambot.jar(de/donmanfred/JTBwrapper.class)
    class file has wrong version 55.0, should be 52.0
Got latest B4J with with JDK 1.8.0_201
 

Blueforcer

Active Member
Licensed User
Do you know how to avoid it, that others can use my bot?
Everbody can find my bot in telegram and control my application^^
 

DonManfred

Expert
Licensed User

DonManfred

Expert
Licensed User
Next version will have a possibility to change the InlineKeyboard. In the 1st version only a dummykeyboard is generated inside the library which could not be changed.

B4X:
        Dim ibld As InlineKeyboardButtonBuilder
        Dim mark As InlineKeyboardMarkup
        mark.initialize(ibld.Initialize.newRow.newButton("1").withCallbackData("BTN1").newButton("2").withCallbackData("BTN2").newButton("3").withCallbackData("BTN3").newRow.newButton("Google").withUrl("https://www.google.com").newRow.build)
        Dim buttons As Message = jtb.sendMessage(jtb.byId(from.Id),"Click the Button!","MARKDOWN",False,False,message.MessageId,mark)
 

CGP

Member
Licensed User
Thanks a lot @DonManfred !

I've tried to add my bot into a group and hangs, cannot handle "new_chat_participant" action.

B4X:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "new_chat_participant" (class io.fouad.jtb.core.beans.Message), not marked as ignorable (34 known properties: "entities", "new_chat_member", "edit_date", "animation", "new_chat_photo", "message_id", "audio", "chat", "document", "delete_chat_photo", "contact", "migrate_from_chat_id", "forward_from", "caption", "forward_date", "left_chat_member", "from", "text", "date", "venue", "new_chat_title", "game", "location", "reply_to_message", "video", "supergroup_chat_created", "sticker", "group_chat_created", "forward_from_chat", "pinned_message", "photo", "channel_chat_created", "voice", "migrate_to_chat_id"])
 at......
Can you take a look?

Many thanks
 

DonManfred

Expert
Licensed User
Kind of Offtopic but still related:

Left side is a Android app which is using the TDL Database Library and act as a Client for my TelegramAccount.

On right side my Telegram Desktop client where i am talking to my telegrambot. Message which i get in telegram desktop client (Pictures in this case) the Android client also get in an Update.

Have fun watching :)

 

DonManfred

Expert
Licensed User
Great work!
It also works for Documents (Files). The Client first get an info about the file (that it can be downloaded) and then call a method to download it.

B4X:
        else if msg.Content Is MessageDoc Then
            Log("Messagecontent Document")
            Dim msgdoc As MessageDoc = msg.Content
            Log(msgdoc)
            If msgdoc.Document <> Null Then
                Log("Document <> null")
                Dim doc As Document = msgdoc.Document
                Log(doc.Filename)
                Log(doc.mimeType)
                
                If doc.InnerDocument <> Null Then
                    Dim dfile As TdFile= doc.InnerDocument
                    Log(dfile)
                    'Log(dfile.Id)
                    'Log(dfile.expectedSize)
                    Log($"FileID: ${dfile.Id}, Size: ${dfile.Size}"$)
                    'Log(dfile.Size)
                    Dim floc As LocalFile = dfile.Local
                    Log($"canBeDeleted=${floc.canBeDeleted}"$)
                    Log($"canBeDownloaded=${floc.canBeDownloaded}"$)
                    Log($"Downloading active=${floc.isDownloadingActive}"$)
                    Log($"downloadedPrefixSize=${floc.downloadedPrefixSize}"$)
                    Log($"downloadedSize=${floc.downloadedSize}"$)
                    Log($"Downloading Completed=${floc.isDownloadingCompleted}"$)
                    Log(floc.Path)
                    If floc.canBeDownloaded And floc.isDownloadingCompleted = False Then
                        sdk.DownloadFile(dfile.Id,1)
                    End If
The result of the downloaded file...
"Path" is a absolute path (/path/to/file/onsdcard/file.ext)
B4X:
    else if tlo Is UpdateFile Then
        Dim updFile As UpdateFile = tlo
        Dim tfile As TdFile = updFile.TdFile
        'Log(tfile.Size)
        Log(tfile.Local)
        Dim lfile As LocalFile = tfile.Local
        Log("Downloading Completed: "&lfile.isDownloadingCompleted)
        Log("Downloaded Size: "&lfile.downloadedSize)
        Log("Downloaded Path: "&lfile.Path)
In case of the images in the Video above:

B4X:
    else if tlo Is UpdateNewMessage Then
        Dim newmsg As UpdateNewMessage = tlo
        Dim msg As Message = newmsg.Message
        Log(msg)
        Log(msg.senderUserId)
        If msg.Content Is MessagePhoto Then
            Log("Messagecontent Photo")
            Dim msgphoto As MessagePhoto = msg.Content
            Dim p As Photo = msgphoto.Photo
            Dim sizes As List = p.Sizes
            Log(sizes)
            If sizes <> Null And sizes.Size > 0 Then
                For i= 0 To sizes.Size -1
                    Dim phsizeObj As Object = sizes.Get(i)
                    Log(phsizeObj)
                    Dim phsize As PhotoSize = phsizeObj
                    Log(phsize)
                    Dim tfile As TdFile = phsize.Photo
                    Log(tfile)
                    Log(tfile.Id)
                    Log(tfile.Size)
                    If tfile.Local <> Null Then
                        Dim locfile As LocalFile = tfile.Local
                        Dim complpath As String = locfile.Path
                        If complpath.Length > 1 Then
                            Dim path As String = GetPath(complpath)
                            Dim filename As String = GetFilename(complpath)
                            'Log(path)
                            Log($"${filename} -> ${path}"$)
                            Dim bmp As Bitmap
                            bmp.Initialize(path,filename)
                            ImageView1.Bitmap = bmp
                        End If

It is quite complicated to work with the amount of Objects in this SDK. But they opens a lot of great possibilities :)
 

DonManfred

Expert
Licensed User
While downloading you´ll get multiple events (updates) for the running download. Until the download finishes.

SDK_onResult(UpdateFile)
LocalFile {
path = "/storage/emulated/0/Android/data/de.donmanfred.telegram/files/TelegramFiles/temp/3"
canBeDownloaded = true
canBeDeleted = true
isDownloadingActive = true
isDownloadingCompleted = false
downloadedPrefixSize = 153026560
downloadedSize = 153026560
}
Downloading Completed: false

SDK_onResult(UpdateFile)
LocalFile {
path = "/storage/emulated/0/Android/data/de.donmanfred.telegram/files/TelegramFiles/documents/Telegram.avi"
canBeDownloaded = true
canBeDeleted = true
isDownloadingActive = false
isDownloadingCompleted = true

downloadedPrefixSize = 153040896
downloadedSize = 153040896
}
Downloading Completed: true
Downloaded Size: 153040896
Downloaded Path: /storage/emulated/0/Android/data/de.donmanfred.telegram/files/TelegramFiles/documents/Telegram.avi
RemoteFile {
id = "BQADAgAD0wIAAtW2wUg_hVxjrJIa3gI"
isUploadingActive = false
isUploadingCompleted = true
uploadedSize = 153040896
}
 

devpialkt

Member
Licensed User
Got error with Version: 0.11

B4X:
onGetUpdatesFailure
com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `io.fouad.jtb.core.enums.MessageEntityType` from String "phone_number": value not one of declared Enum instance names: [italic, pre, bold, text_mention, mention, text_link, code, url, bot_command, email, hashtag]
Thank You
 

DonManfred

Expert
Licensed User
1. You should always create a new thread in the Questionsforum.

2. You are not providing enough useful informations. Try to log the incoming update. Maybe possible to get more info about it.

Do you know how i can reproduce it? What do i need to send/receive to get this error?

3. See the notes in Post 1

For any Question/Issue you have please Create a new Thread in the B4J Questionsforum
Edit to add:
Try V0.13 from Post #1
 
Last edited:

devpialkt

Member
Licensed User
Great, version v0.13 WORKED !!!

many thanks @DonManfred



1. You should always create a new thread in the Questionsforum.

2. You are not providing enough useful informations. Try to log the incoming update. Maybe possible to get more info about it.

Do you know how i can reproduce it? What do i need to send/receive to get this error?

3. See the notes in Post 1



Edit to add:
Try V0.13 from Post #1
 
Top