- Installation
- Your First Echo Bot
- Available Types
- Available Methods
- Handling Updates
- Types of Handlers
- Filtering Updates
- Markup
- Inline Bot
- Using Webhook
- Advanced Usages
- Error Handling
- Conclusion
- Maven
<dependecy>
<groupId>et.telebof</groupId>
<artifactId>telegrambot</artifactId>
<version>1.13.2-alpha</version>
</dependecy>
- Grade
implementation 'et.telebof:telegrambot:1.13.2-alpha'
import et.telebof.BotClient;
public class MyFirstEchoBot {
static final String TOKEN = "YOUR_BOT_TOKEN_HERE";
public static void main(String[] args) {
final BotClient bot = new BotClient(TOKEN);
// Listening for /start command
bot.onMessage(filter -> filter.commands("start"), (context, message) -> {
context.reply("Welcome!").exec();
});
// Listening for any text
bot.onMessage(filter -> filter.text(), (context, message) -> {
context.reply(message.text).exec();
});
bot.run(); // finally run the bot
}
}
Do not worry if you do not understand what the above code mean, it will be explained in the next chapter.
All Telegram types are defined in et.telebof.types
. And they are completely the same as Telegram types.
Their set method is their camelCased name method
All Telegram methods are defined in et.telebof.request
and implemented in et.telebof.BotContext
class.
These methods can be used in 2 ways: Inside handler using context
parameter and Outside handler using bot.context
instance.
No need to pass chat_id
or user_id
to the methods need it as argument using context
argument or bot.context
instance
chat_id
or user_id
must be passed to the methods need it as argument using bot.context
instance
/* Inside Handler */
// send message
context.sendMessage("Hello, World").exec(); // or
context.sendMessage(message.chat.id, "Hello, World").exec();
// The same as
bot.context.sendMessage("Hello, World").exec();
bot.context.sendMessage(message.chat.id, "Hello, World").exec();
// send Photo
context.sendPhoto(new File("photo.png")).exec(); // or
context.sendPhoto(message.chat.id, new File("photo.png")).exec();
// The same as
bot.context.sendPhoto(new File("photo.png")).exec(); // or
bot.context.sendPhoto(message.chat.id, new File("photo.png")).exec();
/* Outside Handler */
bot.context.sendMessage(123456789L, "Hello, World").exec();
bot.context.sendPhoto(123456789L, new File("photo.png")).exec();
Assume that in our examples it is inside handler
// send photo
context.sendPhoto(new File("photo.png")).exec(); // or
context.sendPhoto("FILE_ID").exec();
// send audio
context.sendAudio(new File("audio.mp3")).exec();
context.sendAudio("FILE_ID").exec();
// send video
context.sendVideo(new File("video.mp4")).exec();
context.sendVideo("FILE_ID").exec();
// send voice
context.sendVoice(new File("voice.ogg")).exec();
context.sendVoice("FILE_ID").exec();
// send document
context.sendDocument(new File("doc.pdf")).exec();
context.sendDucument("FILE_ID").exec();
// send animation
context.sendAnimation(new File("animation.gif")).exec();
context.sendAnimation("FILE_ID").exec();
// send contact
context.sendContact(phone_number, first_name).exec();
// send poll
InputPollOption option1 = new InputPollOption("option 1");
InputPollOption option2 = new InputPollOption("option 2")
context.sendPoll(question, new InputPollOption[]{option1, option2}).exec();
// send invoice
LabeledPrice price1 = new LabeledPrice(label1, amount1);
context.sendInvoice(title, dscription, payload, currency, new LabeledPrice[]{price1}).exec();
// send media group
InputMediaPhoto media1 = new InputMediaPhoto(new File("photo_1.png"));
InputMediaPhoto media2 = new InputMediaPhoto(new File("photo_2.png"));
context.sendMediaGroup(new InputMedia[]{media1, media2}).exec();
// get me
User me = context.getMe().exec();
System.out.println(me.username);
// ban chat member
context.banChatMember(user_id).exec();
// leave chat
context.leaveChat().exec();
Update is an event that bot receives like incoming messages, pressing button.
Updates are handled by registering one or more callback classes.
Each update has its own handler. These handlers take two parameters as argument: filter class
and callback class. The filter class is a lambda class of et.telebof.filter.FilterExecutor
takes et.telebof.filter.Filter
as an argument and returns Boolean
, so that if the condition of this filter
matches with the update sent from telegram, the callback class will be called and its body gets execute.
The callback class takes two parameters: et.telebof.BotContext
class and type of class of an update which is being handled
Let's back to the first echo bot example.
import et.telebof.BotClient;
public class MyFirstEchoBot {
static final String TOKEN = "YOUR_BOT_TOKEN_HERE";
public static void main(String[] args) {
final BotClient bot = new BotClient(TOKEN);
bot.onMessage(filter -> filter.commands("start"), (context, message) -> {
context.reply("Welcome!").exec();
});
bot.onMessage(filter -> filter.text(), (context, message) -> {
context.reply(message.text).exec();
});
bot.run();
}
}
We have two handlers: /start
command handler and text
handler.
-
The first handler handles
/start
command and send back a textWelcome!
. -
The second handler handles any incoming text and echoes the text.
-
The
reply
method is a shortage ofsendMessage
and replies message to the message. -
exec()
meaningexecute
is an enclosing and request sender method. This means before ending and sending request, you can pass optional parameters and then send a request to telegram. For examplesendMessage
method has optional parametersparse_mode
,reply_markup
. So you can pass their value for these parameters and send request to telegram.
import et.telebof.enums.ParseMode;
context.sendMessage("*Hello, World*")
.parseMode(ParseMode.MARKDOWN)
.exec();
Lastly we start our bot by using run()
which does not take any parameter and run our bot via long polling.
IMPORTANT: All handlers are handled in the order in which they were registered.
There are 22 types of updates to be handled
bot.onMessage((context, message) -> {});
bot.onCallback((context, callback) -> {});
bot.onInline((context, query) -> {} );
bot.onPoll((context, poll) -> {});
bot.onPoll((context, poll_answer) -> {});
bot.onShipping((context, shipping) -> {});
bot.onChannelPost((context, channel_post) -> {});
bot.onPreCheckout((context, pre_checkout) -> {});
bot.onEditedMessage((context, edited_message) -> {});
bot.onEditedChannelPost((context, edited_channel_post) -> {});
bot.onMychatMember((context, chat_updated) -> {});
bot.onChatMember((context, chat_member) -> {});
bot.onChosenInlineResult((context, chosen) -> {});
bot.onReaction((context, reaction) -> {});
bot.onReactionCount((context, reaction_count) -> {});
bot.onChatBoost((context, chat_boost) -> {});
bot.onRemovedChatBoost((context, removed_chat_boost) -> {});
bot.onBusinessMessage((context, businnes_message) -> {});
bot.onBusinessConnection((context, business_connection) -> {});
bot.onEditedBusinessMessage((context, edited_business_message) -> {});
bot.onDeletedBusinessMessage((context, deleted_business_message) -> {});
If only callback class is passed to a handler, the filter class will return true
by default
bot.onMessage((context, message) -> {});
The same as
bot.onMessage(filter -> true, (context, message) -> {});
In previous topic we have seen how to create handlers and how they work. In this section we will talk about how filters work and how we use them.
As previously discussed, all handlers take two parameters: filter class and callback class.
The filter class is used for filtering content of updates and separate the same update by content they hold.
filter.text()
- filter message is textfiler.photo()
- filter message is photofilter.video()
- filter message is videofilter.voice()
- filter message is voicefilter.audio()
- filter message is audiofilter.animation()
- filter message is animationfilter.document()
- filter message is documentfilter.videoNote()
- filter message is video notefilter.contact()
- filter message is contactfilter.loaction()
- filter message is locationfilter.game()
- filter message is gamefilter.venue()
- filter message is venuefilter.sticker()
- filter message is stickerfilter.dice()
- filter message is dicefilter.invoice()
- message is an invoice for a paymentfilter.media()
- filter message is one of the following: photo, video, audio, sticker, video_note, voice, animation, document.filter.passportData()
- message is Telegram passport datafilter.usersShared()
- filter users were shared with the botfilter.chatShared()
- filter chat was shared with the botfilter.newChatMember()
- filter new members joined or added to the groupfilter.leftChatMember()
- filter member left from the groupfilter.newChatPhoto()
- filter a chat photo was changedfilter.newChatTitle()
- filter a chat title was changedfilter.groupCreated()
- filter a group chat was createdfilter.supergroupCreated()
- filter a supergroup chat was createdfilter.channelCreated()
- filter a channel was createdfilter.messageAutoDeleteTimerChanged()
- filter auto-delete timer settings changed in the chatfilter.migrated()
- filter the group/supergroup has been migrated to/from a supergroup/groupfilter.chatBackgroundSet()
filter chat background setfilter.pinnedMessage()
- filter a message was pinnedfilter.successfulPayment()
- filter message about successful paymentfilter.refundedPayment()
- filter message about refunded paymentfilter.proximityAlertTrigged()
- filter a user in the chat triggered another user's proximity alertfilter.boostAdded()
- filter user boosted the chatfilter.giveaway()
- filter message is scheduled giveawayfilter.giveawayCreated()
- filter a scheduled giveaway was createdfilter.giveawayCompleted()
- a giveaway without public winners was completedfilter.forumTopicCreated()
- filter forum topic createdfilter.forumTopicClosed()
- filter forum topic closedfilter.forumTopicEdited()
- filter forum topic editedfilter.forumTopicReopned()
- filter forum topic reopenedfilter.webAppData()
- filter data sent by a Web Appfilter.videoChatStarted()
- filter video chat was started in the chatfilter.videoChatEnded()
- filter video chat was ended in the chatfilter.videoChatParticipantsInvited()
- filter new participants invited to a video chatfilter.videoChatScheduled()
- filter video chat scheduledfilter.forwarded()
- filter message was forwardedfilter.replied()
- filter message was replied to another messagefilter.repliedToStory()
- filter message was replied to chat storyfilter.entities()
- filter message text contains entities(bold, italic, underline, mention, url, hashtag)filter.quote()
- filter message text contains quotefilter.bot()
- filter user is botfilter.emptyQuery()
- filter query is emptyfilter.Private()
- filter the chat isprivate
filter.group()
- filter the chat type isgroup
filter.supergroup()
- filter chat type issupergroup
filter.channel()
- filter chat type ischannel
filter.commands(String... commands)
- filter message is given commands.filter.callbackData(String... datas)
- filter given callback_data belongs to the pressed button.filter.inlineQuery(String... queries)
- filter given query is queriedfilter.customFilter(CustomFilter cf)
- filter given filterfilter.state(String state)
- filter current state is given state. Pass*
for filtering any statefilter.texts(String... texts)
- filter given text matched with message textfilter.chatIds(Long... ids)
- filter given id matched with current chat's idfilter.fromIds(Long... ids)
- filter given id matched with current user's idfilter.chatUsernames(String... usernames)
- filter given username matched with current chat's usernamefilter.usernames(String... usernames)
- filter given username matched with current user's usernamefilter.regex(String pattern)
- regular expression filter for message text
// handles incoming texts
bot.onMessage(filter -> filter.text(), (context, message) -> {});
// handles incoming photos
bot.onMessage(filter -> filter.photo(), (context, message) -> {});
// handles incoming videos
bot.onMessage(filter -> filter.video(), (context, message) -> {});
// handles message in chat with chat_id of 123456789
bot.onMessage(filter -> filter.chatIds(123456789L), (context, message) -> {});
// handles message from user whose id is 123456789
bot.onMessage(filter -> filter.fromIds(123456789L), (context, message) -> {});
// handles message in chat username @this_chat
bot.onMessage(filter -> filter.chatUsernames("this_chat"), (context, message) -> {});
// handles message from user whose username is @this_user
bot.onMessage(filter -> filter.usernames("this_user"), (context, message) -> {});
### Filtering message text
Message text can be filtered by using the following methods: `filter.commands`, `filter.texts`, `filter.regex`.
#### Filtering command
```java
// handles /start command
bot.onMessage(filter -> filter.commands("start"), (context, message) -> {});
// handles /help command
bot.onMessage(filter -> filter.commands("help"), (context, message) -> {});
// handles hi text
bot.onMessage(filter -> filter.texts("hi"), (context, message) -> {});
// handles hello text
bot.onMessage(filter -> filter.texts("hello"), (context, message) -> {});
// handles any text starts with hi
bot.onMessage(filter -> filter.regex("^hi"), (context, message) -> {});
// handles any text ends with bye
bot.onMessage(filter -> filter.regex("bye$"), (context, message) -> {});
You may want to handle text
and photo
in one handler or a text
in different chats. To do so use logical operators
(&&, ||, !) and combine them together.
Here are some examples
// handles incoming text in private chat
bot.onMessage(filter -> filter.text() && filter.Private(), (context, message) -> {});
// handles an incoming text or photo
bot.onMessage(filter -> filter.text() || filter.photo(), (context, message) -> {});
// handles incoming text in supergroup chat
bot.onMessage(filter -> filter.text() && filter.supergroup(), (context, message) -> {});
// handles incoming audio or video in private chat
bot.onMessage(filter -> filter.Private() && (filter.audio() || filter.video()), (context, message) -> {});
You can write your own filter using filter.customFilter
.
This example will show you how you can write filters using et.telebof.filters.CustomFilter
and filter.customFilter
.
Let's write simple custom filter whether incoming text starts with !
or not.
import et.telebof.BotContext;
import et.telebof.filters.CustomFilter;
import et.telebof.handlers.MessageHandler;
import et.telebof.types.Message;
import et.telebof.types.Update;
// Filter whether the incoming message text starts with `!`. or not
class StartsWithFilter implements CustomFilter {
@Override
public boolean check(Update update) {
return update.message.text.startsWith("!");
}
}
public class FilterBot {
static void startsWith(BotContext context, Message message){
context.sendMessage("Message starts with !").exec();
}
public static void main(String[] args) {
// ...
bot.onMessage(filter -> filter.text() && filter.customFilter(new StartsWithFilter()),
FilterBot::startsWith);
}
}
There are some advanced filters for handling pressing button
and inline query
. These are
filter.callbackData
and filter.inlineQuery
respectively.
Example for handling inline button through its callback data using filter.callbackData
// handles inline button which its callback data equals with "a"
bot.onCallback(filter -> filter.callbackData("a"), (context, callback) -> {
context.answer("You pressed A button!").exec();
});
Example for handling inline query using filter.inlineQuery
// handles an inline query which its query equals with a word "hello"
bot.onInline(filter -> filter.inlineQuery("hello"), (context, query) -> {});
There is another special filter to make conversations with bot called state filter
.
bot.onMessage(filter -> filter.commands("start"), (context, message) -> {
context.sendMessage("What is your name?").exec();
bot.setState(message.from.id, "name"); // set our state to `name`. You can set whatever
});
bot.onMessage(filter -> filter.state("name") && filter.text(), (context, message) -> {
context.sendMessage(String.format("Your name is %s", message.text)).exec();
context.clearState(message.from.id);
});
Example for using reply markup
import et.telebof.types.ReplyKeyboardMarkup;
import et.telebof.types.KeyboardButton;
ReplyKeyboardMarkup markup = new ReplyKeyboardMarkup()
.resizeKeyboard(true); // resize keyboard
markup.add("A", "B", "C"); // You can add String or
markup.add("D", "E");
markup.add(new KeyboardButton("F")); // KeybaordButton class
context.sendMssage("Hello, World!").replyMarkup(markup).exec();
example for using InlineKeyboardMarkup
import et.telebof.types.InlineKeyboardButton;
import et.telebof.types.InlineKeyboardMarkup;
InlineKeybaordMarkup inlineMarkup = new InlineKeybaordMarkup();
inlineMarkup.addKeybaord(
new InlineKeybaordButton("A").callbackData("a"),
new InlineKeybaordButton("C").callbackData("b"),
new InlineKeybaordButton("Url").url("www.example.com")
); // 3 keyboards on a row
// also possible
InlineKeybaordMarkup inlineMarkup = new InlineKeybaordMarkup(new InlineKeybaordButton[]{
new InlineKeybaordButton("A").callbackData("a"),
new InlineKeybaordButton("B").callbackData("b"),
new InlineKeyboardButton("Url").url("www.example.com")
}, 2); // 2 row width. i.e 2 keyboards on a row at max
// also possible
InlineKeybaordMarkup inlineMarkup = new InlineKeybaordMarkup(new InlineKeybaordButton[][]{
new InlineKeybaordButton[]{
new InlineKeybaordButton("A").callbackData("a"),
new InlineKeybaordButton("B").callbackData("b")
},
new InlineKeyboardButton[]{
new InlineKeyboardButton("Url").url("www.example.com")
}
}
);
context.sendMessage("Press one button").replyMarkup(inlineMarkup).exec();
import et.telebof.types.ForceReply;
context.sendMessage("Can you tell me your name please?")
.replyMarkup(new ForceReply())
.exec();
import et.telebof.types.ReplyKeyboardMarkup;
context.sendMessage("There is no reply keyboard now")
.replyMarkup(new RemoveReplyKeybaord())
.exec();
import et.telebof.types.InlineQueryResult;
import et.telebof.types.InlineQueryResultArticle;
import et.telebof.types.InputTextMessageContent;
bot.onInline(filter -> filter.emptyQuery(), (context, query) -> {
InlineQueryResultArticle article = new InlineQueryResultArticle("1")
.title("Write something")
.description("click here")
.inputTextMessageContent(new InputTextMessageContent("Please write something"));
context.answerInline(new InlineQueryResult[]{article}).exec();
});
import et.telebof.Webhook;
import java.io.File;
class MyWebhookBot {
public static void main(String[] args) {
Webhook webhook = new Webhook("www.example.com", "/bot"); // URL and path respectively
//...
bot.deleteWebhook(); // first delete webhook if any
bot.setWebhook(webhook); // set webhook
//...
bot.run(); // start our bot on webhook
}
}
import et.telebof.BotClient;
String url = "https://example.com/bot%s/%s";
BotClient bot = new BotClient.Builder(TOKEN)
.localBotApiUrl(url)
.build();
You have to log out your bot from the Telegram server before switching to your local API server using bot.context.logOut().exec()
log current status of the bot.
import et.telebof.BotClient;
BotClient bot = new BotClient.Builder(TOKEN)
.log(true)
.build();
import et.telebof.BotClient;
import java.net.InetSocketAddress;
import java.net.Proxy;
InetSocketAddress address = new InetSocketAddress(80, "127.97.91"); //port and hostname respectively
Proxy proxy = new Proxy(Proxy.Type.SOCKS, address);
BotClient bot = new BotClient
.Builder(TOKEN)
.proxy(proxy)
.build();
Finally
import et.telebof.BotClient;
import et.telebof.enums.ParseMode;
import et.telebof.enums.Updates;
BotClient bot = new BotClient.Builder(TOKEN)
.log(true) // Log current status
.skipOldUpdates(false) // Receive updates sent last 24 hours
.parseMode(ParseMode.HTML) // Default parse mode passed to sendXyz methods
.limit(10) // Limit how many updates should be received at maximum per request
.useTestServer(false) // Using test server
.timeout(30) // timeout
.offset(-1) // offset
.allowedUpdates(Updates.ALL) // Allowed updates
.proxy(null) // proxy
.build(); // build our client
import et.telebof.TelegramApiException;
try {
context.sendMessage("Hello, World").exec();
} catch(TelegramApiException apiException){
System.out.println(apiException.description);
}
Finally, we now assume that you have basic understanding of this library in this brief tutorial, however, if you have any question or need support regarding this library, you have the following options
- Ping us on our official Telegram group.
- Ask questions by opening a discussion
And join our official Telegram channel for update news.