diff --git a/pom.xml b/pom.xml
index 6016751..75179ea 100644
--- a/pom.xml
+++ b/pom.xml
@@ -42,6 +42,11 @@
20180813
compile
+
+ org.projectlombok
+ lombok
+ LATEST
+
1.8
diff --git a/src/main/java/de/mrbesen/telegram/TelegramAPI.java b/src/main/java/de/mrbesen/telegram/TelegramAPI.java
index eb4a993..3e4b99b 100644
--- a/src/main/java/de/mrbesen/telegram/TelegramAPI.java
+++ b/src/main/java/de/mrbesen/telegram/TelegramAPI.java
@@ -6,11 +6,15 @@ import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLEncoder;
import java.util.LinkedList;
+import java.util.List;
import java.util.Scanner;
import javax.net.ssl.HttpsURLConnection;
+import de.mrbesen.telegram.commands.FeedbackCommand;
import de.mrbesen.telegram.commands.JSONCommandHandler;
+import lombok.Getter;
+import lombok.Setter;
import org.json.JSONArray;
import org.json.JSONObject;
@@ -33,6 +37,7 @@ import de.mrbesen.telegram.objects.TMessage;
import de.mrbesen.telegram.objects.TReplyMarkup;
import de.mrbesen.telegram.objects.TUser;
import de.mrbesen.telegram.objects.TUser.Status;
+import sun.awt.image.ImageWatched;
public class TelegramAPI implements Runnable {
@@ -47,14 +52,10 @@ public class TelegramAPI implements Runnable {
private String botname;
private Thread thread;
private boolean run = true;
+ @Getter @Setter
private boolean longpolling = true;
- public boolean isLongpolling() {
- return longpolling;
- }
-
- public void setLongpolling(boolean longpolling) {
- this.longpolling = longpolling;
- }
+ @Setter @Getter
+ private boolean disableFeedback = false;
private String helpmessage = "generic helppage\nuse TelegramAPI.setHelpText(java.lang.String) to change this.";
@@ -63,6 +64,8 @@ public class TelegramAPI implements Runnable {
protected long start = 0;
private LinkedList users = new LinkedList<>();
+ @Setter
+ private List admins = new LinkedList<>(); //required for feedback
private CommandManager cmdmgr = new CommandManager(this);
private EventManager evntmgr = new EventManager();
@@ -104,6 +107,11 @@ public class TelegramAPI implements Runnable {
public void start() {
if(thread == null) {
+ if(!disableFeedback) {
+ //init Feedback
+ FeedbackCommand fcmd = new FeedbackCommand();
+ cmdmgr.registerCommand("feedback", fcmd);
+ }
run = true;
thread = new Thread(this, "TelegramAPI");
thread.start();
@@ -112,6 +120,10 @@ public class TelegramAPI implements Runnable {
}
}
+ public void addAdmin(long admin) {
+ admins.add(admin);
+ }
+
public void request(Task task) {
async.enque(task);
}
diff --git a/src/main/java/de/mrbesen/telegram/commands/FeedbackCommand.java b/src/main/java/de/mrbesen/telegram/commands/FeedbackCommand.java
new file mode 100644
index 0000000..0545d52
--- /dev/null
+++ b/src/main/java/de/mrbesen/telegram/commands/FeedbackCommand.java
@@ -0,0 +1,110 @@
+package de.mrbesen.telegram.commands;
+
+import com.sun.istack.internal.Nullable;
+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;
+
+import java.util.*;
+
+public class FeedbackCommand implements JSONCommandHandler {
+
+ protected final TInlineKeyboardMarkup cancel = new TInlineKeyboardMarkup(1);
+ protected final Map awaitingFeedback = new TreeMap<>(); //maps users chat id -> message that said "please send feedback" TODO: make persistent?
+ protected final TelegramAPI api;
+ protected final Collection admins;
+ protected final static String CANCELFEEDBACK = "cancelfeedback", REPLYFEEDBACK = "replyFeedback ";
+
+
+ public FeedbackCommand(TelegramAPI api, Collection admins) {
+ this.api = api;
+ this.admins = admins;
+ //build markup
+ cancel.addCallbackButton("❌ cancel", CANCELFEEDBACK, 0);
+ api.getEventManager().registerEvent(UserSendMessageEvent.class, this::onMsg);
+ api.getEventManager().registerEvent(UserCallbackEvent.class, this::onCallback);
+ }
+
+ @Override
+ public boolean onCommand(TUser sender, String cmd, String[] args, TMessage json) {
+ if(cmd.equalsIgnoreCase("feedback")) {
+ removeMsg(sender.getID(), null);
+ awaitingFeedback.put(sender.getID(), null);
+ MessageBuilder mb = new MessageBuilder();
+ mb.setAsync().setMarkup(cancel).setText("Your next Message will be forwarded to the admins.")
+ .setCallback(new AsyncHandler.Callback() {
+ @Override
+ public Object call(TMessage msg) throws Throwable {
+ awaitingFeedback.put(sender.getID(), msg);
+ return null;
+ }
+ });
+ api.sendMessage(mb.build());
+ return true;
+ }
+ return false;
+ }
+
+ public void onMsg(Object event) {
+ UserSendMessageEvent e = (UserSendMessageEvent) event;
+ TUser user = e.getUser();
+ TMessage msg = e.getMessage();
+ if(isFeedback(msg.getText())) {
+ if (awaitingFeedback.containsKey(user.getID())) {
+ removeMsg(user.getID(), e.getMessage());
+
+ //fwd to admins
+ admins.forEach(a -> TMessage.forwardAsync(api, a, msg));
+
+ StringBuilder info = new StringBuilder("Feedbackinfo:\n");
+ info.append("userid: ").append(user.getID());
+ info.append("\nusername: ").append(user.getName());
+ info.append("\nfullname: ").append(user.getFirstName()).append(' ').append(user.getLastName());
+ TInlineKeyboardMarkup markup = new TInlineKeyboardMarkup(1);
+ markup.addUrlButton("chat with user", "tg://" + user.getName(), 1);
+ markup.addCallbackButton("reply ↩", REPLYFEEDBACK + user.getID() + " " + msg.getMessageID(), 1);
+ admins.forEach(a -> api.sendAsync(a, info.toString()));
+ }
+ }
+ }
+
+ public void onCallback(Object event) {
+ UserCallbackEvent e = (UserCallbackEvent) event;
+ if(e.getData().equals(CANCELFEEDBACK)) {
+ removeMsg(e.getUser().getID(), e.getMsg());
+ api.answerCallbackQuery(e.getID(), "Cancelled", true);
+ } else if(e.getData().startsWith(REPLYFEEDBACK)) {
+ String rest = e.getData().substring(REPLYFEEDBACK.length());
+ //TODO
+ }
+ }
+
+ /**
+ * looks up msg from awaiting feedback map, if not present try to use fallback_msg
+ * is Async
+ * removes user from awaitingFeedback
+ * @param chat
+ * @param fallback_msg
+ */
+ protected void removeMsg(long chat, @Nullable TMessage fallback_msg) {
+ 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();
+ return !msg.startsWith("/") && msg.length() > 5 && !msg.startsWith("http");
+ }
+}
diff --git a/src/main/java/de/mrbesen/telegram/objects/TUser.java b/src/main/java/de/mrbesen/telegram/objects/TUser.java
index 70842eb..2f834cf 100644
--- a/src/main/java/de/mrbesen/telegram/objects/TUser.java
+++ b/src/main/java/de/mrbesen/telegram/objects/TUser.java
@@ -1,5 +1,6 @@
package de.mrbesen.telegram.objects;
+import lombok.Getter;
import org.json.JSONObject;
import de.mrbesen.telegram.AsyncHandler.Callback;
@@ -9,48 +10,44 @@ import de.mrbesen.telegram.TelegramAPI;
public class TUser {
- private long id;
+ @Getter
+ private long ID;
private String uname;//optional
- private String firstname;
- private String lastname;//optional
+ @Getter
+ private String firstName;
+ @Getter
+ private String lastName;//optional
+ @Getter
private String langcode; // optional
private boolean isBot = false;
private TelegramAPI api = null;
TUser(long chatid, String uname, TelegramAPI api) {
- this.id = chatid;
+ this.ID = chatid;
this.uname = uname;
this.api = api;
}
public TUser(long chatid, TelegramAPI api) {
this.api = api;
- this.id = chatid;
+ this.ID = chatid;
}
public TUser(JSONObject o, TelegramAPI api) {
this.api = api;
- firstname = o.getString("first_name");
+ firstName = o.getString("first_name");
isBot = o.getBoolean("is_bot");
- id = o.getLong("id");
+ ID = o.getLong("id");
if(o.has("last_name"))
- lastname = o.getString("last_name");
+ lastName = o.getString("last_name");
if(o.has("username"))
uname = o.getString("username");
if(o.has("language_code"))
langcode = o.getString("language_code");
}
- public String getFirstName() {
- return firstname;
- }
-
- public String getLastName() {
- return lastname;
- }
-
public String getLangcode() {
return langcode;
}
@@ -59,10 +56,6 @@ public class TUser {
return isBot;
}
- public long getID() {
- return id;
- }
-
public String getName() {
return uname;
}
@@ -76,7 +69,7 @@ public class TUser {
}
public boolean sendMessage(String text, TReplyMarkup rm, int reply_to_msg) {
- return sendMessage(api, id, text, rm, reply_to_msg, false, null);
+ return sendMessage(api, ID, text, rm, reply_to_msg, false, null);
}
/**
@@ -100,14 +93,14 @@ public class TUser {
public void sendStatus(Status status) {
try {
- api.request("sendChatAction", "chat_id="+id+"&action=" + status.getAPIName());
+ api.request("sendChatAction", "chat_id="+ ID +"&action=" + status.getAPIName());
} catch (Exception e) {
System.err.println("Failed to send status.");
}
}
public boolean sendImage(String caption, String url) {
- return sendImage(api, id, caption, url, null, null) != null;
+ return sendImage(api, ID, caption, url, null, null) != null;
}
public static TMessage sendImage(TelegramAPI api, long userid, String caption, String url, TReplyMarkup rply, Callback async) {
@@ -116,7 +109,7 @@ public class TUser {
}
public boolean sendAnimation(String caption, String url) {
- return sendAnimation(api, id, caption, url, null, null) != null;
+ return sendAnimation(api, ID, caption, url, null, null) != null;
}
public static TMessage sendAnimation(TelegramAPI api, long userid, String caption, String url, TReplyMarkup rply, Callback async) {
@@ -127,7 +120,7 @@ public class TUser {
@Override
public boolean equals(Object user) {
if(user instanceof TUser) {
- return ((TUser) user).getID() == id;
+ return ((TUser) user).getID() == ID;
}
return false;
}