TelegramAPI/src/main/java/de/mrbesen/telegram/commands/FeedbackCommand.java

190 lines
6.6 KiB
Java
Raw Normal View History

2020-02-29 08:04:33 +01:00
package de.mrbesen.telegram.commands;
import de.mrbesen.telegram.AsyncHandler;
import de.mrbesen.telegram.MessageBuilder;
import de.mrbesen.telegram.TelegramAPI;
import de.mrbesen.telegram.event.events.UserCallbackEvent;
import de.mrbesen.telegram.event.events.UserSendMessageEvent;
import de.mrbesen.telegram.objects.TInlineKeyboardMarkup;
import de.mrbesen.telegram.objects.TMessage;
import de.mrbesen.telegram.objects.TUser;
2021-01-02 17:48:26 +01:00
import lombok.Setter;
2020-02-29 08:04:33 +01:00
2020-02-29 11:59:32 +01:00
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
2021-01-02 17:48:26 +01:00
import java.util.function.Function;
2020-02-29 08:04:33 +01:00
public class FeedbackCommand implements JSONCommandHandler {
2020-12-02 19:57:37 +01:00
protected final TInlineKeyboardMarkup cancelMarkup = TInlineKeyboardMarkup.makeSingleButton("❌ cancel", CANCELFEEDBACK);
2020-02-29 08:04:33 +01:00
protected final Map<Long, TMessage> awaitingFeedback = new TreeMap<>(); //maps users chat id -> message that said "please send feedback" TODO: make persistent?
protected final Map<Long, Long[]> answer = new TreeMap<>(); // chatid -> [chatid, messageid] to answer to; next message from key will be fwd to value[0] and reply to value[1]
2020-02-29 08:04:33 +01:00
protected final TelegramAPI api;
2020-02-29 11:59:32 +01:00
protected final List<Long> admins;
2020-02-29 08:04:33 +01:00
protected final static String CANCELFEEDBACK = "cancelfeedback", REPLYFEEDBACK = "replyFeedback ";
2021-01-02 17:48:26 +01:00
@Setter
private Function<TUser, String> feedbackCallback = null;
2020-02-29 08:04:33 +01:00
2020-02-29 11:59:32 +01:00
public FeedbackCommand(TelegramAPI api, List<Long> admins) {
2020-02-29 08:04:33 +01:00
this.api = api;
2020-02-29 11:59:32 +01:00
this.admins = (admins == null ? new LinkedList<>() : admins);
2020-02-29 08:04:33 +01:00
}
@Override
public boolean onCommand(TUser sender, String cmd, String[] args, TMessage json) {
2020-02-29 11:59:32 +01:00
if(json.getChatID() < 0) return false; //do not handle group chats
2020-02-29 08:04:33 +01:00
if(cmd.equalsIgnoreCase("feedback")) {
removeMsg(sender.getID(), null);
awaitingFeedback.put(sender.getID(), null);
MessageBuilder mb = new MessageBuilder();
mb.setAsync().setReciver(sender).setMarkup(cancelMarkup).setText("Your next message will be forwarded to the admins.")
2020-02-29 08:04:33 +01:00
.setCallback(new AsyncHandler.Callback<TMessage, Object>() {
@Override
2020-02-29 11:59:32 +01:00
public Object call(TMessage msg) {
2020-02-29 08:04:33 +01:00
awaitingFeedback.put(sender.getID(), msg);
return null;
}
});
api.sendMessage(mb.build());
return true;
}
return false;
}
2020-02-29 11:59:32 +01:00
public boolean onMsg(UserSendMessageEvent e) {
2020-02-29 08:04:33 +01:00
TUser user = e.getUser();
TMessage msg = e.getMsg();
2021-01-02 17:48:26 +01:00
if (awaitingFeedback.containsKey(user.getID())) { //user send a feedback
removeMsg(user.getID(), e.getMsg());
2020-02-29 11:59:32 +01:00
if(isFeedback(msg.getText())) {
2020-02-29 08:04:33 +01:00
//fwd to admins
admins.forEach(a -> TMessage.forwardAsync(api, a, msg));
2021-01-02 17:48:26 +01:00
MessageBuilder mb = createInfo(user, msg.getMessageID(), true);
2020-02-29 11:59:32 +01:00
admins.forEach(a -> api.sendMessage(mb.setReciver(a).build()));
} else {
System.out.println("feedback omitted: " + msg.getText());
}
return true;
2021-01-02 17:48:26 +01:00
} else { //reply to a message
Long[] rplymsg = answer.remove(user.getID());
2020-02-29 11:59:32 +01:00
if(rplymsg != null) {
if(admins.contains(user.getID())) {
System.out.println("admin answered feedback!");
2020-02-29 11:59:32 +01:00
//admin to user -> copy text send as new msg from bot to disguise admin
TInlineKeyboardMarkup mu = new TInlineKeyboardMarkup(1);
mu.addCallbackButton("↩ reply", buildRplyCallback(user.getID(), msg.getMessageID()), 1);
MessageBuilder mb = new MessageBuilder().setAsync().setReciver(rplymsg[0])
.setReplyTo(Math.toIntExact(rplymsg[1])).setText(msg.getText()).setMarkup(mu);
api.sendMessage(mb.build());
} else {
System.out.println("user answered feedback!");
2020-02-29 11:59:32 +01:00
//user to admin -> fwd message
TMessage.forwardAsync(api, rplymsg[0], msg);
//send info
2021-01-02 17:48:26 +01:00
MessageBuilder mb = createInfo(user, msg.getMessageID(), false);
2020-02-29 11:59:32 +01:00
api.sendMessage(mb.setReciver(rplymsg[0]).setReplyTo(Math.toIntExact(rplymsg[1])).build());
}
System.out.println("Feedback reply from " + user.getID() + " to " + rplymsg[0] + ":" + rplymsg[1] + " send.");
return true;
2020-02-29 08:04:33 +01:00
}
}
2020-02-29 11:59:32 +01:00
return false;
}
2021-01-02 17:48:26 +01:00
protected MessageBuilder createInfo(TUser u, int msgid, boolean firstmsg) {
2020-02-29 11:59:32 +01:00
String info = "Feedbackinfo:\n" + "userid: " + u.getID() + "\nusername: " + u.getName() + "\nfullname: " + u.getFirstName() + ' ' + u.getLastName();
2021-01-02 17:48:26 +01:00
MessageBuilder mb = new MessageBuilder().setAsync();
2021-01-02 17:48:26 +01:00
if(firstmsg && feedbackCallback != null) {
try {
info += '\n' + feedbackCallback.apply(u);
mb.setNoWebView(true);
2021-01-02 17:48:26 +01:00
} catch (Throwable t) {
info += "\nError getting information: " + t.getMessage();
t.printStackTrace();
}
}
2020-02-29 11:59:32 +01:00
TInlineKeyboardMarkup markup = new TInlineKeyboardMarkup(1);
markup.addUrlButton("chat with user", "https://t.me/" + u.getName(), 1);
markup.addCallbackButton("↩ reply", buildRplyCallback(u.getID(), msgid), 1);
return mb.setText(info).setFormatting(MessageBuilder.Formatting.HTML).setMarkup(markup);
2020-02-29 08:04:33 +01:00
}
2020-02-29 11:59:32 +01:00
public boolean onCallback(UserCallbackEvent e) {
2020-02-29 08:04:33 +01:00
if(e.getData().equals(CANCELFEEDBACK)) {
removeMsg(e.getUser().getID(), e.getMsg());
api.answerCallbackQuery(e.getID(), "Cancelled", true);
2020-02-29 11:59:32 +01:00
return true;
2020-02-29 08:04:33 +01:00
} else if(e.getData().startsWith(REPLYFEEDBACK)) {
String rest = e.getData().substring(REPLYFEEDBACK.length());
2020-02-29 11:59:32 +01:00
long chatid = 0;
long msgid = -1;
try {
String[] spl = rest.split(" ",2);
long adminid = Long.parseLong(spl[0]);
msgid = Integer.parseInt(spl[1]);
//convert admin id to chat id
if(adminid <= 0) {
chatid = admins.get((int) -adminid);
} else
chatid = adminid;
} catch (NumberFormatException ex) {
api.answerCallbackQuery(e.getID(), "Error. Sorry :/", true);
ex.printStackTrace();
}
if(msgid > -1) {
answer.put(e.getUser().getID(), new Long[]{chatid, msgid});
2020-02-29 11:59:32 +01:00
api.answerCallbackQuery(e.getID(), "Write a Message", true);
}
return true;
2020-02-29 08:04:33 +01:00
}
2020-02-29 11:59:32 +01:00
return false;
2020-02-29 08:04:33 +01:00
}
/**
* looks up msg from awaiting feedback map, if not present try to use fallback_msg
* is Async
* removes user from awaitingFeedback
2020-02-29 11:59:32 +01:00
*
2020-02-29 08:04:33 +01:00
*/
2020-02-29 11:59:32 +01:00
protected void removeMsg(long chat, TMessage fallback_msg) {
2020-02-29 08:04:33 +01:00
TMessage msg = awaitingFeedback.remove(chat);
if(msg == null) msg = fallback_msg;
if(msg != null) TMessage.delete(api, msg.getChatID(), msg.getMessageID(), true);
}
/**
* check if a message is allowed as feedback
* @param msg
* @return
*/
protected boolean isFeedback(String msg) {
msg = msg.trim();
2020-02-29 11:59:32 +01:00
return (!msg.startsWith("/")) && (msg.length() > 5) && (!msg.startsWith("http"));
}
protected int getAdminID(long adminchat) {
for(int i = 0; i < admins.size(); i++) {
if(admins.get(i) == adminchat)
return i;
}
return -1;
}
protected String buildRplyCallback(long user, int msgid) {
int adminid = getAdminID(user);
if(adminid >= 0) user = -adminid;
return REPLYFEEDBACK + user + " " + msgid;
2020-02-29 08:04:33 +01:00
}
}