327 lines
8.0 KiB
Java
327 lines
8.0 KiB
Java
package de.mrbesen.telegram;
|
|
|
|
import java.io.IOException;
|
|
import java.io.OutputStreamWriter;
|
|
import java.net.URL;
|
|
import java.util.LinkedList;
|
|
import java.util.Scanner;
|
|
|
|
import javax.net.ssl.HttpsURLConnection;
|
|
|
|
import org.json.JSONArray;
|
|
import org.json.JSONObject;
|
|
|
|
import de.mrbesen.telegram.MessageBuilder.SendableMessage;
|
|
import de.mrbesen.telegram.commands.CommandManager;
|
|
import de.mrbesen.telegram.event.Event;
|
|
import de.mrbesen.telegram.event.EventManager;
|
|
import de.mrbesen.telegram.event.events.UserSendAudioEvent;
|
|
import de.mrbesen.telegram.event.events.UserSendMessageEvent;
|
|
import de.mrbesen.telegram.log.Log;
|
|
import de.mrbesen.telegram.log.Log4JLog;
|
|
import de.mrbesen.telegram.log.SimpleLog;
|
|
import de.mrbesen.telegram.objects.JSONBased.Member;
|
|
import de.mrbesen.telegram.objects.TAudio;
|
|
import de.mrbesen.telegram.objects.TMessage;
|
|
import de.mrbesen.telegram.objects.TUser;
|
|
import de.mrbesen.telegram.objects.TUser.Status;
|
|
|
|
public class TelegramAPI implements Runnable {
|
|
|
|
private static final String API_URL = "https://api.telegram.org/bot";
|
|
private static final String TOKENREGEX = "^\\d{4,9}:[\\w-]{12,64}$";
|
|
public static final String APIVERSION = "3.6";//February 13, 2018
|
|
|
|
private int msg_offset = 0;
|
|
private int updateInterval = 1500;
|
|
private String apikey;
|
|
private Thread thread;
|
|
private boolean run = true;
|
|
private String helpmessage = "generic helppage\nuse TelegramAPI.setHelpText(java.lang.String) to change this.";
|
|
|
|
private LinkedList<TUser> users = new LinkedList<>();
|
|
private CommandManager cmdmgr = new CommandManager();
|
|
private EventManager evntmgr = new EventManager();
|
|
//Log log = new SimpleLog();
|
|
Log log = new Log4JLog();
|
|
|
|
public TelegramAPI(String apikey) {
|
|
if (!apikey.matches(TOKENREGEX) ) {
|
|
throw new IllegalArgumentException("Invalid API key");
|
|
}
|
|
this.apikey = apikey;
|
|
}
|
|
|
|
public void start() {
|
|
if(thread == null) {
|
|
run = true;
|
|
thread = new Thread(this, "TelegramAPI");
|
|
thread.start();
|
|
} else {
|
|
throw new IllegalStateException("Still Running.");
|
|
}
|
|
}
|
|
|
|
public JSONObject request(String request, String parameter) throws IOException {
|
|
//do https stuff
|
|
URL url = new URL(API_URL + apikey + "/" + request);
|
|
HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
|
|
con.setDoInput(true);
|
|
con.setDoOutput(true);
|
|
OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream());
|
|
wr.write(parameter);
|
|
wr.flush();
|
|
log.log( "request: " + request + " content " + parameter + " -> " + con.getResponseCode() + ", " + con.getResponseMessage());
|
|
if(con.getResponseCode() == 200) {
|
|
Scanner s = new Scanner(con.getInputStream());
|
|
StringBuilder sb_apianswer = new StringBuilder();
|
|
while(s.hasNextLine()) {
|
|
sb_apianswer.append(s.nextLine()).append('\n');
|
|
}
|
|
s.close();
|
|
|
|
return new JSONObject(sb_apianswer.toString());
|
|
} else {
|
|
throw new IOException("API request returned HTTP " + con.getResponseCode() + " (" + con.getResponseMessage() + ") for action " + request );
|
|
}
|
|
}
|
|
|
|
public TMessage sendMessage(TUser user, String text) {
|
|
MessageBuilder builder = new MessageBuilder();
|
|
builder.setReciver(user.getID());
|
|
builder.setText(text);
|
|
return sendMessage(builder.build());
|
|
}
|
|
|
|
public TMessage sendMessage(SendableMessage msg) {
|
|
try {
|
|
JSONObject o = request("sendMessage", msg.getQ());
|
|
return new TMessage(o.getJSONObject("result"), this);
|
|
} catch(IOException e) {
|
|
log.log("",e);
|
|
}
|
|
return null;
|
|
}
|
|
public void sendTypedMessage(final String msg, final TUser user, final int seconds) {
|
|
new Thread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
user.sendStatus(Status.Typing);
|
|
try {
|
|
Thread.sleep(seconds*1000);
|
|
} catch (InterruptedException e) {
|
|
}
|
|
sendMessage(new MessageBuilder().setText(msg).setReciver(user.getID()).build());
|
|
|
|
}
|
|
}).start();
|
|
}
|
|
|
|
public void stop() {
|
|
run = false;
|
|
thread.interrupt();
|
|
Thread.yield();//try to not get into that loop
|
|
while(isRunning()) {
|
|
thread.interrupt();
|
|
Thread.yield();
|
|
try {
|
|
Thread.sleep(10);
|
|
} catch(InterruptedException e) {}
|
|
}
|
|
log.log("tapi stoped.");
|
|
thread = null;
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
while(run) {
|
|
fetchUpdates();
|
|
try {
|
|
Thread.sleep(updateInterval);
|
|
} catch (InterruptedException e) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public boolean isRunning() {
|
|
return thread.isAlive();
|
|
}
|
|
|
|
private void fetchUpdates() {
|
|
try {
|
|
processUpdates(request("getUpdates", "offset=" + msg_offset));
|
|
} catch (IOException e) {
|
|
log.log("error getting updates.", e);
|
|
}
|
|
}
|
|
|
|
private void processUpdates(JSONObject object) {
|
|
if(object == null)
|
|
return;
|
|
JSONArray arr_results = object.getJSONArray("result");
|
|
for(int i = 0; !arr_results.isNull(i); i++) {
|
|
JSONObject entry = arr_results.getJSONObject(i);
|
|
TelegramAPIUpdate upd = new TelegramAPIUpdate(entry, this);
|
|
msg_offset = (upd.update_id+1 > msg_offset ? upd.update_id+1 : msg_offset);
|
|
}
|
|
}
|
|
|
|
public TUser getUser(String name) {
|
|
for(TUser us : users) {
|
|
if(us.getName().equals(name))
|
|
return us;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public TUser getUser(int id) {
|
|
for(TUser us : users) {
|
|
if(us.getID() == id)
|
|
return us;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* gets a user by id from the known user lists,
|
|
* if no user found, it creates a new User and adds it to the list.
|
|
* @param json
|
|
* @return
|
|
*/
|
|
public TUser getUser(JSONObject json) {
|
|
int id = json.getInt("id");
|
|
TUser user = getUser(id);
|
|
if(user != null)
|
|
return user;
|
|
user = new TUser(json, this);
|
|
users.add(user);
|
|
return user;
|
|
}
|
|
|
|
public void setHelpText(String helptext) {
|
|
helpmessage = ( helptext == null ? "" : helptext);
|
|
}
|
|
|
|
/**
|
|
* Set the logging method, use {@link Log4JLog} for usage of LOG4J,
|
|
* or {@link SimpleLog} for usage of System.out.println();
|
|
* use Null t odisable logging the default is {@link SimpleLog}
|
|
* @param l
|
|
*/
|
|
public void setLog(Log l) {
|
|
if(l == null)
|
|
log = new Log();
|
|
else
|
|
log = l;
|
|
}
|
|
|
|
public CommandManager getCommandManager() {
|
|
return cmdmgr;
|
|
}
|
|
|
|
public EventManager getEventManager() {
|
|
return evntmgr;
|
|
}
|
|
|
|
public void setUpdateInterval(int d) {
|
|
if(d < 0)
|
|
throw new IllegalArgumentException("UpdateInterval is not allowed to be negative.");
|
|
updateInterval = d;
|
|
}
|
|
|
|
public String getHelpMessage() {
|
|
return helpmessage;
|
|
}
|
|
|
|
public int getupdateInterval() {
|
|
return updateInterval;
|
|
}
|
|
|
|
protected class TelegramAPIUpdate {
|
|
protected int update_id = 0;
|
|
private TMessage msg = null;
|
|
private boolean isCommand = false;
|
|
|
|
protected TelegramAPIUpdate(JSONObject json, TelegramAPI api) {
|
|
update_id = json.getInt("update_id");
|
|
|
|
if(json.has("message")) {
|
|
msg = new TMessage(json.getJSONObject("message"), api);
|
|
|
|
String text = msg.getText();
|
|
if(text != null) {
|
|
if(text.startsWith("/" )) {
|
|
text = text.substring(1);//remove '/'
|
|
isCommand = true;
|
|
cmdmgr.onCommand(text, msg.getFrom(), json.getJSONObject("message"));
|
|
} else {
|
|
Event e = null;
|
|
if(getMsg().has(Member.audio)) {
|
|
e = new UserSendAudioEvent(getUser(), new TAudio((JSONObject) getMsg().get(Member.audio)));
|
|
} else if(getMsg().has(Member.video)) {
|
|
|
|
} else if(getMsg().has(Member.document)) {
|
|
|
|
} else if(getMsg().has(Member.invoice)) {
|
|
|
|
} else if(getMsg().has(Member.location)) {
|
|
|
|
} else if(getMsg().has(Member.video_note)) {
|
|
|
|
} else if(getMsg().has(Member.game)) {
|
|
|
|
} else if(getMsg().has(Member.contact)) {
|
|
|
|
} else if(getMsg().has(Member.sticker)) {
|
|
|
|
} else {
|
|
e = new UserSendMessageEvent(getMsg());
|
|
}
|
|
getEventManager().callEvent(e);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected int getUpdate_id() {
|
|
return update_id;
|
|
}
|
|
|
|
protected TMessage getMsg() {
|
|
return msg;
|
|
}
|
|
|
|
protected TUser getUser() {
|
|
return msg.getFrom();
|
|
}
|
|
|
|
protected boolean isCommand() {
|
|
return isCommand;
|
|
}
|
|
}
|
|
|
|
public enum JSONObjectType {
|
|
User,
|
|
Chat,
|
|
Message,
|
|
MessageEntity,
|
|
Audio,
|
|
Document,
|
|
Game,
|
|
Sticker,
|
|
Video,
|
|
Voice,
|
|
Videonote,
|
|
Location,
|
|
Venue,
|
|
Contact;
|
|
|
|
boolean isArray = false;
|
|
void setArray(boolean b) {
|
|
isArray = b;
|
|
}
|
|
}
|
|
|
|
}
|