Skip to content

Repository files navigation

Java Telegram Bot API

Maven Centralcodecov

Java library for interacting with Telegram Bot API

Download

Gradle:

implementation 'com.github.pengrad:java-telegram-bot-api:6.9.1'

Maven:

<dependency>
<groupId>com.github.pengrad</groupId>
<artifactId>java-telegram-bot-api</artifactId>
<version>6.9.1</version>
</dependency>

JAR with all dependencies on release page

Usage

// Create your bot passing the token received from @BotFatherTelegramBotbot = newTelegramBot("BOT_TOKEN");
// Register for updatesbot.setUpdatesListener(updates -> {
// ... process updates// return id of last processed update or confirm them allreturnUpdatesListener.CONFIRMED_UPDATES_ALL;
// Create Exception Handler
}, e -> {
if (e.response() != null) {
// got bad response from telegrame.response().errorCode();
e.response().description();
} else {
// probably network errore.printStackTrace();
}
});
// Send messageslongchatId = update.message().chat().id();
SendResponseresponse = bot.execute(newSendMessage(chatId, "Hello!"));

Documentation

Creating your bot

TelegramBotbot = newTelegramBot("BOT_TOKEN");

Network operations based on OkHttp library.
You can build bot with custom OkHttpClient, for specific timeouts or interceptors.

TelegramBotbot = newTelegramBot.Builder("BOT_TOKEN").okHttpClient(client).build();

Making requests

Synchronous

BaseResponseresponse = bot.execute(request);

Asynchronous

bot.execute(request, newCallback() {
@OverridepublicvoidonResponse(BaseRequestrequest, BaseResponseresponse) {
}
@OverridepublicvoidonFailure(BaseRequestrequest, IOExceptione) {
}
});

Request in response to update

Stringresponse = request.toWebhookResponse();

Getting updates

You can use getUpdates request, parse incoming Webhook request, or set listener to receive updates.
Update object just copies Telegram's response.

classUpdate {
IntegerupdateId();
Messagemessage();
MessageeditedMessage();
InlineQueryinlineQuery();
ChosenInlineResultchosenInlineResult();
CallbackQuerycallbackQuery();
}

Get updates

Building request

GetUpdatesgetUpdates = newGetUpdates().limit(100).offset(0).timeout(0);

The getUpdates method returns the earliest 100 unconfirmed updates. To confirm an update, use the offset parameter when calling getUpdates like this: offset = updateId of last processed update + 1
All updates with updateId less than offset will be marked as confirmed on the server and will no longer be returned.

Executing

// syncGetUpdatesResponseupdatesResponse = bot.execute(getUpdates);
List<Update> updates = updatesResponse.updates();
...
Messagemessage = update.message()
// asyncbot.execute(getUpdates, newCallback<GetUpdates, GetUpdatesResponse>() {
@OverridepublicvoidonResponse(GetUpdatesrequest, GetUpdatesResponseresponse) {
List<Update> updates = response.updates();
}
@OverridepublicvoidonFailure(GetUpdatesrequest, IOExceptione) {
}
});

Webhook

Building request

SetWebhookrequest = newSetWebhook()
.url("url")
.certificate(newbyte[]{}) // byte[]
.certificate(newFile("path")); // or file 

Executing

// syncBaseResponseresponse = bot.execute(request);
booleanok = response.isOk();
// asyncbot.execute(request, newCallback<SetWebhook, BaseResponse>() {
@OverridepublicvoidonResponse(SetWebhookrequest, BaseResponseresponse) {
}
@OverridepublicvoidonFailure(SetWebhookrequest, IOExceptione) {
}
});

Using Webhook you can parse request to Update

Updateupdate = BotUtils.parseUpdate(stringRequest); // from StringUpdateupdate = BotUtils.parseUpdate(reader); // or from java.io.ReaderMessagemessage = update.message();

Updates Listener

You can set a listener to receive incoming updates as if using Webhook.
This will trigger executing getUpdates requests in a loop.

