Project Icon

java-telegram-bot-api

Java库实现Telegram Bot API完整功能

java-telegram-bot-api是一个功能完整的Java库,用于开发Telegram机器人。该库支持Bot API 7.8的全部功能,包括Telegram Passport、支付和游戏平台。它提供了创建机器人、处理更新、发送消息等简单API,支持同步和异步请求,并附带详细文档和示例。

Java Telegram 机器人 API

Maven Central codecov

用于与 Telegram Bot API 交互的 Java 库

下载

Gradle:

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

Maven:

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

发布页面上包含所有依赖项的 JAR 包

使用方法

// 使用从 @BotFather 获得的令牌创建您的机器人
TelegramBot bot = new TelegramBot("BOT_TOKEN");

// 注册更新监听器
bot.setUpdatesListener(updates -> {
    // ... 处理更新
    // 返回最后处理的更新 ID 或确认所有更新
    return UpdatesListener.CONFIRMED_UPDATES_ALL;
// 创建异常处理器
}, e -> {
    if (e.response() != null) {
        // 从 Telegram 收到错误响应
        e.response().errorCode();
        e.response().description();
    } else {
        // 可能是网络错误
        e.printStackTrace();
    }
});

// 发送消息
long chatId = update.message().chat().id();
SendResponse response = bot.execute(new SendMessage(chatId, "你好!"));

文档

创建您的机器人

TelegramBot bot = new TelegramBot("BOT_TOKEN");

网络操作基于 OkHttp 库。
您可以使用自定义 OkHttpClient 构建机器人,以设置特定的超时时间或拦截器。

TelegramBot bot = new TelegramBot.Builder("BOT_TOKEN").okHttpClient(client).build();

发送请求

同步

BaseResponse response = bot.execute(request);

异步

bot.execute(request, new Callback() {
    @Override
    public void onResponse(BaseRequest request, BaseResponse response) {
    
    }
    @Override
    public void onFailure(BaseRequest request, IOException e) {
    
    }
});

响应更新的请求

String response = request.toWebhookResponse();

获取更新

您可以使用 getUpdates 请求,解析传入的 Webhook 请求,或设置监听器来接收更新。
Update 对象只是复制 Telegram 的响应。

class Update {
    Integer updateId();
    Message message();
    Message editedMessage();
    InlineQuery inlineQuery();
    ChosenInlineResult chosenInlineResult();
    CallbackQuery callbackQuery();
}

获取更新

构建请求

GetUpdates getUpdates = new GetUpdates().limit(100).offset(0).timeout(0);

getUpdates 方法返回最早的 100 个未确认更新。要确认更新,在调用 getUpdates 时使用 offset 参数,如下所示: offset = 最后处理的更新的 updateId + 1
所有 updateId 小于 offset 的更新将在服务器上被标记为已确认,不再返回。

执行

// 同步
GetUpdatesResponse updatesResponse = bot.execute(getUpdates);
List<Update> updates = updatesResponse.updates();
...
Message message = update.message()


// 异步
bot.execute(getUpdates, new Callback<GetUpdates, GetUpdatesResponse>() {
    @Override
    public void onResponse(GetUpdates request, GetUpdatesResponse response) {
        List<Update> updates = response.updates();
    }
    
    @Override
    public void onFailure(GetUpdates request, IOException e) {
    
    }
});

Webhook

构建请求

SetWebhook request = new SetWebhook()
       .url("url")
       .certificate(new byte[]{}) // byte[]
       .certificate(new File("path")); // 或文件 

执行

// 同步
BaseResponse response = bot.execute(request);
boolean ok = response.isOk();

// 异步
bot.execute(request, new Callback<SetWebhook, BaseResponse>() {
    @Override
    public void onResponse(SetWebhook request, BaseResponse response) {
    
    }
    @Override
    public void onFailure(SetWebhook request, IOException e) {
        
    }
});

使用 Webhook 时,您可以将请求解析为 Update

Update update = BotUtils.parseUpdate(stringRequest); // 从字符串
Update update = BotUtils.parseUpdate(reader); // 或从 java.io.Reader

Message message = update.message();

更新监听器

您可以设置监听器来接收传入的更新,就像使用 Webhook 一样。
这将触发循环执行 getUpdates 请求。

bot.setUpdatesListener(new UpdatesListener() {
    @Override
    public int process(List<Update> updates) {

        // 处理更新

        return UpdatesListener.CONFIRMED_UPDATES_ALL;
    }
// 创建异常处理器
}, new ExceptionHandler() {
    @override
    public void onException(TelegramException e)
    {
        if (e.response() != null) {
            // 从 Telegram 收到错误响应
            e.response().errorCode();
            e.response().description();
        } else {
            // 可能是网络错误
            e.printStackTrace();
        }
    }
});

