My last post focussed on a thread-blocking rate-limiter for a Telegram Bot API framework I'm building. For this framework, I needed a way to make sending GET and POST requests very simple. If you look up any Java code snippets that do not require external libraries for making a simple GET request, you may see that this isn't exactly a neat and compact task. If you want to do more complex stuff, the code gets messy very quickly. Especially if you want to send POST requests with
Content-Type: multipart/formdata, which is a complex way of saying you want to be able to upload files to a server. That's why I wrote a little library that hides the details and offers a simple interface.
My design goals where as follows:
- No external libraries. The less dependencies, the better.
- Simple interface. I don't need to know about complexity that I don't care about as a user.
- As few method calls as possible for the user. If I want to make just one request, I only want to call one method.
- No callbacks. I will be making my API calls from various threads so I intend to just block the thread until I receive a response. A typical HTTP request takes a few hundred milliseconds, so this is acceptable to me.
- I need some control over the timeout limits for making a connection and maintaining a connection because I intend to use long polling for receiving the updates.
- Modular code. No dependencies regarding the framework, so I can re-use it in other projects.
I had to re-write almost everything from scratch just after I finished. Eclipse decided to delete all my files while I was doing final refactoring. It offered me to undo 'my' mistake, but then couldn't find the files and just froze. The files were gone. Since it was only about 700 lines of code at that point, it took me just a little over an hour to reproduce it from memory. I have never seen Eclipse do anything like this, but I've had it running continiously for several days. I guess I learned why version management is important, even when you're not getting paid to keep your project management in order.
Code? Did you say CODE!?
The code is available on my Github profile. The README file contains some useful examples, but to illustrate how it applies to the framework, here are some specific examples to Telegram bots. Note that the API token I'm using here is the example token from the API documentation, so don't waste your time trying to use it.
NB: I have left out a bit of exception handling to make the code snippets more readable.
Example: Sending a text message to a chat
The code snippet below sends a text message saying
Hello, world! to the chat with ID
By the way, if you need the ID of any chat, just add my bot @GetMyIDBot to the chat or forward a message from a specific chat to it. It will reply with a message containing the information you requested.
Connection con = new HttpsConnection("api.telegram.org"); String basepath = "bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11/"; Map<String, String> fields = new HashMap<String, String>(); fields.put("chat_id", "1234567890"); fields.put("text", "Hello, world!"); con.post(basepath + "sendMessage", fields);
Example: Sending a photo to a channel
The code snippet below sends a photo to a Telegram channel named
@ExampleChannel, with a caption saying
What a lovely photo!.
Connection con = new HttpsConnection("api.telegram.org"); String basepath = "bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11/"; Map<String, String> fields = new HashMap<String, String>(); fields.put("chat_id", "@ExampleChannel"); fields.put("caption", "What a lovely photo!"); byte photoBytes = Files.readAllBytes(Paths.get("photo.jpg")); InputFile photoFile = new InputFile("photo.jpg", "image/jpg", photoBytes); con.post(basepath + "sendPhoto", fields, "photo", photoFile);
As you can see, sending requests is pretty simple, even if they're as complex as a