bot.setUpdatesListener(newUpdatesListener() {
@Overridepublicintprocess(List<Update> updates) {
// process updatesreturnUpdatesListener.CONFIRMED_UPDATES_ALL;
}
// Create Exception Handler
}, newExceptionHandler() {
@overridepublicvoidonException(TelegramExceptione)
{
if (e.response() != null) {
// got bad response from telegrame.response().errorCode();
e.response().description();
} else {
// probably network errore .printStackTrace();
}
}
});

Listener should return id of the last processed (confirmed) update.
To confirm all updates return UpdatesListener.CONFIRMED_UPDATES_ALL, this should be enough in most cases.
To not confirm any updates return UpdatesListener.CONFIRMED_UPDATES_NONE, these updates will be redelivered.
To set a specific update as last confirmed, just return the required updateId.

To stop receiving updates

bot.removeGetUpdatesListener();

Available types

All types have the same name as original ones.
Type's fields are methods in lowerCamelCase.

Types used in responses (Update, Message, User, Document...) are in com.pengrad.telegrambot.model package.

Types used in requests (Keyboard, InlineQueryResult, ParseMode, InputMessageContent...) are in com.pengrad.telegrambot.model.request package.
When creating a request's type, required params should be passed in the constructor, optional params can be added in chains.

Keyboards

ForceReply, ReplyKeyboardRemove

KeyboardforceReply = newForceReply(isSelective); // or just new ForceReply();KeyboardreplyKeyboardRemove = newReplyKeyboardRemove(); // new ReplyKeyboardRemove(isSelective)

ReplyKeyboardMarkup

KeyboardreplyKeyboardMarkup = newReplyKeyboardMarkup(
newString[]{"first row button1", "first row button2"},
newString[]{"second row button1", "second row button2"})
.oneTimeKeyboard(true) // optional
.resizeKeyboard(true) // optional
.selective(true); // optional

KeyboardButton

Keyboardkeyboard = newReplyKeyboardMarkup(
newKeyboardButton[]{
newKeyboardButton("text"),
newKeyboardButton("contact").requestContact(true),
newKeyboardButton("location").requestLocation(true)
}
); 

InlineKeyboardMarkup

InlineKeyboardMarkupinlineKeyboard = newInlineKeyboardMarkup(
newInlineKeyboardButton[]{
newInlineKeyboardButton("url").url("www.google.com"),
newInlineKeyboardButton("callback_data").callbackData("callback_data"),
newInlineKeyboardButton("Switch!").switchInlineQuery("switch_inline_query")
});

Chat Action

ChatActionaction = ChatAction.typing;
ChatActionaction = ChatAction.upload_photo;
ChatActionaction = ChatAction.find_location;

Available methods

All request methods have the same names as original ones.
Required params should be passed in the constructor.
Optional params can be added in chains.

Send message

All send requests (SendMessage, SendPhoto, SendLocation...) return SendResponse object that contains Message.

SendMessagerequest = newSendMessage(chatId, "text")
.parseMode(ParseMode.HTML)
.disableWebPagePreview(true)
.disableNotification(true)
.replyToMessageId(1)
.replyMarkup(newForceReply());
// syncSendResponsesendResponse = bot.execute(request);
booleanok = sendResponse.isOk();
Messagemessage = sendResponse.message();
// asyncbot.execute(request, newCallback<SendMessage, SendResponse>() {
@OverridepublicvoidonResponse(SendMessagerequest, SendResponseresponse) {
}
@OverridepublicvoidonFailure(SendMessagerequest, IOExceptione) {
}
});

Formatting options

ParseModeparseMode = ParseMode.Markdown;
ParseModeparseMode = ParseMode.HTML;

Get file

GetFilerequest = newGetFile("fileId")
GetFileResponsegetFileResponse = bot.execute(request);
Filefile = getFileResponse.file(); // com.pengrad.telegrambot.model.Filefile.fileId();
file.filePath(); // relative pathfile.fileSize();

To get downloading link as https://api.telegram.org/file/<BOT_TOKEN>/<FILE_PATH>

StringfullPath = bot.getFullFilePath(file); // com.pengrad.telegrambot.model.File

Other requests

All requests return BaseResponse if not mention here

classBaseResponse {
booleanisOk();
interrorCode();
Stringdescription();
}

GetMe request returns GetMeResponse