监听器应返回最后一个已处理(已确认)更新的 id。 要确认所有更新,请返回 UpdatesListener.CONFIRMED_UPDATES_ALL,这在大多数情况下应该足够。 要不确认任何更新,请返回 UpdatesListener.CONFIRMED_UPDATES_NONE,这些更新将被重新传递。 要将特定更新设置为最后确认的更新,只需返回所需的 updateId。

要停止接收更新

bot.removeGetUpdatesListener();

可用类型

所有类型的名称与原始名称相同。 类型的字段是采用小驼峰命名法的方法。

响应中使用的类型(Update、Message、User、Document...)位于 com.pengrad.telegrambot.model 包中。

请求中使用的类型(Keyboard、InlineQueryResult、ParseMode、InputMessageContent...)位于 com.pengrad.telegrambot.model.request 包中。 创建请求类型时,必需的参数应在构造函数中传递,可选参数可以通过链式调用添加。

键盘

ForceReply, ReplyKeyboardRemove

Keyboard forceReply = new ForceReply(isSelective); // 或直接使用 new ForceReply();
Keyboard replyKeyboardRemove = new ReplyKeyboardRemove(); // new ReplyKeyboardRemove(isSelective)

ReplyKeyboardMarkup

Keyboard replyKeyboardMarkup = new ReplyKeyboardMarkup(
                new String[]{"第一行按钮1", "第一行按钮2"},
                new String[]{"第二行按钮1", "第二行按钮2"})
                .oneTimeKeyboard(true)   // 可选
                .resizeKeyboard(true)    // 可选
                .selective(true);        // 可选

KeyboardButton

Keyboard keyboard = new ReplyKeyboardMarkup(
        new KeyboardButton[]{
                new KeyboardButton("文本"),
                new KeyboardButton("联系人").requestContact(true),
                new KeyboardButton("位置").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("切换!").switchInlineQuery("switch_inline_query")
        });

聊天动作

ChatAction action = ChatAction.typing;
ChatAction action = ChatAction.upload_photo;
ChatAction action = ChatAction.find_location;

可用方法

所有请求方法的名称与原始名称相同。 必需的参数应在构造函数中传递。 可选参数可以通过链式调用添加。

发送消息

所有发送请求(SendMessage、SendPhoto、SendLocation...)都返回包含 MessageSendResponse 对象。

SendMessage request = new SendMessage(chatId, "文本")
        .parseMode(ParseMode.HTML)
        .disableWebPagePreview(true)
        .disableNotification(true)
        .replyToMessageId(1)
        .replyMarkup(new ForceReply());

// 同步
SendResponse sendResponse = bot.execute(request);
boolean ok = sendResponse.isOk();
Message message = sendResponse.message();

// 异步
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();  // 相对路径
file.fileSize();

要获取下载链接,格式为 https://api.telegram.org/file/<BOT_TOKEN>/<FILE_PATH>

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

其他请求

如果这里没有提到,所有请求都返回 BaseResponse

class BaseResponse {
  boolean isOk();
  int errorCode();
  String description();
}

GetMe 请求返回 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()
}

StopPoll

class PollResponse {
  Poll poll()
}

更新消息

普通消息

EditMessageText editMessageText = new EditMessageText(chatId, messageId, "新测试")
        .parseMode(ParseMode.HTML)
        .disableWebPagePreview(true)
        .replyMarkup(new ReplyKeyboardRemove());
        
BaseResponse response = bot.execute(editMessageText);

内联消息

EditMessageText editInlineMessageText = new EditMessageText(inlineMessageId, "新文本");
BaseResponse response = bot.execute(editInlineMessageText);

删除消息

DeleteMessage deleteMessage = new DeleteMessage(chatId, messageId);
BaseResponse response = bot.execute(deleteMessage);

贴纸

发送贴纸

// File 或 byte[] 或现有贴纸的 fileId 字符串或 URL 字符串
SendSticker sendSticker = new SendSticker(chatId, imageFile);
SendResponse response = bot.execute(sendSticker);

获取贴纸集

GetStickerSet getStickerSet = new GetStickerSet(stickerSet);
GetStickerSetResponse response = bot.execute(getStickerSet);
StickerSet stickerSet = response.stickerSet();

上传贴纸文件

// File 或 byte[] 或 URL 字符串
UploadStickerFile uploadStickerFile = new UploadStickerFile(chatId, stickerFile);
GetFileResponse response = bot.execute(uploadStickerFile);

内联模式

获取更新

GetUpdatesResponse updatesResponse = bot.execute(new GetUpdates());
List<Update> updates = updatesResponse.updates();
...
InlineQuery inlineQuery = update.inlineQuery();
ChosenInlineResult chosenInlineResult = update.chosenInlineResult();
CallbackQuery callbackQuery = update.callbackQuery();

如果使用 webhook,您可以将请求解析为 InlineQuery

