diff --git a/src/main/java/de/mrbesen/telegram/AsyncHandler.java b/src/main/java/de/mrbesen/telegram/AsyncHandler.java index 5fc6c1a..3c8b36b 100644 --- a/src/main/java/de/mrbesen/telegram/AsyncHandler.java +++ b/src/main/java/de/mrbesen/telegram/AsyncHandler.java @@ -1,11 +1,11 @@ package de.mrbesen.telegram; +import org.json.JSONObject; + import java.net.UnknownHostException; import java.util.LinkedList; import java.util.List; -import org.json.JSONObject; - public class AsyncHandler implements Runnable { private List tasks = new LinkedList<>(); @@ -44,8 +44,8 @@ public class AsyncHandler implements Runnable { ensureThreads(tasks.size()); } - public void enque(String request, String parameters) { - enque(new Task(request, parameters)); + public void enque(String request, String parameters, long userid) { + enque(new Task(request, parameters, userid)); } //makes sure, that at least count Threads are running @@ -84,7 +84,7 @@ public class AsyncHandler implements Runnable { //run task try { try { - Object obj = api.request(current.apimethod, current.parameters); + Object obj = api.request(current.apimethod, current.parameters, current.userid); Callback callb = current.callback; while(callb != null) { obj = (Object) callb.callObj(obj); @@ -125,15 +125,18 @@ public class AsyncHandler implements Runnable { String parameters; Callback callback = null; Callback exceptionhandl = null; + final long userid; - public Task(String apimethod, String parameters) { + public Task(String apimethod, String parameters, long userid) { this.apimethod = apimethod; this.parameters = parameters; + this.userid = userid; } - public Task(String apimethod, String parameters, Callback callback) { + public Task(String apimethod, String parameters, long userid, Callback callback) { this.apimethod = apimethod; this.parameters = parameters; + this.userid = userid; this.callback = callback; } diff --git a/src/main/java/de/mrbesen/telegram/MessageBuilder.java b/src/main/java/de/mrbesen/telegram/MessageBuilder.java index 99e2e0b..b75bf4a 100644 --- a/src/main/java/de/mrbesen/telegram/MessageBuilder.java +++ b/src/main/java/de/mrbesen/telegram/MessageBuilder.java @@ -1,12 +1,14 @@ package de.mrbesen.telegram; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; - import de.mrbesen.telegram.AsyncHandler.Callback; import de.mrbesen.telegram.objects.TMessage; import de.mrbesen.telegram.objects.TReplyMarkup; import de.mrbesen.telegram.objects.TUser; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; public class MessageBuilder { @@ -213,11 +215,11 @@ public class MessageBuilder { String q = "chat_id=" + reciver_id + text + optionals + attachment; if(async) { - AsyncSendable tmp = new AsyncSendable(cmd, q, callback, excpt); + AsyncSendable tmp = new AsyncSendable(cmd, q, reciver_id, callback, excpt); tmp.prio = asyncprio; return tmp; } - return new SendableMessage(cmd, q); + return new SendableMessage(cmd, q, reciver_id); } /** @@ -227,21 +229,13 @@ public class MessageBuilder { public TMessage send() { return api.sendMessage(build()); } - + + @Getter + @AllArgsConstructor class SendableMessage { - private String q; - private String command; - - public SendableMessage(String cmd, String q) { - this.q = q; - command = cmd; - } - String getQ() { - return q; - } - String getCommand() { - return command; - } + private final String q; + private final String command; + private final long userid; } class AsyncSendable extends SendableMessage { @@ -250,8 +244,8 @@ public class MessageBuilder { Callback excpt = null; boolean prio = false; - public AsyncSendable(String cmd, String q, Callback clb, Callback excpt) { - super(cmd, q); + public AsyncSendable(String cmd, String q, long userid, Callback clb, Callback excpt) { + super(cmd, q, userid); callback = clb; this.excpt = excpt; } diff --git a/src/main/java/de/mrbesen/telegram/TelegramAPI.java b/src/main/java/de/mrbesen/telegram/TelegramAPI.java index f3d1ca3..b5f8109 100644 --- a/src/main/java/de/mrbesen/telegram/TelegramAPI.java +++ b/src/main/java/de/mrbesen/telegram/TelegramAPI.java @@ -12,8 +12,11 @@ import de.mrbesen.telegram.event.events.*; import de.mrbesen.telegram.log.Log; import de.mrbesen.telegram.log.Log4JLog; import de.mrbesen.telegram.log.SimpleLog; -import de.mrbesen.telegram.objects.*; import de.mrbesen.telegram.objects.JSONBased.Member; +import de.mrbesen.telegram.objects.TFile; +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 lombok.Getter; import lombok.Setter; @@ -136,15 +139,15 @@ public class TelegramAPI implements Runnable { async.enque(task); } - public void requestAsync(String request, String parameter) { - this.async.enque(request, parameter); + public void requestAsync(String request, String parameter, long userid) { + this.async.enque(request, parameter, userid); } - public JSONObject request(String request, String parameter) throws IOException { - return request(request, parameter, true); + public JSONObject request(String request, String parameter, long userid) throws IOException { + return request(request, parameter, userid,true); } - public JSONObject request(String request, String parameter, boolean logging) throws IOException { + public JSONObject request(String request, String parameter, long userid, boolean logging) throws IOException { //do https stuff boolean toomany = true; //für retry after 429 error int trycount = 0; @@ -198,6 +201,11 @@ public class TelegramAPI implements Runnable { } catch(InterruptedException e) {} if(trycount < 10) continue; + } else if(response == 403) { + if(errdesc.equals("Forbidden: bot was blocked by the user")) { + if(userid != 0) + evntmgr.callEvent(new UserBlockedBotEvent(getUser(userid))); + } } throw new APIError(parameter, request, con.getResponseCode(), null, errdesc); @@ -235,11 +243,11 @@ public class TelegramAPI implements Runnable { AsyncSendable asyncm = (AsyncSendable) msg; Callback adapter = getCallbackAdapter(this); adapter.next = asyncm.callback; - Task t = new Task(msg.getCommand(), msg.getQ(), adapter); + Task t = new Task(msg.getCommand(), msg.getQ(), msg.getUserid(), adapter); t.setExceptionhandl(asyncm.excpt == null ? IOE400supressor : asyncm.excpt); async.enque(t); } else { - JSONObject o = request(msg.getCommand(), msg.getQ(), true); + JSONObject o = request(msg.getCommand(), msg.getQ(), msg.getUserid(), true); return new TMessage(o.getJSONObject("result"), this); } } catch(IOException e) { @@ -285,7 +293,7 @@ public class TelegramAPI implements Runnable { }); //commit - Task t = new Task("setMyCommands", "commands=" + arr.toString(), null); + Task t = new Task("setMyCommands", "commands=" + arr.toString(), 0, null); async.enque(t); } @@ -295,7 +303,7 @@ public class TelegramAPI implements Runnable { } public TFile getFile(final String fileid) throws IOException { - JSONObject jfile = request("getFile", "file_id=" + fileid); + JSONObject jfile = request("getFile", "file_id=" + fileid, 0); return new TFile(jfile.getJSONObject("result")); } @@ -319,10 +327,10 @@ public class TelegramAPI implements Runnable { return; if(async) { - requestAsync("answerCallbackQuery", "callback_query_id=" + callbackid + "&text=" + text); + requestAsync("answerCallbackQuery", "callback_query_id=" + callbackid + "&text=" + text, 0); } else { try { - request("answerCallbackQuery", "callback_query_id=" + callbackid + "&text=" + text); + request("answerCallbackQuery", "callback_query_id=" + callbackid + "&text=" + text, 0); } catch(IOException e) { e.printStackTrace(); } @@ -345,7 +353,7 @@ public class TelegramAPI implements Runnable { rply = "&reply_markup=" + URLEncoder.encode(rm.toJSONString(), "UTF-8"); String q = "chat_id=" + chatid + "&message_id=" + msg_id + "&caption=" + URLEncoder.encode(newCaption, "UTF-8") + rply; if(async) { - Task t = new Task("editMessageCaption", q); + Task t = new Task("editMessageCaption", q, chatid); t.setExceptionhandl(new Callback() { @Override public Void call(Throwable j) throws Throwable { @@ -361,7 +369,7 @@ public class TelegramAPI implements Runnable { }); this.async.enque(t); } else { - request("editMessageCaption", q); + request("editMessageCaption", q, chatid); } } catch(IOException e) { log.log("", e); @@ -375,9 +383,9 @@ public class TelegramAPI implements Runnable { String q = "chat_id=" + chatid + "&message_id=" + msg_id + "&reply_markup=" + URLEncoder.encode(rm.toJSONString(), "UTF-8"); if(async) { - this.async.enque("editMessageReplyMarkup", q); + this.async.enque("editMessageReplyMarkup", q, chatid); } else { - request("editMessageReplyMarkup", q); + request("editMessageReplyMarkup", q, chatid); } } catch(IOException e) { log.log("", e); @@ -422,7 +430,7 @@ public class TelegramAPI implements Runnable { private void fetchUpdates() { try { - processUpdates(request("getUpdates", "offset=" + msg_offset + "&timeout=" + (longpolling ? updateInterval : 1), false)); + processUpdates(request("getUpdates", "offset=" + msg_offset + "&timeout=" + (longpolling ? updateInterval : 1), 0,false)); } catch (IOException e) { log.log("error getting updates.", e); @@ -456,6 +464,7 @@ public class TelegramAPI implements Runnable { if(u != null || !createIfNotExitsts) return u; u = new TUser(id, this); + evntmgr.callEvent(new NewUserEvent(u)); users.put(id, u); return u; } diff --git a/src/main/java/de/mrbesen/telegram/WebhookTelegramAPI.java b/src/main/java/de/mrbesen/telegram/WebhookTelegramAPI.java index 68d0f3c..8e73218 100644 --- a/src/main/java/de/mrbesen/telegram/WebhookTelegramAPI.java +++ b/src/main/java/de/mrbesen/telegram/WebhookTelegramAPI.java @@ -1,16 +1,15 @@ package de.mrbesen.telegram; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +import org.json.JSONObject; + import java.io.IOException; import java.net.InetSocketAddress; import java.nio.charset.Charset; import java.util.Random; -import org.json.JSONObject; - -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; -import com.sun.net.httpserver.HttpServer; - //for https server: https://stackoverflow.com/questions/2308479/simple-java-https-server //for jks store: https://stackoverflow.com/questions/2138940/import-pem-into-java-key-store public class WebhookTelegramAPI extends TelegramAPI implements HttpHandler { @@ -47,7 +46,7 @@ public class WebhookTelegramAPI extends TelegramAPI implements HttpHandler { if(externaladdr.endsWith("/")) externaladdr = externaladdr.substring(0, externaladdr.length()-1); - request("setWebhook", "url=" + externaladdr + "/" + pw + "&allowed_updates=" + allowedupd); + request("setWebhook", "url=" + externaladdr + "/" + pw + "&allowed_updates=" + allowedupd, 0); } public WebhookTelegramAPI(String apikey, String externaladdr) throws IOException { diff --git a/src/main/java/de/mrbesen/telegram/event/events/NewUserEvent.java b/src/main/java/de/mrbesen/telegram/event/events/NewUserEvent.java new file mode 100644 index 0000000..d9643c8 --- /dev/null +++ b/src/main/java/de/mrbesen/telegram/event/events/NewUserEvent.java @@ -0,0 +1,12 @@ +package de.mrbesen.telegram.event.events; + +import de.mrbesen.telegram.objects.TUser; + +/** + * its not given that the user has never seen this bot, its just the first time since the last restart + */ +public class NewUserEvent extends UserEvent { + public NewUserEvent(TUser user) { + super(user); + } +} diff --git a/src/main/java/de/mrbesen/telegram/event/events/UserBlockedBotEvent.java b/src/main/java/de/mrbesen/telegram/event/events/UserBlockedBotEvent.java new file mode 100644 index 0000000..9a0ff52 --- /dev/null +++ b/src/main/java/de/mrbesen/telegram/event/events/UserBlockedBotEvent.java @@ -0,0 +1,9 @@ +package de.mrbesen.telegram.event.events; + +import de.mrbesen.telegram.objects.TUser; + +public class UserBlockedBotEvent extends UserEvent { + public UserBlockedBotEvent(TUser user) { + super(user); + } +} diff --git a/src/main/java/de/mrbesen/telegram/event/events/UserEvent.java b/src/main/java/de/mrbesen/telegram/event/events/UserEvent.java new file mode 100644 index 0000000..df2b360 --- /dev/null +++ b/src/main/java/de/mrbesen/telegram/event/events/UserEvent.java @@ -0,0 +1,12 @@ +package de.mrbesen.telegram.event.events; + +import de.mrbesen.telegram.event.Event; +import de.mrbesen.telegram.objects.TUser; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class UserEvent implements Event { + @Getter + private final TUser user; +} diff --git a/src/main/java/de/mrbesen/telegram/objects/TMessage.java b/src/main/java/de/mrbesen/telegram/objects/TMessage.java index 492d1d9..6927c2e 100644 --- a/src/main/java/de/mrbesen/telegram/objects/TMessage.java +++ b/src/main/java/de/mrbesen/telegram/objects/TMessage.java @@ -46,7 +46,7 @@ public class TMessage extends JSONBased { public static TMessage forward(TelegramAPI api, long userid, TMessage tmsg) { try { String fro = String.valueOf(tmsg.forward_from == null ? tmsg.from.getID() : tmsg.forward_from.getID()); - return new TMessage(api.request("forwardMessage", "chat_id=" + userid + "&from_chat_id=" + fro + "&message_id=" + tmsg.message_id).getJSONObject("result"), api); + return new TMessage(api.request("forwardMessage", "chat_id=" + userid + "&from_chat_id=" + fro + "&message_id=" + tmsg.message_id, userid).getJSONObject("result"), api); } catch (IOException | NullPointerException e) { e.printStackTrace(); } @@ -55,7 +55,7 @@ public class TMessage extends JSONBased { public static void forwardAsync(TelegramAPI api, long userid, TMessage tmsg) { String fro = String.valueOf(tmsg.forward_from == null ? tmsg.from.getID() : tmsg.forward_from.getID()); - api.request(new Task("forwardMessage", "chat_id=" + userid + "&from_chat_id=" + fro + "&message_id=" + tmsg.message_id)); + api.request(new Task("forwardMessage", "chat_id=" + userid + "&from_chat_id=" + fro + "&message_id=" + tmsg.message_id, userid)); } public TMessage(JSONObject json, TelegramAPI api) { @@ -150,10 +150,10 @@ public class TMessage extends JSONBased { public static void delete(TelegramAPI api, long chatid, int msgid, boolean async) { String q = "chat_id=" + chatid + "&message_id=" + msgid; if(async) { - api.requestAsync("deleteMessage", q); + api.requestAsync("deleteMessage", q, chatid); } else { try { - api.request("deleteMessage", q); + api.request("deleteMessage", q, chatid); } catch (IOException e) { e.printStackTrace(); } diff --git a/src/main/java/de/mrbesen/telegram/objects/TUser.java b/src/main/java/de/mrbesen/telegram/objects/TUser.java index 2f834cf..c74405e 100644 --- a/src/main/java/de/mrbesen/telegram/objects/TUser.java +++ b/src/main/java/de/mrbesen/telegram/objects/TUser.java @@ -1,12 +1,11 @@ package de.mrbesen.telegram.objects; -import lombok.Getter; -import org.json.JSONObject; - import de.mrbesen.telegram.AsyncHandler.Callback; import de.mrbesen.telegram.MessageBuilder; import de.mrbesen.telegram.MessageBuilder.Attachment; import de.mrbesen.telegram.TelegramAPI; +import lombok.Getter; +import org.json.JSONObject; public class TUser { @@ -93,7 +92,7 @@ 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(), ID); } catch (Exception e) { System.err.println("Failed to send status."); }