classGetMeResponse {
Useruser();
}

GetChatAdministrators

classGetChatAdministratorsResponse {
List<ChatMember> administrators()
}

GetChatMembersCount

classGetChatMembersCountResponse {
intcount() }

GetChatMember

classGetChatMemberResponse {
ChatMemberchatMember()
}

GetChat

classGetChatResponse {
Chatchat()
}

GetUserProfilePhotos

classGetUserProfilePhotosResponse {
UserProfilePhotosphotos()
}

StopPoll

classPollResponse {
Pollpoll()
}

Updating messages

Normal message

EditMessageTexteditMessageText = newEditMessageText(chatId, messageId, "new test")
.parseMode(ParseMode.HTML)
.disableWebPagePreview(true)
.replyMarkup(newReplyKeyboardRemove());
BaseResponseresponse = bot.execute(editMessageText);

Inline message

EditMessageTexteditInlineMessageText = newEditMessageText(inlineMessageId, "new text");
BaseResponseresponse = bot.execute(editInlineMessageText);

Delete message

DeleteMessagedeleteMessage = newDeleteMessage(chatId, messageId);
BaseResponseresponse = bot.execute(deleteMessage);

Stickers

Send sticker

// File or byte[] or string fileId of existing sticker or string URLSendStickersendSticker = newSendSticker(chatId, imageFile);
SendResponseresponse = bot.execute(sendSticker);

Get sticker set

GetStickerSetgetStickerSet = newGetStickerSet(stickerSet);
GetStickerSetResponseresponse = bot.execute(getStickerSet);
StickerSetstickerSet = response.stickerSet();

Upload sticker file

// File or byte[] or string URLUploadStickerFileuploadStickerFile = newUploadStickerFile(chatId, stickerFile);
GetFileResponseresponse = bot.execute(uploadStickerFile);

Inline mode

Getting updates

GetUpdatesResponseupdatesResponse = bot.execute(newGetUpdates());
List<Update> updates = updatesResponse.updates();
...
InlineQueryinlineQuery = update.inlineQuery();
ChosenInlineResultchosenInlineResult = update.chosenInlineResult();
CallbackQuerycallbackQuery = update.callbackQuery();

If using webhook, you can parse request to InlineQuery

Updateupdate = BotUtils.parseUpdate(stringRequest); // from StringUpdateupdate = BotUtils.parseUpdate(reader); // from java.io.ReaderInlineQueryinlineQuery = update.inlineQuery();

Inline query result

InlineQueryResultr1 = newInlineQueryResultPhoto("id", "photoUrl", "thumbUrl");
InlineQueryResultr2 = newInlineQueryResultArticle("id", "title", "message text").thumbUrl("url");
InlineQueryResultr3 = newInlineQueryResultGif("id", "gifUrl", "thumbUrl");
InlineQueryResultr4 = newInlineQueryResultMpeg4Gif("id", "mpeg4Url", "thumbUrl");
InlineQueryResultr5 = newInlineQueryResultVideo(
"id", "videoUrl", InlineQueryResultVideo.MIME_VIDEO_MP4, "message", "thumbUrl", "video title")
.inputMessageContent(newInputLocationMessageContent(21.03f, 105.83f));

Answer inline query

BaseResponseresponse = bot.execute(newAnswerInlineQuery(inlineQuery.id(), r1, r2, r3, r4, r5));
// or fullbot.execute(
newAnswerInlineQuery(inlineQuery.id(), newInlineQueryResult[]{r1, r2, r3, r4, r5})
.cacheTime(cacheTime)
.isPersonal(isPersonal)
.nextOffset("offset")
.switchPmParameter("pmParam")
.switchPmText("pmText")
);

Payments

Send invoice

SendInvoicesendInvoice = newSendInvoice(chatId, "title", "desc", "my_payload",
"providerToken", "my_start_param", "USD", newLabeledPrice("label", 200))
.needPhoneNumber(true)
.needShippingAddress(true)
.isFlexible(true)
.replyMarkup(newInlineKeyboardMarkup(newInlineKeyboardButton[]{
newInlineKeyboardButton("just pay").pay(),
newInlineKeyboardButton("google it").url("www.google.com")
}));
SendResponseresponse = bot.execute(sendInvoice);