Update update = BotUtils.parseUpdate(stringRequest); // 从 String
Update update = BotUtils.parseUpdate(reader); // 从 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));

// 或完整版
bot.execute(
        new AnswerInlineQuery(inlineQuery.id(), new InlineQueryResult[]{r1, r2, r3, r4, r5})
                .cacheTime(cacheTime)
                .isPersonal(isPersonal)
                .nextOffset("offset")
                .switchPmParameter("pmParam")
                .switchPmText("pmText")
);

支付

发送账单

SendInvoice sendInvoice = new SendInvoice(chatId, "标题", "描述", "my_payload",
        "providerToken", "my_start_param", "USD", new LabeledPrice("标签", 200))
        .needPhoneNumber(true)
        .needShippingAddress(true)
        .isFlexible(true)
        .replyMarkup(new InlineKeyboardMarkup(new InlineKeyboardButton[]{
                new InlineKeyboardButton("直接支付").pay(),
                new InlineKeyboardButton("谷歌一下").url("www.google.com")
        }));
SendResponse response = bot.execute(sendInvoice);

回答配送查询

LabeledPrice[] prices = new LabeledPrice[]{
        new LabeledPrice("配送", 100),
        new LabeledPrice("小费", 50)
};
AnswerShippingQuery answerShippingQuery = new AnswerShippingQuery(shippingQueryId,
        new ShippingOption("1", "VNPT", prices),
        new ShippingOption("2", "免费", new LabeledPrice("免费配送", 0))
);
BaseResponse response = bot.execute(answerShippingQuery);

// 回答错误
AnswerShippingQuery answerShippingError = new AnswerShippingQuery(id, "无法配送到这里!");
BaseResponse response = bot.execute(answerShippingError);

回答预结账查询

AnswerPreCheckoutQuery answerCheckout = new AnswerPreCheckoutQuery(preCheckoutQueryId);
BaseResponse response = bot.execute(answerPreCheckoutQuery);

// 回答错误
AnswerPreCheckoutQuery answerCheckout = new AnswerPreCheckoutQuery(id, "抱歉,商品不可用");
BaseResponse response = bot.execute(answerPreCheckoutQuery);

Telegram Passport

当用户点击"授权"按钮确认您的请求时,Bot API会向机器人发送一个包含加密的Telegram Passport数据的更新,该更新包含passport_data字段。Telegram Passport 手册

接收信息

您可以从更新中获取加密的Passport数据(通过UpdatesListener或Webhook)

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

PassportData包含一组EncryptedPassportElementEncryptedCredentials。 您需要使用私钥解密Credentials(公钥已上传到@BotFather

String privateKey = "...";
EncryptedCredentials encryptedCredentials = passportData.credentials();
Credentials credentials = encryptedCredentials.decrypt(privateKey);

这些Credentials可用于解密EncryptedPassportElement中的加密数据。

EncryptedPassportElement[] encryptedPassportElements = passportData.data();
for (EncryptedPassportElement element : encryptedPassportElements) {
    DecryptedData decryptedData = element.decryptData(credentials);
    // DecryptedData可以通过检查instanceOf转换为特定类型 
    if (decryptedData instanceof PersonalDetails) {
        PersonalDetails personalDetails = (PersonalDetails) decryptedData;
    }
    // 或者通过检查护照元素的类型
    if (element.type() == EncryptedPassportElement.Type.address) {
        ResidentialAddress address = (ResidentialAddress) decryptedData;
    }
}

EncryptedPassportElement还包含一组PassportFile(上传到Telegram Passport的文件)。 您需要逐个下载并解密内容。 该库支持下载和解密,返回解密后的byte[]

EncryptedPassportElement element = ...

// 合并所有文件 
List<PassportFile> files = new ArrayList<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()));
}

// 解密
for (PassportFile file : files) {
    if (file == null) continue;
    byte[] data = element.decryptFile(file, credentials, bot); // GetFile请求并解密内容
    // 如果需要,保存到文件
    new FileOutputStream("files/" + element.type()).write(data);
}

设置Passport数据错误

SetPassportDataErrors setPassportDataErrors = new SetPassportDataErrors(chatId,
        new PassportElementErrorDataField("personal_details", "first_name", "dataHash",
                "请输入有效的名字"),
        new PassportElementErrorSelfie("driver_license", "fileHash",
                "照片上看不清您的脸")
);
bot.execute(setPassportDataErrors);

游戏

发送游戏

SendResponse response = bot.execute(new SendGame(chatId, "my_super_game"));

设置游戏分数

BaseResponse response = bot.execute(new SetGameScore(userId, score, chatId, messageId));

获取游戏高分

GetGameHighScoresResponse response = bot.execute(new GetGameHighScores(userId, chatId, messageId));
GameHighScore[] scores = response.result();
项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号