Java API for Telegram Bots and Gaming Platform
Full support of all Bot API 4.0 methods with Telegram Passport and Decryption API
Gradle:
compile 'com.github.pengrad:java-telegram-bot-api:4.0.0'
Maven:
<dependency>
<groupId>com.github.pengrad</groupId>
<artifactId>java-telegram-bot-api</artifactId>
<version>4.0.0</version>
</dependency>
JAR-file:
JAR with all dependencies on release page
- Creating your bot
- Making requests
- Getting updates
- Available types
- Available methods
- Updating messages
- Inline mode
- Payments
- Games
- Test Telegram Bot API
TelegramBot bot = new TelegramBot("BOT_TOKEN");
Network operations based on OkHttp library.
You can build bot with custom OkHttpClient, for specific timeouts or interceptors.
TelegramBot bot = new TelegramBot.Builder("BOT_TOKEN").okHttpClient(client).build();
Synchronous
BaseResponse response = bot.execute(request);
Asynchronous
bot.execute(request, new Callback() {
@Override
public void onResponse(BaseRequest request, BaseResponse response) {
}
@Override
public void onFailure(BaseRequest request, IOException e) {
}
});
Request in response to update
String response = request.toWebhookResponse();
You can use getUpdates request, parse incoming Webhook request, or set listener to receive updates.
Update object just copies Telegram's response.
class Update {
Integer updateId();
Message message();
Message editedMessage();
InlineQuery inlineQuery();
ChosenInlineResult chosenInlineResult();
CallbackQuery callbackQuery();
}
Building request
GetUpdates getUpdates = new GetUpdates().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
// sync
GetUpdatesResponse updatesResponse = bot.execute(getUpdates);
List<Update> updates = updatesResponse.updates();
...
Message message = update.message()
// async
bot.execute(getUpdates, new Callback<GetUpdates, GetUpdatesResponse>() {
@Override
public void onResponse(GetUpdates request, GetUpdatesResponse response) {
List<Update> updates = updatesResponse.updates();
}
@Override
public void onFailure(GetUpdates request, IOException e) {
}
});
Building request
SetWebhook request = new SetWebhook()
.url("url")
.certificate(new byte[]{}) // byte[]
.certificate(new File("path")); // or file
Executing
// sync
BaseResponse response = bot.execute(request);
boolean ok = response.isOk();
// async
bot.execute(request, new Callback<SetWebhook, BaseResponse>() {
@Override
public void onResponse(SetWebhook request, BaseResponse response) {
}
@Override
public void onFailure(SetWebhook request, IOException e) {
}
});
Using Webhook you can parse request to Update
Update update = BotUtils.parseUpdate(stringRequest); // from String
Update update = BotUtils.parseUpdate(reader); // or from java.io.Reader
Message message = update.message();
You can set listener to receiving incoming updates as if using Webhook.
This will trigger executing getUpdates requests in a loop.
bot.setUpdatesListener(new UpdatesListener() {
@Override
public int process(List<Update> updates) {
// process updates
return UpdatesListener.CONFIRMED_UPDATES_ALL;
}
});
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 specific update as last confirmed just return required updateId.
To stop receiving updates
bot.removeGetUpdatesListener();
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 request's type required params should be passed in constructor, optional params can be added in chains.
ForceReply, ReplyKeyboardRemove
Keyboard forceReply = new ForceReply(isSelective); // or just new ForceReply();
Keyboard replyKeyboardRemove = new ReplyKeyboardRemove(); // new ReplyKeyboardRemove(isSelective)
ReplyKeyboardMarkup
Keyboard replyKeyboardMarkup = new ReplyKeyboardMarkup(
new String[]{"first row button1", "first row button2"},
new String[]{"second row button1", "second row button2"})
.oneTimeKeyboard(true) // optional
.resizeKeyboard(true) // optional
.selective(true); // optional
KeyboardButton
Keyboard keyboard = new ReplyKeyboardMarkup(
new KeyboardButton[]{
new KeyboardButton("text"),
new KeyboardButton("contact").requestContact(true),
new KeyboardButton("location").requestLocation(true)
}
);
InlineKeyboardMarkup
InlineKeyboardMarkup inlineKeyboard = new InlineKeyboardMarkup(
new InlineKeyboardButton[]{
new InlineKeyboardButton("url").url("www.google.com"),
new InlineKeyboardButton("callback_data").callbackData("callback_data"),
new InlineKeyboardButton("switch_inline_query").switchInlineQuery("switch_inline_query")
});
ChatAction action = ChatAction.typing;
ChatAction action = ChatAction.upload_photo;
ChatAction action = ChatAction.find_location;
All request methods have the same names as original ones.
Required params should be passed in constructor.
Optional params can be added in chains.
All send requests (SendMessage, SendPhoto, SendLocation...) return SendResponse object that contains Message.
SendMessage request = new SendMessage(chatId, "text")
.parseMode(ParseMode.HTML)
.disableWebPagePreview(true)
.disableNotification(true)
.replyToMessageId(1)
.replyMarkup(new ForceReply());
// sync
SendResponse sendResponse = bot.execute(request);
boolean ok = sendResponse.isOk();
Message message = sendResponse.message();
// async
bot.execute(request, new Callback<SendMessage, SendResponse>() {
@Override
public void onResponse(SendMessage request, SendResponse response) {
}
@Override
public void onFailure(SendMessage request, IOException e) {
}
});
ParseMode parseMode = ParseMode.Markdown;
ParseMode parseMode = ParseMode.HTML;
GetFile request = new GetFile("fileId")
GetFileResponse getFileResponse = bot.execute(request);
File file = getFileResponse.file(); // com.pengrad.telegrambot.model.File
file.fileId();
file.filePath(); // relative path
file.fileSize();
To get downloading link as https://api.telegram.org/file/bot<token>/<file_path>
String fullPath = bot.getFullFilePath(file); // com.pengrad.telegrambot.model.File
All requests return BaseResponse if not mention here
class BaseResponse {
boolean isOk();
int errorCode();
String description();
}
GetMe request returns GetMeResponse
class GetMeResponse {
User user();
}
GetChatAdministrators
class GetChatAdministratorsResponse {
List<ChatMember> administrators()
}
GetChatMembersCount
class GetChatMembersCountResponse {
int count()
}
GetChatMember
class GetChatMemberResponse {
ChatMember chatMember()
}
GetChat
class GetChatResponse {
Chat chat()
}
GetUserProfilePhotos
class GetUserProfilePhotosResponse {
UserProfilePhotos photos()
}
Normal message
EditMessageText editMessageText = new EditMessageText(chatId, messageId, "new test")
.parseMode(ParseMode.HTML)
.disableWebPagePreview(true)
.replyMarkup(new ReplyKeyboardRemove());
BaseResponse response = bot.execute(editMessageText);
Inline message
EditMessageText editInlineMessageText = new EditMessageText(inlineMessageId, "new text");
BaseResponse response = bot.execute(editInlineMessageText);
Delete message
DeleteMessage deleteMessage = new DeleteMessage(chatId, messageId);
BaseResponse response = bot.execute(deleteMessage);
Getting updates
GetUpdatesResponse updatesResponse = bot.execute(new GetUpdates());
List<Update> updates = updatesResponse.updates();
...
InlineQuery inlineQuery = update.inlineQuery();
ChosenInlineResult chosenInlineResult = update.chosenInlineResult();
CallbackQuery callbackQuery = update.callbackQuery();
If using webhook, you can parse request to InlineQuery
Update update = BotUtils.parseUpdate(stringRequest); // from String
Update update = BotUtils.parseUpdate(reader); // from java.io.Reader
InlineQuery inlineQuery = update.inlineQuery();
InlineQueryResult r1 = new InlineQueryResultPhoto("id", "photoUrl", "thumbUrl");
InlineQueryResult r2 = new InlineQueryResultArticle("id", "title", "message text").thumbUrl("url");
InlineQueryResult r3 = new InlineQueryResultGif("id", "gifUrl", "thumbUrl");
InlineQueryResult r4 = new InlineQueryResultMpeg4Gif("id", "mpeg4Url", "thumbUrl");
InlineQueryResult r5 = new InlineQueryResultVideo(
"id", "videoUrl", InlineQueryResultVideo.MIME_VIDEO_MP4, "message", "thumbUrl", "video title")
.inputMessageContent(new InputLocationMessageContent(21.03f, 105.83f));
BaseResponse response = bot.execute(new AnswerInlineQuery(inlineQuery.id(), r1, r2, r3, r4, r5));
// or full
bot.execute(
new AnswerInlineQuery(inlineQuery.id(), new InlineQueryResult[]{r1, r2, r3, r4, r5})
.cacheTime(cacheTime)
.isPersonal(isPersonal)
.nextOffset("offset")
.switchPmParameter("pmParam")
.switchPmText("pmText")
);
Send invoice
SendInvoice sendInvoice = new SendInvoice(chatId, "title", "desc", "my_payload",
"providerToken", "my_start_param", "USD", new LabeledPrice("label", 200))
.needPhoneNumber(true)
.needShippingAddress(true)
.isFlexible(true)
.replyMarkup(new InlineKeyboardMarkup(new InlineKeyboardButton[]{
new InlineKeyboardButton("just pay").pay(),
new InlineKeyboardButton("google it").url("www.google.com")
}));
SendResponse response = bot.execute(sendInvoice);
Answer shipping query
AnswerShippingQuery answerShippingQuery = new AnswerShippingQuery(shippingQueryId,
new ShippingOption("1", "VNPT", new LabeledPrice("delivery", 100), new LabeledPrice("tips", 50)),
new ShippingOption("2", "FREE", new LabeledPrice("free delivery", 0))
);
BaseResponse response = bot.execute(answerShippingQuery);
// answer with error
AnswerShippingQuery answerShippingError = new AnswerShippingQuery(shippingQueryId, "Can't delivery to your address");
BaseResponse response = bot.execute(answerShippingError);
Answer pre-checkout query
AnswerPreCheckoutQuery answerCheckout = new AnswerPreCheckoutQuery(preCheckoutQueryId);
BaseResponse response = bot.execute(answerPreCheckoutQuery);
// answer with error
AnswerPreCheckoutQuery answerCheckout = new AnswerPreCheckoutQuery(preCheckoutQueryId, "Sorry, item not available");
BaseResponse response = bot.execute(answerPreCheckoutQuery);
Send game
SendResponse response = bot.execute(new SendGame(chatId, "my_super_game"));
Set game score
BaseResponse response = bot.execute(new SetGameScore(userId, score, chatId, messageId));
Get game high scores
GetGameHighScoresResponse response = bot.execute(new GetGameHighScores(userId, chatId, messageId));
GameHighScore[] scores = response.result();
Test on RapidAPI