我们今天的任务是创建一个"照片"机器人,该机器人将向用户发送照片。这只是一个示例,因此不会从网上获取照片,也不支持群聊功能。仅处理本地图片。但有一个好处: 我们将学会如何创建自定义键盘,如何发送照片以及创建指令。
准备图片
让我们下载5张完全不知名的照片。请注意: 我们将多次向用户发送相同的文件,因此我们应在Telegram服务器的流量和磁盘空间上精打细算。令人惊叹的是,我们只需在服务器上传一次文件,然后就可以通过唯一的文件ID来发送文件(图片、音频文件、文档、语音信息等) 。好了,那么现在让我们在发送给机器人时获取每张图片的ID
一如既往,在intelildea中创建一个新项目,并在src目录下创建两个文件:Main.java和PhotoBot.java。打开第一个文件,然后输入如下内容:
import org.telegram.telegrambots.ApiContextInitializer;
import org.telegram.telegrambots.TelegramBotsApi;
import org.telegram.telegrambots.exceptions.TelegramApiException;
public class Main {
public static void main(String[] args) {
ApiContextInitializer.init();
TelegramBotsApi botsApi = new TelegramBotsApi();
try {
botsApi.registerBot(new PhotoBot());
} catch (TelegramApiException e) {
e.printStackTrace();
}
System.out.println("PhotoBot successfully started!");
}
}
这段代码将在我们的机器人成功启动时打印"PhotoBot successfully started!"。然后,保存它并打开PhotoBot.java文件。请粘贴之前课程中的以下代码:
import org.telegram.telegrambots.api.methods.send.SendMessage;
import org.telegram.telegrambots.api.objects.Update;
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
import org.telegram.telegrambots.exceptions.TelegramApiException;
public class PhotoBot extends TelegramLongPollingBot {
@Override
public void onUpdateReceived(Update update) {
// We check if the update has a message and the message has text
if (update.hasMessage() && update.getMessage().hasText()) {
// Set variables
String message_text = update.getMessage().getText();
long chat_id = update.getMessage().getChatId();
SendMessage message = new SendMessage() // Create a message object object
.setChatId(chat_id)
.setText(message_text);
try {
sendMessage(message); // Sending our message object to user
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
}
@Override
public String getBotUsername() {
// Return bot username
// If bot username is @MyAmazingBot, it must return 'MyAmazingBot'
return "PhotoBot";
}
@Override
public String getBotToken() {
// Return bot token from BotFather
return "12345:qwertyuiopASDGFHKMK";
}
}
现在让我们更新我们的 onUpdateReceived 方法。我们想要发送我们发送给机器人的图片的file_id。让我们检查消息中是否包含照片对象:
@Override
public void onUpdateReceived(Update update) {
// We check if the update has a message and the message has text
if (update.hasMessage() && update.getMessage().hasText()) {
// Set variables
String message_text = update.getMessage().getText();
long chat_id = update.getMessage().getChatId();
SendMessage message = new SendMessage() // Create a message object object
.setChatId(chat_id)
.setText(message_text);
try {
sendMessage(message); // Sending our message object to user
} catch (TelegramApiException e) {
e.printStackTrace();
}
} else if (update.hasMessage() && update.getMessage().hasPhoto()) {
// Message contains photo
}
}
我们希望我们的机器人发送 file_id 对应的图片, 需要这样做
else if (update.hasMessage() && update.getMessage().hasPhoto()) {
// Message contains photo
// Set variables
long chat_id = update.getMessage().getChatId();
// Array with photo objects with different sizes
// We will get the biggest photo from that array
List<PhotoSize> photos = update.getMessage().getPhoto();
// Know file_id
String f_id = photos.stream()
.sorted(Comparator.comparing(PhotoSize::getFileSize).reversed())
.findFirst()
.orElse(null).getFileId();
// Know photo width
int f_width = photos.stream()
.sorted(Comparator.comparing(PhotoSize::getFileSize).reversed())
.findFirst()
.orElse(null).getWidth();
// Know photo height
int f_height = photos.stream()
.sorted(Comparator.comparing(PhotoSize::getFileSize).reversed())
.findFirst()
.orElse(null).getHeight();
// Set photo caption
String caption = "file_id: " + f_id + "\nwidth: " + Integer.toString(f_width) + "\nheight: " + Integer.toString(f_height);
SendPhoto msg = new SendPhoto()
.setChatId(chat_id)
.setPhoto(f_id)
.setCaption(caption);
try {
sendPhoto(msg); // Call method to send the photo with caption
} catch (TelegramApiException e) {
e.printStackTrace();
}
}

太棒了!现在我们知道照片的文件ID,所以我们可以通过文件ID发送它们。让我们在发送命令 /pic 时让我们的机器人用那张照片回答。
if (update.hasMessage() && update.getMessage().hasText()) {
// Set variables
String message_text = update.getMessage().getText();
long chat_id = update.getMessage().getChatId();
if (message_text.equals("/start")) {
// User send /start
SendMessage message = new SendMessage() // Create a message object object
.setChatId(chat_id)
.setText(message_text);
try {
sendMessage(message); // Sending our message object to user
} catch (TelegramApiException e) {
e.printStackTrace();
}
} else if (message_text.equals("/pic")) {
// User sent /pic
SendPhoto msg = new SendPhoto()
.setChatId(chat_id)
.setPhoto("AgADAgAD6qcxGwnPsUgOp7-MvnQ8GecvSw0ABGvTl7ObQNPNX7UEAAEC")
.setCaption("Photo");
try {
sendPhoto(msg); // Call method to send the photo
} catch (TelegramApiException e) {
e.printStackTrace();
}
} else {
// Unknown command
SendMessage message = new SendMessage() // Create a message object object
.setChatId(chat_id)
.setText("Unknown command");
try {
sendMessage(message); // Sending our message object to user
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
}


现在让我们来看看ReplyKeyboardMarkup。我们将创建这样的自定义键盘

好吧,你已经知道如何让我们的机器人识别命令了。让我们再做一个if 分支处理 /markup 命令。
请记住!当您按下按钮时,它会将按钮上的文本发送给机器人。例如,如果我在按钮上输入"你好"文本,那么当我按下按钮时,它就会为我发送"你好"的文本。
else if (message_text.equals("/markup")) {
SendMessage message = new SendMessage() // Create a message object object
.setChatId(chat_id)
.setText("Here is your keyboard");
// Create ReplyKeyboardMarkup object
ReplyKeyboardMarkup keyboardMarkup = new ReplyKeyboardMarkup();
// Create the keyboard (list of keyboard rows)
List<KeyboardRow> keyboard = new ArrayList<>();
// Create a keyboard row
KeyboardRow row = new KeyboardRow();
// Set each button, you can also use KeyboardButton objects if you need something else than text
row.add("Row 1 Button 1");
row.add("Row 1 Button 2");
row.add("Row 1 Button 3");
// Add the first row to the keyboard
keyboard.add(row);
// Create another keyboard row
row = new KeyboardRow();
// Set each button for the second line
row.add("Row 2 Button 1");
row.add("Row 2 Button 2");
row.add("Row 2 Button 3");
// Add the second row to the keyboard
keyboard.add(row);
// Set the keyboard to the markup
keyboardMarkup.setKeyboard(keyboard);
// Add it to the message
message.setReplyMarkup(keyboardMarkup);
try {
sendMessage(message); // Sending our message object to user
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
太棒了!现在让我们教我们的机器人对这些按钮做出反应:
else if (message_text.equals("Row 1 Button 1")) {
SendPhoto msg = new SendPhoto()
.setChatId(chat_id)
.setPhoto("AgADAgAD6qcxGwnPsUgOp7-MvnQ8GecvSw0ABGvTl7ObQNPNX7UEAAEC")
.setCaption("Photo");
try {
sendPhoto(msg); // Call method to send the photo
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
现在,当用户按下带有"Row 1 Button 1"文本的按钮时,机器人将通过文件ID向用户发送图片:

当用户向机器人发送 /hide 命令时,让我们执行"隐藏键盘"功能。这可以通过ReplyMarkupRemove来实现。
else if (message_text.equals("/hide")) {
SendMessage msg = new SendMessage()
.setChatId(chat_id)
.setText("Keyboard hidden");
ReplyKeyboardRemove keyboardMarkup = new ReplyKeyboardRemove();
msg.setReplyMarkup(keyboardMarkup);
try {
sendMessage(msg); // Call method to send the photo
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
查看完整代码
import org.telegram.telegrambots.ApiContextInitializer;
import org.telegram.telegrambots.TelegramBotsApi;
import org.telegram.telegrambots.exceptions.TelegramApiException;
public class Main {
public static void main(String[] args) {
ApiContextInitializer.init();
TelegramBotsApi botsApi = new TelegramBotsApi();
try {
botsApi.registerBot(new PhotoBot());
} catch (TelegramApiException e) {
e.printStackTrace();
}
System.out.println("PhotoBot successfully started!");
}
}
import org.telegram.telegrambots.api.methods.send.SendMessage;
import org.telegram.telegrambots.api.methods.send.SendPhoto;
import org.telegram.telegrambots.api.objects.PhotoSize;
import org.telegram.telegrambots.api.objects.Update;
import org.telegram.telegrambots.api.objects.replykeyboard.ReplyKeyboardMarkup;
import org.telegram.telegrambots.api.objects.replykeyboard.ReplyKeyboardRemove;
import org.telegram.telegrambots.api.objects.replykeyboard.buttons.KeyboardRow;
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
import org.telegram.telegrambots.exceptions.TelegramApiException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class PhotoBot extends TelegramLongPollingBot {
@Override
public void onUpdateReceived(Update update) {
// We check if the update has a message and the message has text
if (update.hasMessage() && update.getMessage().hasText()) {
// Set variables
String message_text = update.getMessage().getText();
long chat_id = update.getMessage().getChatId();
if (message_text.equals("/start")) {
SendMessage message = new SendMessage() // Create a message object object
.setChatId(chat_id)
.setText(message_text);
try {
sendMessage(message); // Sending our message object to user
} catch (TelegramApiException e) {
e.printStackTrace();
}
} else if (message_text.equals("/pic")) {
SendPhoto msg = new SendPhoto()
.setChatId(chat_id)
.setPhoto("AgADAgAD6qcxGwnPsUgOp7-MvnQ8GecvSw0ABGvTl7ObQNPNX7UEAAEC")
.setCaption("Photo");
try {
sendPhoto(msg); // Call method to send the photo
} catch (TelegramApiException e) {
e.printStackTrace();
}
} else if (message_text.equals("/markup")) {
SendMessage message = new SendMessage() // Create a message object object
.setChatId(chat_id)
.setText("Here is your keyboard");
// Create ReplyKeyboardMarkup object
ReplyKeyboardMarkup keyboardMarkup = new ReplyKeyboardMarkup();
// Create the keyboard (list of keyboard rows)
List<KeyboardRow> keyboard = new ArrayList<>();
// Create a keyboard row
KeyboardRow row = new KeyboardRow();
// Set each button, you can also use KeyboardButton objects if you need something else than text
row.add("Row 1 Button 1");
row.add("Row 1 Button 2");
row.add("Row 1 Button 3");
// Add the first row to the keyboard
keyboard.add(row);
// Create another keyboard row
row = new KeyboardRow();
// Set each button for the second line
row.add("Row 2 Button 1");
row.add("Row 2 Button 2");
row.add("Row 2 Button 3");
// Add the second row to the keyboard
keyboard.add(row);
// Set the keyboard to the markup
keyboardMarkup.setKeyboard(keyboard);
// Add it to the message
message.setReplyMarkup(keyboardMarkup);
try {
sendMessage(message); // Sending our message object to user
} catch (TelegramApiException e) {
e.printStackTrace();
}
} else if (message_text.equals("Row 1 Button 1")) {
SendPhoto msg = new SendPhoto()
.setChatId(chat_id)
.setPhoto("AgADAgAD6qcxGwnPsUgOp7-MvnQ8GecvSw0ABGvTl7ObQNPNX7UEAAEC")
.setCaption("Photo");
try {
sendPhoto(msg); // Call method to send the photo
} catch (TelegramApiException e) {
e.printStackTrace();
}
} else if (message_text.equals("/hide")) {
SendMessage msg = new SendMessage()
.setChatId(chat_id)
.setText("Keyboard hidden");
ReplyKeyboardRemove keyboardMarkup = new ReplyKeyboardRemove();
msg.setReplyMarkup(keyboardMarkup);
try {
sendMessage(msg); // Call method to send the photo
} catch (TelegramApiException e) {
e.printStackTrace();
}
} else {
SendMessage message = new SendMessage() // Create a message object object
.setChatId(chat_id)
.setText("Unknown command");
try {
sendMessage(message); // Sending our message object to user
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
} else if (update.hasMessage() && update.getMessage().hasPhoto()) {
// Message contains photo
// Set variables
long chat_id = update.getMessage().getChatId();
List<PhotoSize> photos = update.getMessage().getPhoto();
String f_id = photos.stream()
.sorted(Comparator.comparing(PhotoSize::getFileSize).reversed())
.findFirst()
.orElse(null).getFileId();
int f_width = photos.stream()
.sorted(Comparator.comparing(PhotoSize::getFileSize).reversed())
.findFirst()
.orElse(null).getWidth();
int f_height = photos.stream()
.sorted(Comparator.comparing(PhotoSize::getFileSize).reversed())
.findFirst()
.orElse(null).getHeight();
String caption = "file_id: " + f_id + "\nwidth: " + Integer.toString(f_width) + "\nheight: " + Integer.toString(f_height);
SendPhoto msg = new SendPhoto()
.setChatId(chat_id)
.setPhoto(f_id)
.setCaption(caption);
try {
sendPhoto(msg); // Call method to send the message
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
}
@Override
public String getBotUsername() {
// Return bot username
// If bot username is @MyAmazingBot, it must return 'MyAmazingBot'
return "PhotoBot";
}
@Override
public String getBotToken() {
// Return bot token from BotFather
return "12345:qwertyuiopASDGFHKMK";
}
}