Answer shipping query

LabeledPrice[] prices = newLabeledPrice[]{
newLabeledPrice("delivery", 100),
newLabeledPrice("tips", 50)
};
AnswerShippingQueryanswerShippingQuery = newAnswerShippingQuery(shippingQueryId,
newShippingOption("1", "VNPT", prices),
newShippingOption("2", "FREE", newLabeledPrice("free delivery", 0))
);
BaseResponseresponse = bot.execute(answerShippingQuery);
// answer with errorAnswerShippingQueryanswerShippingError = newAnswerShippingQuery(id, "Can't deliver here!");
BaseResponseresponse = bot.execute(answerShippingError);

Answer pre-checkout query

AnswerPreCheckoutQueryanswerCheckout = newAnswerPreCheckoutQuery(preCheckoutQueryId);
BaseResponseresponse = bot.execute(answerPreCheckoutQuery);
// answer with errorAnswerPreCheckoutQueryanswerCheckout = newAnswerPreCheckoutQuery(id, "Sorry, item not available");
BaseResponseresponse = bot.execute(answerPreCheckoutQuery);

Telegram Passport

When the user confirms your request by pressing the ‘Authorize’ button, the Bot API sends an Update with the field passport_data to the bot that contains encrypted Telegram Passport data. Telegram Passport Manual

Receiving information

You can get encrypted Passport data from Update (via UpdatesListener or Webhook)

PassportDatapassportData = update.message().passportData();

PassportData contains anarray of EncryptedPassportElement and EncryptedCredentials.
You need to decrypt Credentials using private key (public key you uploaded to @BotFather)

StringprivateKey = "...";
EncryptedCredentialsencryptedCredentials = passportData.credentials();
Credentialscredentials = encryptedCredentials.decrypt(privateKey);

These Credentials can be used to decrypt encrypted data in EncryptedPassportElement.

EncryptedPassportElement[] encryptedPassportElements = passportData.data();
for (EncryptedPassportElementelement : encryptedPassportElements) {
DecryptedDatadecryptedData = element.decryptData(credentials);
// DecryptedData can be cast to specific type by checking instanceOf if (decryptedDatainstanceofPersonalDetails) {
PersonalDetailspersonalDetails = (PersonalDetails) decryptedData;
}
// Or by checking type of passport elementif (element.type() == EncryptedPassportElement.Type.address) {
ResidentialAddressaddress = (ResidentialAddress) decryptedData;
}
}

EncryptedPassportElement also contains an array of PassportFile (file uploaded to Telegram Passport).
You need to download them 1 by 1 and decrypt content.
This library supports downloading and decryption, returns decrypted byte[]

EncryptedPassportElementelement = ...
// Combine all files List<PassportFile> files = newArrayList<PassportFile>();
files.add(element.frontSide());
files.add(element.reverseSide());
files.add(element.selfie());
if (element.files() != null) {
files.addAll(Arrays.asList(element.files()));
}
if (element.translation() != null) {
files.addAll(Arrays.asList(element.translation()));
}
// Decryptfor (PassportFilefile : files) {
if (file == null) continue;
byte[] data = element.decryptFile(file, credentials, bot); // GetFile request and decrypt content// save to file if needednewFileOutputStream("files/" + element.type()).write(data);
}

Set Passport data errors

SetPassportDataErrorssetPassportDataErrors = newSetPassportDataErrors(chatId,
newPassportElementErrorDataField("personal_details", "first_name", "dataHash",
"Please enter a valid First name"),
newPassportElementErrorSelfie("driver_license", "fileHash",
"Can't see your face on photo")
);
bot.execute(setPassportDataErrors);

Games

Send game

SendResponseresponse = bot.execute(newSendGame(chatId, "my_super_game"));

Set game score

BaseResponseresponse = bot.execute(newSetGameScore(userId, score, chatId, messageId));

Get game high scores

GetGameHighScoresResponseresponse = bot.execute(newGetGameHighScores(userId, chatId, messageId));
GameHighScore[] scores = response.result();

About

Telegram Bot API for Java

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages