Refreshed MessageSender and added a silent sender

This commit is contained in:
Abbas Abou Daya 2017-10-28 22:15:53 -04:00
parent babb9d8be5
commit adddadfba5
7 changed files with 273 additions and 684 deletions

View File

@ -3,8 +3,9 @@ package org.telegram.abilitybots.api.bot;
import org.apache.commons.io.IOUtils;
import org.telegram.abilitybots.api.db.DBContext;
import org.telegram.abilitybots.api.objects.*;
import org.telegram.abilitybots.api.sender.DefaultMessageSender;
import org.telegram.abilitybots.api.sender.DefaultSender;
import org.telegram.abilitybots.api.sender.MessageSender;
import org.telegram.abilitybots.api.sender.SilentSender;
import org.telegram.abilitybots.api.util.AbilityUtils;
import org.telegram.abilitybots.api.util.Pair;
import org.telegram.abilitybots.api.util.Trio;
@ -110,6 +111,7 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
// DB and sender
protected final DBContext db;
protected MessageSender sender;
protected SilentSender silent;
// Bot token and username
private final String botToken;
@ -121,13 +123,16 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
// Reply registry
private List<Reply> replies;
public abstract int creatorId();
protected AbilityBot(String botToken, String botUsername, DBContext db, DefaultBotOptions botOptions) {
super(botOptions);
this.botToken = botToken;
this.botUsername = botUsername;
this.db = db;
this.sender = new DefaultMessageSender(this);
this.sender = new DefaultSender(this);
silent = new SilentSender(sender);
registerAbilities();
}
@ -144,8 +149,6 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
this(botToken, botUsername, onlineInstance(botUsername));
}
public abstract int creatorId();
/**
* @return the map of ID -> EndUser
*/
@ -268,7 +271,7 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
try {
return getUser(username).id();
} catch (IllegalStateException ex) {
sender.send(format("Sorry, I could not find the user [%s].", username), chatId);
silent.send(format("Sorry, I could not find the user [%s].", username), chatId);
throw propagate(ex);
}
}
@ -307,7 +310,7 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
.reduce((a, b) -> format("%s%n%s", a, b))
.orElse("No public commands found.");
sender.send(commands, ctx.chatId());
silent.send(commands, ctx.chatId());
})
.build();
}
@ -360,7 +363,7 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
.locality(USER)
.privacy(CREATOR)
.input(0)
.action(ctx -> sender.forceReply(RECOVERY_MESSAGE, ctx.chatId()))
.action(ctx -> silent.forceReply(RECOVERY_MESSAGE, ctx.chatId()))
.reply(update -> {
Long chatId = update.getMessage().getChatId();
String fileId = update.getMessage().getDocument().getFileId();
@ -368,13 +371,13 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
try (FileReader reader = new FileReader(downloadFileWithId(fileId))) {
String backupData = IOUtils.toString(reader);
if (db.recover(backupData)) {
sender.send(RECOVER_SUCCESS, chatId);
silent.send(RECOVER_SUCCESS, chatId);
} else {
sender.send("Oops, something went wrong during recovery.", chatId);
silent.send("Oops, something went wrong during recovery.", chatId);
}
} catch (Exception e) {
BotLogger.error("Could not recover DB from backup", TAG, e);
sender.send("I have failed to recover.", chatId);
silent.send("I have failed to recover.", chatId);
}
}, MESSAGE, DOCUMENT, REPLY, isReplyTo(RECOVERY_MESSAGE))
.build();
@ -410,10 +413,10 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
Set<Integer> blacklist = blacklist();
if (blacklist.contains(userId))
sender.sendMd(format("%s is already *banned*.", bannedUser), ctx.chatId());
silent.sendMd(format("%s is already *banned*.", bannedUser), ctx.chatId());
else {
blacklist.add(userId);
sender.sendMd(format("%s is now *banned*.", bannedUser), ctx.chatId());
silent.sendMd(format("%s is now *banned*.", bannedUser), ctx.chatId());
}
})
.post(commitTo(db))
@ -438,9 +441,9 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
Set<Integer> blacklist = blacklist();
if (!blacklist.remove(userId))
sender.sendMd(format("@%s is *not* on the *blacklist*.", username), ctx.chatId());
silent.sendMd(format("@%s is *not* on the *blacklist*.", username), ctx.chatId());
else {
sender.sendMd(format("@%s, your ban has been *lifted*.", username), ctx.chatId());
silent.sendMd(format("@%s, your ban has been *lifted*.", username), ctx.chatId());
}
})
.post(commitTo(db))
@ -462,10 +465,10 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
Set<Integer> admins = admins();
if (admins.contains(userId))
sender.sendMd(format("@%s is already an *admin*.", username), ctx.chatId());
silent.sendMd(format("@%s is already an *admin*.", username), ctx.chatId());
else {
admins.add(userId);
sender.sendMd(format("@%s has been *promoted*.", username), ctx.chatId());
silent.sendMd(format("@%s has been *promoted*.", username), ctx.chatId());
}
}).post(commitTo(db))
.build();
@ -486,9 +489,9 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
Set<Integer> admins = admins();
if (admins.remove(userId)) {
sender.sendMd(format("@%s has been *demoted*.", username), ctx.chatId());
silent.sendMd(format("@%s has been *demoted*.", username), ctx.chatId());
} else {
sender.sendMd(format("@%s is *not* an *admin*.", username), ctx.chatId());
silent.sendMd(format("@%s is *not* an *admin*.", username), ctx.chatId());
}
})
.post(commitTo(db))
@ -513,10 +516,10 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
long chatId = ctx.chatId();
if (admins.contains(id))
sender.send("You're already my master.", chatId);
silent.send("You're already my master.", chatId);
else {
admins.add(id);
sender.send("You're now my master.", chatId);
silent.send("You're now my master.", chatId);
}
} else {
// This is not a joke
@ -614,7 +617,7 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
boolean isOk = abilityTokens == 0 || (tokens.length > 0 && tokens.length == abilityTokens);
if (!isOk)
sender.send(String.format("Sorry, this feature requires %d additional %s.", abilityTokens, abilityTokens == 1 ? "input" : "inputs"), getChatId(trio.a()));
silent.send(String.format("Sorry, this feature requires %d additional %s.", abilityTokens, abilityTokens == 1 ? "input" : "inputs"), getChatId(trio.a()));
return isOk;
}
@ -626,7 +629,7 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
boolean isOk = abilityLocality == ALL || locality == abilityLocality;
if (!isOk)
sender.send(String.format("Sorry, %s-only feature.", abilityLocality.toString().toLowerCase()), getChatId(trio.a()));
silent.send(String.format("Sorry, %s-only feature.", abilityLocality.toString().toLowerCase()), getChatId(trio.a()));
return isOk;
}
@ -641,7 +644,7 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
boolean isOk = privacy.compareTo(trio.b().privacy()) >= 0;
if (!isOk)
sender.send(String.format("Sorry, %s-only feature.", trio.b().privacy().toString().toLowerCase()), getChatId(trio.a()));
silent.send(String.format("Sorry, %s-only feature.", trio.b().privacy().toString().toLowerCase()), getChatId(trio.a()));
return isOk;
}
@ -730,7 +733,7 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
boolean checkMessageFlags(Trio<Update, Ability, String[]> trio) {
Ability ability = trio.b();
Update update = trio.a();
// The following variable is required to avoid bug #JDK-8044546
BiFunction<Boolean, Predicate<Update>, Boolean> flagAnd = (flag, nextFlag) -> flag && nextFlag.test(update);
return ability.flags().stream()
@ -738,6 +741,6 @@ public abstract class AbilityBot extends TelegramLongPollingBot {
}
private File downloadFileWithId(String fileId) throws TelegramApiException {
return sender.downloadFile(sender.getFile(new GetFile().setFileId(fileId)));
return sender.downloadFile(sender.execute(new GetFile().setFileId(fileId)));
}
}

View File

@ -1,493 +0,0 @@
package org.telegram.abilitybots.api.sender;
import org.telegram.telegrambots.api.methods.*;
import org.telegram.telegrambots.api.methods.games.GetGameHighScores;
import org.telegram.telegrambots.api.methods.games.SetGameScore;
import org.telegram.telegrambots.api.methods.groupadministration.*;
import org.telegram.telegrambots.api.methods.pinnedmessages.PinChatMessage;
import org.telegram.telegrambots.api.methods.pinnedmessages.UnpinChatMessage;
import org.telegram.telegrambots.api.methods.send.*;
import org.telegram.telegrambots.api.methods.updates.DeleteWebhook;
import org.telegram.telegrambots.api.methods.updatingmessages.DeleteMessage;
import org.telegram.telegrambots.api.methods.updatingmessages.EditMessageCaption;
import org.telegram.telegrambots.api.methods.updatingmessages.EditMessageReplyMarkup;
import org.telegram.telegrambots.api.methods.updatingmessages.EditMessageText;
import org.telegram.telegrambots.api.objects.*;
import org.telegram.telegrambots.api.objects.games.GameHighScore;
import org.telegram.telegrambots.api.objects.replykeyboard.ForceReplyKeyboard;
import org.telegram.telegrambots.bots.DefaultAbsSender;
import org.telegram.telegrambots.exceptions.TelegramApiException;
import org.telegram.telegrambots.logging.BotLogger;
import org.telegram.telegrambots.updateshandlers.DownloadFileCallback;
import org.telegram.telegrambots.updateshandlers.SentCallback;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import static java.util.Optional.empty;
import static java.util.Optional.ofNullable;
/**
* The default implementation of the {@link MessageSender}. This serves as a proxy to the {@link DefaultAbsSender} methods.
* <p>Most of the methods below will be directly calling the bot's similar functions. However, there are some methods introduced to ease sending messages such as:</p>
* <ol>
* <li>{@link DefaultMessageSender#sendMd(String, long)} - with markdown</li>
* <li>{@link DefaultMessageSender#send(String, long)} - without markdown</li>
* </ol>
*
* @author Abbas Abou Daya
*/
public class DefaultMessageSender implements MessageSender {
private static final String TAG = MessageSender.class.getName();
private DefaultAbsSender bot;
public DefaultMessageSender(DefaultAbsSender bot) {
this.bot = bot;
}
@Override
public Optional<Message> send(String message, long id) {
return doSendMessage(message, id, false);
}
@Override
public Optional<Message> sendMd(String message, long id) {
return doSendMessage(message, id, true);
}
@Override
public Optional<Message> forceReply(String message, long id) {
SendMessage msg = new SendMessage();
msg.setText(message);
msg.setChatId(id);
msg.setReplyMarkup(new ForceReplyKeyboard());
return optionalSendMessage(msg);
}
@Override
public Boolean answerInlineQuery(AnswerInlineQuery answerInlineQuery) throws TelegramApiException {
return bot.execute(answerInlineQuery);
}
@Override
public Boolean sendChatAction(SendChatAction sendChatAction) throws TelegramApiException {
return bot.execute(sendChatAction);
}
@Override
public Message forwardMessage(ForwardMessage forwardMessage) throws TelegramApiException {
return bot.execute(forwardMessage);
}
@Override
public Message sendLocation(SendLocation sendLocation) throws TelegramApiException {
return bot.execute(sendLocation);
}
@Override
public Message sendVenue(SendVenue sendVenue) throws TelegramApiException {
return bot.execute(sendVenue);
}
@Override
public Message sendContact(SendContact sendContact) throws TelegramApiException {
return bot.execute(sendContact);
}
@Override
public Boolean kickMember(KickChatMember kickChatMember) throws TelegramApiException {
return bot.execute(kickChatMember);
}
@Override
public Boolean unbanMember(UnbanChatMember unbanChatMember) throws TelegramApiException {
return bot.execute(unbanChatMember);
}
@Override
public Boolean leaveChat(LeaveChat leaveChat) throws TelegramApiException {
return bot.execute(leaveChat);
}
@Override
public Chat getChat(GetChat getChat) throws TelegramApiException {
return bot.execute(getChat);
}
@Override
public List<ChatMember> getChatAdministrators(GetChatAdministrators getChatAdministrators) throws TelegramApiException {
return bot.execute(getChatAdministrators);
}
@Override
public ChatMember getChatMember(GetChatMember getChatMember) throws TelegramApiException {
return bot.execute(getChatMember);
}
@Override
public Integer getChatMemberCount(GetChatMemberCount getChatMemberCount) throws TelegramApiException {
return bot.execute(getChatMemberCount);
}
@Override
public Boolean setChatPhoto(SetChatPhoto setChatPhoto) throws TelegramApiException {
return bot.setChatPhoto(setChatPhoto);
}
@Override
public Boolean deleteChatPhoto(DeleteChatPhoto deleteChatPhoto) throws TelegramApiException {
return bot.execute(deleteChatPhoto);
}
@Override
public void deleteChatPhoto(DeleteChatPhoto deleteChatPhoto, SentCallback<Boolean> sentCallback) throws TelegramApiException {
bot.executeAsync(deleteChatPhoto, sentCallback);
}
@Override
public Boolean pinChatMessage(PinChatMessage pinChatMessage) throws TelegramApiException {
return bot.execute(pinChatMessage);
}
@Override
public void pinChatMessage(PinChatMessage pinChatMessage, SentCallback<Boolean> sentCallback) throws TelegramApiException {
bot.executeAsync(pinChatMessage, sentCallback);
}
@Override
public Boolean unpinChatMessage(UnpinChatMessage unpinChatMessage) throws TelegramApiException {
return bot.execute(unpinChatMessage);
}
@Override
public void unpinChatMessage(UnpinChatMessage unpinChatMessage, SentCallback<Boolean> sentCallback) throws TelegramApiException {
bot.executeAsync(unpinChatMessage, sentCallback);
}
@Override
public Boolean promoteChatMember(PromoteChatMember promoteChatMember) throws TelegramApiException {
return bot.execute(promoteChatMember);
}
@Override
public void promoteChatMember(PromoteChatMember promoteChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException {
bot.executeAsync(promoteChatMember, sentCallback);
}
@Override
public Boolean restrictChatMember(RestrictChatMember restrictChatMember) throws TelegramApiException {
return bot.execute(restrictChatMember);
}
@Override
public void restrictChatMember(RestrictChatMember restrictChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException {
bot.executeAsync(restrictChatMember, sentCallback);
}
@Override
public Boolean setChatDescription(SetChatDescription setChatDescription) throws TelegramApiException {
return bot.execute(setChatDescription);
}
@Override
public void setChatDescription(SetChatDescription setChatDescription, SentCallback<Boolean> sentCallback) throws TelegramApiException {
bot.executeAsync(setChatDescription, sentCallback);
}
@Override
public Boolean setChatTite(SetChatTitle setChatTitle) throws TelegramApiException {
return bot.execute(setChatTitle);
}
@Override
public void setChatTite(SetChatTitle setChatTitle, SentCallback<Boolean> sentCallback) throws TelegramApiException {
bot.executeAsync(setChatTitle, sentCallback);
}
@Override
public String exportChatInviteLink(ExportChatInviteLink exportChatInviteLink) throws TelegramApiException {
return bot.execute(exportChatInviteLink);
}
@Override
public void exportChatInviteLinkAsync(ExportChatInviteLink exportChatInviteLink, SentCallback<String> sentCallback) throws TelegramApiException {
bot.executeAsync(exportChatInviteLink, sentCallback);
}
@Override
public Boolean deleteMessage(DeleteMessage deleteMessage) throws TelegramApiException {
return bot.execute(deleteMessage);
}
@Override
public void deleteMessageAsync(DeleteMessage deleteMessage, SentCallback<Boolean> sentCallback) throws TelegramApiException {
bot.executeAsync(deleteMessage, sentCallback);
}
@Override
public Serializable editMessageText(EditMessageText editMessageText) throws TelegramApiException {
return bot.execute(editMessageText);
}
@Override
public Serializable editMessageCaption(EditMessageCaption editMessageCaption) throws TelegramApiException {
return bot.execute(editMessageCaption);
}
@Override
public Serializable editMessageReplyMarkup(EditMessageReplyMarkup editMessageReplyMarkup) throws TelegramApiException {
return bot.execute(editMessageReplyMarkup);
}
@Override
public Boolean answerCallbackQuery(AnswerCallbackQuery answerCallbackQuery) throws TelegramApiException {
return bot.execute(answerCallbackQuery);
}
@Override
public UserProfilePhotos getUserProfilePhotos(GetUserProfilePhotos getUserProfilePhotos) throws TelegramApiException {
return bot.execute(getUserProfilePhotos);
}
@Override
public java.io.File downloadFile(String path) throws TelegramApiException {
return bot.downloadFile(path);
}
@Override
public void downloadFileAsync(String path, DownloadFileCallback<String> callback) throws TelegramApiException {
bot.downloadFileAsync(path, callback);
}
@Override
public java.io.File downloadFile(File file) throws TelegramApiException {
return bot.downloadFile(file);
}
@Override
public void downloadFileAsync(File file, DownloadFileCallback<File> callback) throws TelegramApiException {
bot.downloadFileAsync(file, callback);
}
@Override
public File getFile(GetFile getFile) throws TelegramApiException {
return bot.execute(getFile);
}
@Override
public User getMe() throws TelegramApiException {
return bot.getMe();
}
@Override
public WebhookInfo getWebhookInfo() throws TelegramApiException {
return bot.getWebhookInfo();
}
@Override
public Serializable setGameScore(SetGameScore setGameScore) throws TelegramApiException {
return bot.execute(setGameScore);
}
@Override
public Serializable getGameHighScores(GetGameHighScores getGameHighScores) throws TelegramApiException {
return bot.execute(getGameHighScores);
}
@Override
public Message sendGame(SendGame sendGame) throws TelegramApiException {
return bot.execute(sendGame);
}
@Override
public Boolean deleteWebhook(DeleteWebhook deleteWebhook) throws TelegramApiException {
return bot.execute(deleteWebhook);
}
@Override
public Message sendMessage(SendMessage sendMessage) throws TelegramApiException {
return bot.execute(sendMessage);
}
@Override
public void sendMessageAsync(SendMessage sendMessage, SentCallback<Message> sentCallback) throws TelegramApiException {
bot.executeAsync(sendMessage, sentCallback);
}
@Override
public void answerInlineQueryAsync(AnswerInlineQuery answerInlineQuery, SentCallback<Boolean> sentCallback) throws TelegramApiException {
bot.executeAsync(answerInlineQuery, sentCallback);
}
@Override
public void sendChatActionAsync(SendChatAction sendChatAction, SentCallback<Boolean> sentCallback) throws TelegramApiException {
bot.executeAsync(sendChatAction, sentCallback);
}
@Override
public void forwardMessageAsync(ForwardMessage forwardMessage, SentCallback<Message> sentCallback) throws TelegramApiException {
bot.executeAsync(forwardMessage, sentCallback);
}
@Override
public void sendLocationAsync(SendLocation sendLocation, SentCallback<Message> sentCallback) throws TelegramApiException {
bot.executeAsync(sendLocation, sentCallback);
}
@Override
public void sendVenueAsync(SendVenue sendVenue, SentCallback<Message> sentCallback) throws TelegramApiException {
bot.executeAsync(sendVenue, sentCallback);
}
@Override
public void sendContactAsync(SendContact sendContact, SentCallback<Message> sentCallback) throws TelegramApiException {
bot.executeAsync(sendContact, sentCallback);
}
@Override
public void kickMemberAsync(KickChatMember kickChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException {
bot.executeAsync(kickChatMember, sentCallback);
}
@Override
public void unbanMemberAsync(UnbanChatMember unbanChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException {
bot.executeAsync(unbanChatMember, sentCallback);
}
@Override
public void leaveChatAsync(LeaveChat leaveChat, SentCallback<Boolean> sentCallback) throws TelegramApiException {
bot.executeAsync(leaveChat, sentCallback);
}
@Override
public void getChatAsync(GetChat getChat, SentCallback<Chat> sentCallback) throws TelegramApiException {
bot.executeAsync(getChat, sentCallback);
}
@Override
public void getChatAdministratorsAsync(GetChatAdministrators getChatAdministrators, SentCallback<ArrayList<ChatMember>> sentCallback) throws TelegramApiException {
bot.executeAsync(getChatAdministrators, sentCallback);
}
@Override
public void getChatMemberAsync(GetChatMember getChatMember, SentCallback<ChatMember> sentCallback) throws TelegramApiException {
bot.executeAsync(getChatMember, sentCallback);
}
@Override
public void getChatMemberCountAsync(GetChatMemberCount getChatMemberCount, SentCallback<Integer> sentCallback) throws TelegramApiException {
bot.executeAsync(getChatMemberCount, sentCallback);
}
@Override
public void editMessageTextAsync(EditMessageText editMessageText, SentCallback<Serializable> sentCallback) throws TelegramApiException {
bot.executeAsync(editMessageText, sentCallback);
}
@Override
public void editMessageCaptionAsync(EditMessageCaption editMessageCaption, SentCallback<Serializable> sentCallback) throws TelegramApiException {
bot.executeAsync(editMessageCaption, sentCallback);
}
@Override
public void editMessageReplyMarkup(EditMessageReplyMarkup editMessageReplyMarkup, SentCallback<Serializable> sentCallback) throws TelegramApiException {
bot.executeAsync(editMessageReplyMarkup, sentCallback);
}
@Override
public void answerCallbackQueryAsync(AnswerCallbackQuery answerCallbackQuery, SentCallback<Boolean> sentCallback) throws TelegramApiException {
bot.executeAsync(answerCallbackQuery, sentCallback);
}
@Override
public void getUserProfilePhotosAsync(GetUserProfilePhotos getUserProfilePhotos, SentCallback<UserProfilePhotos> sentCallback) throws TelegramApiException {
bot.executeAsync(getUserProfilePhotos, sentCallback);
}
@Override
public void getFileAsync(GetFile getFile, SentCallback<File> sentCallback) throws TelegramApiException {
bot.executeAsync(getFile, sentCallback);
}
@Override
public void getMeAsync(SentCallback<User> sentCallback) throws TelegramApiException {
bot.getMeAsync(sentCallback);
}
@Override
public void getWebhookInfoAsync(SentCallback<WebhookInfo> sentCallback) throws TelegramApiException {
bot.getWebhookInfoAsync(sentCallback);
}
@Override
public void setGameScoreAsync(SetGameScore setGameScore, SentCallback<Serializable> sentCallback) throws TelegramApiException {
bot.executeAsync(setGameScore, sentCallback);
}
@Override
public void getGameHighScoresAsync(GetGameHighScores getGameHighScores, SentCallback<ArrayList<GameHighScore>> sentCallback) throws TelegramApiException {
bot.executeAsync(getGameHighScores, sentCallback);
}
@Override
public void sendGameAsync(SendGame sendGame, SentCallback<Message> sentCallback) throws TelegramApiException {
bot.executeAsync(sendGame, sentCallback);
}
@Override
public void deleteWebhook(DeleteWebhook deleteWebhook, SentCallback<Boolean> sentCallback) throws TelegramApiException {
bot.executeAsync(deleteWebhook, sentCallback);
}
@Override
public Message sendDocument(SendDocument sendDocument) throws TelegramApiException {
return bot.sendDocument(sendDocument);
}
@Override
public Message sendPhoto(SendPhoto sendPhoto) throws TelegramApiException {
return bot.sendPhoto(sendPhoto);
}
@Override
public Message sendVideo(SendVideo sendVideo) throws TelegramApiException {
return bot.sendVideo(sendVideo);
}
@Override
public Message sendSticker(SendSticker sendSticker) throws TelegramApiException {
return bot.sendSticker(sendSticker);
}
@Override
public Message sendAudio(SendAudio sendAudio) throws TelegramApiException {
return bot.sendAudio(sendAudio);
}
@Override
public Message sendVoice(SendVoice sendVoice) throws TelegramApiException {
return bot.sendVoice(sendVoice);
}
private Optional<Message> doSendMessage(String txt, long groupId, boolean format) {
SendMessage smsg = new SendMessage();
smsg.setChatId(groupId);
smsg.setText(txt);
smsg.enableMarkdown(format);
return optionalSendMessage(smsg);
}
private Optional<Message> optionalSendMessage(SendMessage smsg) {
try {
return ofNullable(sendMessage(smsg));
} catch (TelegramApiException e) {
BotLogger.error("Could not send message", TAG, e);
return empty();
}
}
}

View File

@ -0,0 +1,140 @@
package org.telegram.abilitybots.api.sender;
import org.telegram.telegrambots.api.methods.AnswerInlineQuery;
import org.telegram.telegrambots.api.methods.BotApiMethod;
import org.telegram.telegrambots.api.methods.groupadministration.SetChatPhoto;
import org.telegram.telegrambots.api.methods.send.*;
import org.telegram.telegrambots.api.methods.stickers.AddStickerToSet;
import org.telegram.telegrambots.api.methods.stickers.CreateNewStickerSet;
import org.telegram.telegrambots.api.methods.stickers.UploadStickerFile;
import org.telegram.telegrambots.api.objects.File;
import org.telegram.telegrambots.api.objects.Message;
import org.telegram.telegrambots.api.objects.User;
import org.telegram.telegrambots.api.objects.WebhookInfo;
import org.telegram.telegrambots.bots.DefaultAbsSender;
import org.telegram.telegrambots.exceptions.TelegramApiException;
import org.telegram.telegrambots.updateshandlers.DownloadFileCallback;
import org.telegram.telegrambots.updateshandlers.SentCallback;
import java.io.Serializable;
/**
* The default implementation of the {@link MessageSender}. This serves as a proxy to the {@link DefaultAbsSender} methods.
*
* @author Abbas Abou Daya
*/
public class DefaultSender implements MessageSender {
private static final String TAG = MessageSender.class.getName();
private DefaultAbsSender bot;
public DefaultSender(DefaultAbsSender bot) {
this.bot = bot;
}
@Override
public <T extends Serializable, Method extends BotApiMethod<T>, Callback extends SentCallback<T>> void executeAsync(Method method, Callback callback) throws TelegramApiException {
bot.executeAsync(method, callback);
}
@Override
public <T extends Serializable, Method extends BotApiMethod<T>> T execute(Method method) throws TelegramApiException {
return bot.execute(method);
}
@Override
public Boolean addStickerToSet(AddStickerToSet addStickerToSet) throws TelegramApiException {
return bot.addStickerToSet(addStickerToSet);
}
@Override
public Boolean createNewStickerSet(CreateNewStickerSet createNewStickerSet) throws TelegramApiException {
return bot.createNewStickerSet(createNewStickerSet);
}
@Override
public File uploadStickerFile(UploadStickerFile uploadStickerFile) throws TelegramApiException {
return bot.uploadStickerFile(uploadStickerFile);
}
@Override
public Boolean setChatPhoto(SetChatPhoto setChatPhoto) throws TelegramApiException {
return bot.setChatPhoto(setChatPhoto);
}
@Override
public java.io.File downloadFile(String path) throws TelegramApiException {
return bot.downloadFile(path);
}
@Override
public void downloadFileAsync(String path, DownloadFileCallback<String> callback) throws TelegramApiException {
bot.downloadFileAsync(path, callback);
}
@Override
public java.io.File downloadFile(File file) throws TelegramApiException {
return bot.downloadFile(file);
}
@Override
public void downloadFileAsync(File file, DownloadFileCallback<File> callback) throws TelegramApiException {
bot.downloadFileAsync(file, callback);
}
@Override
public User getMe() throws TelegramApiException {
return bot.getMe();
}
@Override
public WebhookInfo getWebhookInfo() throws TelegramApiException {
return bot.getWebhookInfo();
}
@Override
public void getMeAsync(SentCallback<User> sentCallback) throws TelegramApiException {
bot.getMeAsync(sentCallback);
}
@Override
public void getWebhookInfoAsync(SentCallback<WebhookInfo> sentCallback) throws TelegramApiException {
bot.getWebhookInfoAsync(sentCallback);
}
@Override
public Message sendDocument(SendDocument sendDocument) throws TelegramApiException {
return bot.sendDocument(sendDocument);
}
@Override
public Message sendPhoto(SendPhoto sendPhoto) throws TelegramApiException {
return bot.sendPhoto(sendPhoto);
}
@Override
public Message sendVideo(SendVideo sendVideo) throws TelegramApiException {
return bot.sendVideo(sendVideo);
}
@Override
public Message sendSticker(SendSticker sendSticker) throws TelegramApiException {
return bot.sendSticker(sendSticker);
}
@Override
public Message sendAudio(SendAudio sendAudio) throws TelegramApiException {
return bot.sendAudio(sendAudio);
}
@Override
public Message sendVoice(SendVoice sendVoice) throws TelegramApiException {
return bot.sendVoice(sendVoice);
}
@Override
public Message sendVideoNote(SendVideoNote sendVideoNote) throws TelegramApiException {
return null;
}
}

View File

@ -1,28 +1,21 @@
package org.telegram.abilitybots.api.sender;
import org.telegram.telegrambots.api.methods.*;
import org.telegram.telegrambots.api.methods.games.GetGameHighScores;
import org.telegram.telegrambots.api.methods.games.SetGameScore;
import org.telegram.telegrambots.api.methods.groupadministration.*;
import org.telegram.telegrambots.api.methods.pinnedmessages.PinChatMessage;
import org.telegram.telegrambots.api.methods.pinnedmessages.UnpinChatMessage;
import org.telegram.telegrambots.api.methods.BotApiMethod;
import org.telegram.telegrambots.api.methods.groupadministration.SetChatPhoto;
import org.telegram.telegrambots.api.methods.send.*;
import org.telegram.telegrambots.api.methods.updates.DeleteWebhook;
import org.telegram.telegrambots.api.methods.updatingmessages.DeleteMessage;
import org.telegram.telegrambots.api.methods.updatingmessages.EditMessageCaption;
import org.telegram.telegrambots.api.methods.updatingmessages.EditMessageReplyMarkup;
import org.telegram.telegrambots.api.methods.updatingmessages.EditMessageText;
import org.telegram.telegrambots.api.objects.*;
import org.telegram.telegrambots.api.objects.games.GameHighScore;
import org.telegram.telegrambots.api.methods.stickers.AddStickerToSet;
import org.telegram.telegrambots.api.methods.stickers.CreateNewStickerSet;
import org.telegram.telegrambots.api.methods.stickers.UploadStickerFile;
import org.telegram.telegrambots.api.objects.File;
import org.telegram.telegrambots.api.objects.Message;
import org.telegram.telegrambots.api.objects.User;
import org.telegram.telegrambots.api.objects.WebhookInfo;
import org.telegram.telegrambots.bots.DefaultAbsSender;
import org.telegram.telegrambots.exceptions.TelegramApiException;
import org.telegram.telegrambots.updateshandlers.DownloadFileCallback;
import org.telegram.telegrambots.updateshandlers.SentCallback;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* A sender interface that replicates {@link DefaultAbsSender} methods.
@ -30,86 +23,19 @@ import java.util.Optional;
* @author Abbas Abou Daya
*/
public interface MessageSender {
Optional<Message> send(String message, long id);
Optional<Message> sendMd(String message, long id);
<T extends Serializable, Method extends BotApiMethod<T>, Callback extends SentCallback<T>> void executeAsync(Method method, Callback callback) throws TelegramApiException;
Optional<Message> forceReply(String message, long id);
<T extends Serializable, Method extends BotApiMethod<T>> T execute(Method method) throws TelegramApiException;
Boolean answerInlineQuery(AnswerInlineQuery answerInlineQuery) throws TelegramApiException;
Boolean addStickerToSet(AddStickerToSet addStickerToSet) throws TelegramApiException;
Boolean sendChatAction(SendChatAction sendChatAction) throws TelegramApiException;
public Boolean createNewStickerSet(CreateNewStickerSet createNewStickerSet) throws TelegramApiException;
Message forwardMessage(ForwardMessage forwardMessage) throws TelegramApiException;
Message sendLocation(SendLocation sendLocation) throws TelegramApiException;
Message sendVenue(SendVenue sendVenue) throws TelegramApiException;
Message sendContact(SendContact sendContact) throws TelegramApiException;
Boolean kickMember(KickChatMember kickChatMember) throws TelegramApiException;
Boolean unbanMember(UnbanChatMember unbanChatMember) throws TelegramApiException;
Boolean leaveChat(LeaveChat leaveChat) throws TelegramApiException;
Chat getChat(GetChat getChat) throws TelegramApiException;
List<ChatMember> getChatAdministrators(GetChatAdministrators getChatAdministrators) throws TelegramApiException;
ChatMember getChatMember(GetChatMember getChatMember) throws TelegramApiException;
Integer getChatMemberCount(GetChatMemberCount getChatMemberCount) throws TelegramApiException;
public File uploadStickerFile(UploadStickerFile uploadStickerFile) throws TelegramApiException;
Boolean setChatPhoto(SetChatPhoto setChatPhoto) throws TelegramApiException;
Boolean deleteChatPhoto(DeleteChatPhoto deleteChatPhoto) throws TelegramApiException;
void deleteChatPhoto(DeleteChatPhoto deleteChatPhoto, SentCallback<Boolean> sentCallback) throws TelegramApiException;
Boolean pinChatMessage(PinChatMessage pinChatMessage) throws TelegramApiException;
void pinChatMessage(PinChatMessage pinChatMessage, SentCallback<Boolean> sentCallback) throws TelegramApiException;
Boolean unpinChatMessage(UnpinChatMessage unpinChatMessage) throws TelegramApiException;
void unpinChatMessage(UnpinChatMessage unpinChatMessage, SentCallback<Boolean> sentCallback) throws TelegramApiException;
Boolean promoteChatMember(PromoteChatMember promoteChatMember) throws TelegramApiException;
void promoteChatMember(PromoteChatMember promoteChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException;
Boolean restrictChatMember(RestrictChatMember restrictChatMember) throws TelegramApiException;
void restrictChatMember(RestrictChatMember restrictChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException;
Boolean setChatDescription(SetChatDescription setChatDescription) throws TelegramApiException;
void setChatDescription(SetChatDescription setChatDescription, SentCallback<Boolean> sentCallback) throws TelegramApiException;
Boolean setChatTite(SetChatTitle setChatTitle) throws TelegramApiException;
void setChatTite(SetChatTitle setChatTitle, SentCallback<Boolean> sentCallback) throws TelegramApiException;
String exportChatInviteLink(ExportChatInviteLink exportChatInviteLink) throws TelegramApiException;
void exportChatInviteLinkAsync(ExportChatInviteLink exportChatInviteLink, SentCallback<String> sentCallback) throws TelegramApiException;
Boolean deleteMessage(DeleteMessage deleteMessage) throws TelegramApiException;
void deleteMessageAsync(DeleteMessage deleteMessage, SentCallback<Boolean> sentCallback) throws TelegramApiException;
Serializable editMessageText(EditMessageText editMessageText) throws TelegramApiException;
Serializable editMessageCaption(EditMessageCaption editMessageCaption) throws TelegramApiException;
Serializable editMessageReplyMarkup(EditMessageReplyMarkup editMessageReplyMarkup) throws TelegramApiException;
Boolean answerCallbackQuery(AnswerCallbackQuery answerCallbackQuery) throws TelegramApiException;
UserProfilePhotos getUserProfilePhotos(GetUserProfilePhotos getUserProfilePhotos) throws TelegramApiException;
java.io.File downloadFile(String path) throws TelegramApiException;
void downloadFileAsync(String path, DownloadFileCallback<String> callback) throws TelegramApiException;
@ -118,83 +44,25 @@ public interface MessageSender {
void downloadFileAsync(File file, DownloadFileCallback<File> callback) throws TelegramApiException;
File getFile(GetFile getFile) throws TelegramApiException;
User getMe() throws TelegramApiException;
WebhookInfo getWebhookInfo() throws TelegramApiException;
Serializable setGameScore(SetGameScore setGameScore) throws TelegramApiException;
Serializable getGameHighScores(GetGameHighScores getGameHighScores) throws TelegramApiException;
Message sendGame(SendGame sendGame) throws TelegramApiException;
Boolean deleteWebhook(DeleteWebhook deleteWebhook) throws TelegramApiException;
Message sendMessage(SendMessage sendMessage) throws TelegramApiException;
void sendMessageAsync(SendMessage sendMessage, SentCallback<Message> sentCallback) throws TelegramApiException;
void answerInlineQueryAsync(AnswerInlineQuery answerInlineQuery, SentCallback<Boolean> sentCallback) throws TelegramApiException;
void sendChatActionAsync(SendChatAction sendChatAction, SentCallback<Boolean> sentCallback) throws TelegramApiException;
void forwardMessageAsync(ForwardMessage forwardMessage, SentCallback<Message> sentCallback) throws TelegramApiException;
void sendLocationAsync(SendLocation sendLocation, SentCallback<Message> sentCallback) throws TelegramApiException;
void sendVenueAsync(SendVenue sendVenue, SentCallback<Message> sentCallback) throws TelegramApiException;
void sendContactAsync(SendContact sendContact, SentCallback<Message> sentCallback) throws TelegramApiException;
void kickMemberAsync(KickChatMember kickChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException;
void unbanMemberAsync(UnbanChatMember unbanChatMember, SentCallback<Boolean> sentCallback) throws TelegramApiException;
void leaveChatAsync(LeaveChat leaveChat, SentCallback<Boolean> sentCallback) throws TelegramApiException;
void getChatAsync(GetChat getChat, SentCallback<Chat> sentCallback) throws TelegramApiException;
void getChatAdministratorsAsync(GetChatAdministrators getChatAdministrators, SentCallback<ArrayList<ChatMember>> sentCallback) throws TelegramApiException;
void getChatMemberAsync(GetChatMember getChatMember, SentCallback<ChatMember> sentCallback) throws TelegramApiException;
void getChatMemberCountAsync(GetChatMemberCount getChatMemberCount, SentCallback<Integer> sentCallback) throws TelegramApiException;
void editMessageTextAsync(EditMessageText editMessageText, SentCallback<Serializable> sentCallback) throws TelegramApiException;
void editMessageCaptionAsync(EditMessageCaption editMessageCaption, SentCallback<Serializable> sentCallback) throws TelegramApiException;
void editMessageReplyMarkup(EditMessageReplyMarkup editMessageReplyMarkup, SentCallback<Serializable> sentCallback) throws TelegramApiException;
void answerCallbackQueryAsync(AnswerCallbackQuery answerCallbackQuery, SentCallback<Boolean> sentCallback) throws TelegramApiException;
void getUserProfilePhotosAsync(GetUserProfilePhotos getUserProfilePhotos, SentCallback<UserProfilePhotos> sentCallback) throws TelegramApiException;
void getFileAsync(GetFile getFile, SentCallback<File> sentCallback) throws TelegramApiException;
void getMeAsync(SentCallback<User> sentCallback) throws TelegramApiException;
void getWebhookInfoAsync(SentCallback<WebhookInfo> sentCallback) throws TelegramApiException;
void setGameScoreAsync(SetGameScore setGameScore, SentCallback<Serializable> sentCallback) throws TelegramApiException;
void getGameHighScoresAsync(GetGameHighScores getGameHighScores, SentCallback<ArrayList<GameHighScore>> sentCallback) throws TelegramApiException;
void sendGameAsync(SendGame sendGame, SentCallback<Message> sentCallback) throws TelegramApiException;
void deleteWebhook(DeleteWebhook deleteWebhook, SentCallback<Boolean> sentCallback) throws TelegramApiException;
Message sendDocument(SendDocument sendDocument) throws TelegramApiException;
Message sendPhoto(SendPhoto sendPhoto) throws TelegramApiException;
Message sendVideo(SendVideo sendVideo) throws TelegramApiException;
Message sendSticker(SendSticker sendSticker) throws TelegramApiException;
Message sendAudio(SendAudio sendAudio) throws TelegramApiException;
Message sendVoice(SendVoice sendVoice) throws TelegramApiException;
Message sendVideoNote(SendVideoNote sendVideoNote) throws TelegramApiException;
Message sendSticker(SendSticker sendSticker) throws TelegramApiException;
}

View File

@ -0,0 +1,67 @@
package org.telegram.abilitybots.api.sender;
import org.telegram.telegrambots.api.methods.BotApiMethod;
import org.telegram.telegrambots.api.methods.send.SendMessage;
import org.telegram.telegrambots.api.objects.Message;
import org.telegram.telegrambots.api.objects.replykeyboard.ForceReplyKeyboard;
import org.telegram.telegrambots.exceptions.TelegramApiException;
import org.telegram.telegrambots.logging.BotLogger;
import java.io.Serializable;
import java.util.Optional;
//TODO: DOC
public class SilentSender {
private static final String TAG = SilentSender.class.getSimpleName();
private final MessageSender sender;
public SilentSender(MessageSender sender) {
this.sender = sender;
}
public Optional<Message> send(String message, long id) {
return doSendMessage(message, id, false);
}
public Optional<Message> sendMd(String message, long id) {
return doSendMessage(message, id, true);
}
public Optional<Message> forceReply(String message, long id) {
SendMessage msg = new SendMessage();
msg.setText(message);
msg.setChatId(id);
msg.setReplyMarkup(new ForceReplyKeyboard());
return execute(msg);
}
private Optional<Message> doSendMessage(String txt, long groupId, boolean format) {
SendMessage smsg = new SendMessage();
smsg.setChatId(groupId);
smsg.setText(txt);
smsg.enableMarkdown(format);
return execute(smsg);
}
private <T extends Serializable, Method extends BotApiMethod<T>> Optional<T> execute(Method method) {
try {
return Optional.ofNullable(sender.execute(method));
} catch (TelegramApiException e) {
BotLogger.error("Could not execute bot API method", TAG, e);
return Optional.empty();
}
}
private <T extends Serializable, Method extends BotApiMethod<T>> Optional<T> executeAsync(Method method) {
try {
return Optional.ofNullable(sender.execute(method));
} catch (TelegramApiException e) {
BotLogger.error("Could not execute bot API method", TAG, e);
return Optional.empty();
}
}
}

View File

@ -2,14 +2,15 @@ package org.telegram.abilitybots.api.bot;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.Files;
import org.apache.commons.io.FileUtils;
import org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Matchers;
import org.telegram.abilitybots.api.db.DBContext;
import org.telegram.abilitybots.api.objects.*;
import org.telegram.abilitybots.api.sender.MessageSender;
import org.telegram.abilitybots.api.sender.SilentSender;
import org.telegram.abilitybots.api.util.Pair;
import org.telegram.abilitybots.api.util.Trio;
import org.telegram.telegrambots.api.objects.*;
@ -25,9 +26,11 @@ import java.util.Set;
import static com.google.common.collect.Sets.newHashSet;
import static java.lang.String.format;
import static java.util.Collections.emptySet;
import static org.apache.commons.io.FileUtils.deleteQuietly;
import static org.apache.commons.lang3.ArrayUtils.addAll;
import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
import static org.mockito.internal.verification.VerificationModeFactory.times;
import static org.telegram.abilitybots.api.bot.AbilityBot.RECOVERY_MESSAGE;
@ -54,13 +57,18 @@ public class AbilityBotTest {
private DefaultBot bot;
private DBContext db;
private MessageSender sender;
private SilentSender silent;
@Before
public void setUp() {
db = offlineInstance("db");
bot = new DefaultBot(EMPTY, EMPTY, db);
sender = mock(MessageSender.class);
bot.setSender(sender);
silent = mock(SilentSender.class);
bot.sender = sender;
bot.silent = silent;
}
@Test
@ -69,7 +77,7 @@ public class AbilityBotTest {
bot.onUpdateReceived(update);
verify(sender, times(1)).send(format("Sorry, %s-only feature.", "admin"), MUSER.id());
verify(silent, times(1)).send(format("Sorry, %s-only feature.", "admin"), MUSER.id());
}
@Test
@ -78,7 +86,7 @@ public class AbilityBotTest {
bot.onUpdateReceived(update);
verify(sender, times(1)).send(format("Sorry, %s-only feature.", "group"), MUSER.id());
verify(silent, times(1)).send(format("Sorry, %s-only feature.", "group"), MUSER.id());
}
@ -88,7 +96,7 @@ public class AbilityBotTest {
bot.onUpdateReceived(update);
verify(sender, times(1)).send(format("Sorry, this feature requires %d additional inputs.", 4), MUSER.id());
verify(silent, times(1)).send(format("Sorry, this feature requires %d additional inputs.", 4), MUSER.id());
}
@Test
@ -97,7 +105,7 @@ public class AbilityBotTest {
// False means the update was not pushed down the stream since it has been consumed by the reply
assertFalse(bot.filterReply(update));
verify(sender, times(1)).send("reply", MUSER.id());
verify(silent, times(1)).send("reply", MUSER.id());
}
@Test
@ -105,6 +113,7 @@ public class AbilityBotTest {
MessageContext context = defaultContext();
bot.backupDB().action().accept(context);
deleteQuietly(new java.io.File("backup.json"));
verify(sender, times(1)).sendDocument(any());
}
@ -115,10 +124,10 @@ public class AbilityBotTest {
Object backup = getDbBackup();
java.io.File backupFile = createBackupFile(backup);
when(sender.downloadFile(Matchers.any(File.class))).thenReturn(backupFile);
when(sender.downloadFile(any(File.class))).thenReturn(backupFile);
bot.recoverDB().replies().get(0).actOn(update);
verify(sender, times(1)).send(RECOVER_SUCCESS, GROUP_ID);
verify(silent, times(1)).send(RECOVER_SUCCESS, GROUP_ID);
assertEquals("Bot recovered but the DB is still not in sync", db.getSet(TEST), newHashSet(TEST));
assertTrue("Could not delete backup file", backupFile.delete());
}
@ -492,7 +501,7 @@ public class AbilityBotTest {
bot.reportCommands().action().accept(context);
verify(sender, times(1)).send("default - dis iz default command", GROUP_ID);
verify(silent, times(1)).send("default - dis iz default command", GROUP_ID);
}
@After

View File

@ -38,8 +38,8 @@ public class DefaultBot extends AbilityBot {
return getDefaultBuilder()
.name(DEFAULT)
.info("dis iz default command")
.reply(upd -> sender.send("reply", upd.getMessage().getChatId()), MESSAGE, update -> update.getMessage().getText().equals("must reply"))
.reply(upd -> sender.send("reply", upd.getCallbackQuery().getMessage().getChatId()), CALLBACK_QUERY)
.reply(upd -> silent.send("reply", upd.getMessage().getChatId()), MESSAGE, update -> update.getMessage().getText().equals("must reply"))
.reply(upd -> silent.send("reply", upd.getCallbackQuery().getMessage().getChatId()), CALLBACK_QUERY)
.build();
}
@ -70,9 +70,4 @@ public class DefaultBot extends AbilityBot {
public Ability testAbility() {
return getDefaultBuilder().build();
}
@VisibleForTesting
void setSender(MessageSender sender) {
this.sender = sender;
}
}