diff --git a/readme.md b/readme.md index 2a4276a..afe0f00 100644 --- a/readme.md +++ b/readme.md @@ -149,6 +149,7 @@ import com.n1netails.n1netails.telegram.model.InlineKeyboardMarkup; import com.n1netails.n1netails.telegram.model.TelegramMessage; import com.n1netails.n1netails.telegram.service.BotService; +import java.util.Arrays; import java.util.Collections; public class ExampleService { @@ -158,7 +159,7 @@ public class ExampleService { this.telegramClient = new TelegramClientImpl(new BotService()); } - public void telegramNotificationExample(String content) { + public void telegramNotificationExample(String content) throws TelegramClientException { Button button = new Button("Visit N1netails", "https://n1netails.com"); InlineKeyboardMarkup keyboardMarkup = new InlineKeyboardMarkup(Collections.singletonList(Collections.singletonList(button))); TelegramMessage telegramMessage = new TelegramMessage("N1netails Telegram Works!", false, keyboardMarkup); @@ -169,7 +170,7 @@ public class ExampleService { telegramClient.sendMessage(chatId, botToken, telegramMessage); } - public void telegramGifNotificationExample() { + public void telegramGifNotificationExample() throws TelegramClientException { TelegramMessage telegramMessage = new TelegramMessage("Check out this GIF!", "https://media1.giphy.com/media/v1.Y2lkPTc5MGI3NjExaDRhOWtpMnVsM2NiMzJ4aXpoOXpuamZzcHpudG4zbzIzenVlaHN0eSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/xsE65jaPsUKUo/giphy.gif", false); // replace with your telegram chat id String chatId = "your-telegram-chat-id"; @@ -178,7 +179,7 @@ public class ExampleService { telegramClient.sendMessage(chatId, botToken, telegramMessage); } - public void telegramGifNotificationWithCtaButtonsExample() { + public void telegramGifNotificationWithCtaButtonsExample() throws TelegramClientException { Button button = new Button("Visit N1netails", "https://n1netails.com"); InlineKeyboardMarkup keyboardMarkup = new InlineKeyboardMarkup(Collections.singletonList(Collections.singletonList(button))); TelegramMessage telegramMessage = new TelegramMessage("Check out this GIF!", "https://media1.giphy.com/media/v1.Y2lkPTc5MGI3NjExaDRhOWtpMnVsM2NiMzJ4aXpoOXpuamZzcHpudG4zbzIzenVlaHN0eSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/xsE65jaPsUKUo/giphy.gif", false, keyboardMarkup); @@ -188,9 +189,45 @@ public class ExampleService { String botToken = "your-telegram-bot-token"; telegramClient.sendMessage(chatId, botToken, telegramMessage); } + + public void telegramImageNotificationExample() throws TelegramClientException { + TelegramMessage telegramMessage = new TelegramMessage(); + telegramMessage.setText("Check out this photo!"); + telegramMessage.setImages(Collections.singletonList("https://n1netails.com/img/n1netails_icon_transparent.png")); + // replace with your telegram chat id + String chatId = "your-telegram-chat-id"; + // replace with your telegram bot token + String botToken = "your-telegram-bot-token"; + telegramClient.sendMessage(chatId, botToken, telegramMessage); + } + + public void telegramVideoNotificationExample() throws TelegramClientException { + TelegramMessage telegramMessage = new TelegramMessage(); + telegramMessage.setText("Check out this video!"); + telegramMessage.setVideos(Collections.singletonList("https://n1netails.nyc3.cdn.digitaloceanspaces.com/video_2026-02-11_18-16-07.mp4")); + // replace with your telegram chat id + String chatId = "your-telegram-chat-id"; + // replace with your telegram bot token + String botToken = "your-telegram-bot-token"; + telegramClient.sendMessage(chatId, botToken, telegramMessage); + } + + public void telegramMediaGroupNotificationExample() throws TelegramClientException { + TelegramMessage telegramMessage = new TelegramMessage(); + telegramMessage.setText("Check out these photos and videos!"); + telegramMessage.setImages(Arrays.asList("https://n1netails.com/img/n1netails_icon_transparent.png", "https://n1netails.com/img/quickstart/n1netails-letter.jpg")); + telegramMessage.setVideos(Collections.singletonList("https://n1netails.nyc3.cdn.digitaloceanspaces.com/video_2026-02-11_18-16-07.mp4")); + // replace with your telegram chat id + String chatId = "your-telegram-chat-id"; + // replace with your telegram bot token + String botToken = "your-telegram-bot-token"; + telegramClient.sendMessage(chatId, botToken, telegramMessage); + } } ``` +> 📌 **Note:** Media (images, videos, animations) must be provided as public URLs. Telegram does not support `replyMarkup` (CTA buttons) when sending multiple media items (Media Group). + #### Example message output
N1netails telegram message simple @@ -206,6 +243,22 @@ public class ExampleService { N1netails telegram message simple
+#### Example message Image output +
+ N1netails telegram message simple +
+ +#### Example message Video output +
+ N1netails telegram message simple +
+ +#### Example message Media group output +
+ N1netails telegram message simple +
+ + # Develop ## Build Build the project using the following command diff --git a/src/main/java/com/n1netails/n1netails/telegram/model/TelegramMessage.java b/src/main/java/com/n1netails/n1netails/telegram/model/TelegramMessage.java index 2c3eb87..74e908b 100644 --- a/src/main/java/com/n1netails/n1netails/telegram/model/TelegramMessage.java +++ b/src/main/java/com/n1netails/n1netails/telegram/model/TelegramMessage.java @@ -3,6 +3,8 @@ import lombok.Getter; import lombok.Setter; +import java.util.List; + /** * Telegram Message * @author shahid foy @@ -13,6 +15,8 @@ public class TelegramMessage { private String text; private String animation; + private List images; + private List videos; private boolean disableNotification; private InlineKeyboardMarkup replyMarkup; @@ -68,4 +72,34 @@ public TelegramMessage(String text, String animation, boolean disableNotificatio this.disableNotification = disableNotification; this.replyMarkup = replyMarkup; } + + /** + * Telegram Message Constructor + * @param text telegram content + * @param images list of image urls + * @param videos list of video urls + * @param disableNotification disable telegram notification + */ + public TelegramMessage(String text, List images, List videos, boolean disableNotification) { + this.text = text; + this.images = images; + this.videos = videos; + this.disableNotification = disableNotification; + } + + /** + * Telegram Message Constructor + * @param text telegram content + * @param images list of image urls + * @param videos list of video urls + * @param disableNotification disable telegram notification + * @param replyMarkup the reply markup + */ + public TelegramMessage(String text, List images, List videos, boolean disableNotification, InlineKeyboardMarkup replyMarkup) { + this.text = text; + this.images = images; + this.videos = videos; + this.disableNotification = disableNotification; + this.replyMarkup = replyMarkup; + } } diff --git a/src/main/java/com/n1netails/n1netails/telegram/service/BotService.java b/src/main/java/com/n1netails/n1netails/telegram/service/BotService.java index a8072b6..c97c88d 100644 --- a/src/main/java/com/n1netails/n1netails/telegram/service/BotService.java +++ b/src/main/java/com/n1netails/n1netails/telegram/service/BotService.java @@ -2,9 +2,11 @@ import com.n1netails.n1netails.telegram.exception.TelegramClientException; import com.n1netails.n1netails.telegram.model.TelegramMessage; +import org.json.JSONArray; import org.json.JSONObject; import java.io.BufferedReader; +import java.util.List; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; @@ -32,28 +34,72 @@ public BotService() {} */ public void send(String chatId, String botToken, TelegramMessage message) throws TelegramClientException { try { - boolean isAnimation = message.getAnimation() != null && !message.getAnimation().isEmpty(); - String method = isAnimation ? "sendAnimation" : "sendMessage"; - String apiUrl = "https://api.telegram.org/bot" + botToken + "/" + method; - + String method; JSONObject jsonPayload = new JSONObject(); jsonPayload.put("chat_id", chatId); - if (isAnimation) { + List images = message.getImages(); + List videos = message.getVideos(); + int imageCount = (images != null) ? images.size() : 0; + int videoCount = (videos != null) ? videos.size() : 0; + int totalMedia = imageCount + videoCount; + + if (totalMedia > 1) { + method = "sendMediaGroup"; + JSONArray mediaArray = new JSONArray(); + if (images != null) { + for (int i = 0; i < images.size(); i++) { + JSONObject media = new JSONObject(); + media.put("type", "photo"); + media.put("media", images.get(i)); + if (i == 0 && message.getText() != null) { + media.put("caption", message.getText()); + } + mediaArray.put(media); + } + } + if (videos != null) { + for (int i = 0; i < videos.size(); i++) { + JSONObject media = new JSONObject(); + media.put("type", "video"); + media.put("media", videos.get(i)); + if (imageCount == 0 && i == 0 && message.getText() != null) { + media.put("caption", message.getText()); + } + mediaArray.put(media); + } + } + jsonPayload.put("media", mediaArray); + } else if (imageCount == 1) { + method = "sendPhoto"; + jsonPayload.put("photo", images.get(0)); + if (message.getText() != null) { + jsonPayload.put("caption", message.getText()); + } + } else if (videoCount == 1) { + method = "sendVideo"; + jsonPayload.put("video", videos.get(0)); + if (message.getText() != null) { + jsonPayload.put("caption", message.getText()); + } + } else if (message.getAnimation() != null && !message.getAnimation().isEmpty()) { + method = "sendAnimation"; jsonPayload.put("animation", message.getAnimation()); if (message.getText() != null) { jsonPayload.put("caption", message.getText()); } } else { + method = "sendMessage"; jsonPayload.put("text", message.getText()); } jsonPayload.put("disable_notification", message.isDisableNotification()); - if (message.getReplyMarkup() != null) { + if (message.getReplyMarkup() != null && !method.equals("sendMediaGroup")) { jsonPayload.put("reply_markup", new JSONObject(message.getReplyMarkup())); } + String apiUrl = "https://api.telegram.org/bot" + botToken + "/" + method; HttpURLConnection conn = openConnection(apiUrl); conn.setRequestMethod("POST"); conn.setDoOutput(true); diff --git a/src/test/java/com/n1netails/n1netails/telegram/service/BotServiceTest.java b/src/test/java/com/n1netails/n1netails/telegram/service/BotServiceTest.java index 9368ed9..b047ebd 100644 --- a/src/test/java/com/n1netails/n1netails/telegram/service/BotServiceTest.java +++ b/src/test/java/com/n1netails/n1netails/telegram/service/BotServiceTest.java @@ -8,6 +8,7 @@ import org.junit.jupiter.api.Test; import java.io.ByteArrayOutputStream; +import java.util.Arrays; import java.util.Collections; import java.net.HttpURLConnection; @@ -76,4 +77,58 @@ void testSendAnimationWithKeyboard() throws Exception { JSONObject replyMarkup = payload.getJSONObject("reply_markup"); assertEquals("Click me", replyMarkup.getJSONArray("inline_keyboard").getJSONArray(0).getJSONObject(0).getString("text")); } + + @Test + void testSendSinglePhoto() throws Exception { + TelegramMessage message = new TelegramMessage(); + message.setText("My Photo"); + message.setImages(Collections.singletonList("http://example.com/photo.jpg")); + botService.send("chat123", "token123", message); + + assertEquals("https://api.telegram.org/bottoken123/sendPhoto", lastApiUrl); + JSONObject payload = new JSONObject(outputStream.toString()); + assertEquals("chat123", payload.getString("chat_id")); + assertEquals("http://example.com/photo.jpg", payload.getString("photo")); + assertEquals("My Photo", payload.getString("caption")); + } + + @Test + void testSendSingleVideo() throws Exception { + TelegramMessage message = new TelegramMessage(); + message.setText("My Video"); + message.setVideos(Collections.singletonList("http://example.com/video.mp4")); + botService.send("chat123", "token123", message); + + assertEquals("https://api.telegram.org/bottoken123/sendVideo", lastApiUrl); + JSONObject payload = new JSONObject(outputStream.toString()); + assertEquals("chat123", payload.getString("chat_id")); + assertEquals("http://example.com/video.mp4", payload.getString("video")); + assertEquals("My Video", payload.getString("caption")); + } + + @Test + void testSendMediaGroup() throws Exception { + TelegramMessage message = new TelegramMessage(); + message.setText("Our Trip"); + message.setImages(Arrays.asList("http://example.com/photo1.jpg", "http://example.com/photo2.jpg")); + message.setVideos(Collections.singletonList("http://example.com/video1.mp4")); + botService.send("chat123", "token123", message); + + assertEquals("https://api.telegram.org/bottoken123/sendMediaGroup", lastApiUrl); + JSONObject payload = new JSONObject(outputStream.toString()); + assertEquals("chat123", payload.getString("chat_id")); + + org.json.JSONArray media = payload.getJSONArray("media"); + assertEquals(3, media.length()); + + assertEquals("photo", media.getJSONObject(0).getString("type")); + assertEquals("http://example.com/photo1.jpg", media.getJSONObject(0).getString("media")); + assertEquals("Our Trip", media.getJSONObject(0).getString("caption")); + + assertEquals("photo", media.getJSONObject(1).getString("type")); + assertEquals("http://example.com/photo2.jpg", media.getJSONObject(1).getString("media")); + + assertEquals("video", media.getJSONObject(2).getString("type")); + assertEquals("http://example.com/video1.mp4", media.getJSONObject(2).getString("media")); + } } diff --git a/telegram-group-media-message.png b/telegram-group-media-message.png new file mode 100644 index 0000000..73b0adf Binary files /dev/null and b/telegram-group-media-message.png differ diff --git a/telegram-image-message.png b/telegram-image-message.png new file mode 100644 index 0000000..4cc04d6 Binary files /dev/null and b/telegram-image-message.png differ diff --git a/telegram-video-message.png b/telegram-video-message.png new file mode 100644 index 0000000..26dbaec Binary files /dev/null and b/telegram-video-message.png differ