--Mastodon seems to be able to Toot from his own code like Twitter --It seems that Python and Ruby have libraries, but I can't find Java. ――When I tried to beat it, I was able to stream Toot and Union TL
There seems to be an easy library to play with the REST API called Jersey, so I used it. To be honest, I tried to stick them together properly, so I'm messing around without knowing the details.
The connection instance is mstdn.jp, and the client id / secret and personal access token are prepared in advance with the help of Mastodon.py. (Since it was troublesome to write the authentication code ... I will try it someday) It seems that Streaming connection and Toot itself can be done with an access token.
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import org.glassfish.jersey.media.sse.EventInput;
import org.glassfish.jersey.media.sse.InboundEvent;
import org.glassfish.jersey.media.sse.SseFeature;
public class MainWindow extends JFrame{
private static final String APP_NAME = "TestMastodonClient";
private static final int APP_WIDTH = 640;
private static final int APP_HEIGHT = 480;
//For the time being mstdn.I did it with jp, change it appropriately when doing it with other instances
private static final String HOST_MASTODON = "https://mstdn.jp";
//Client id in advance/Get secret and access token(I'm Mastodon.I did it with py)
private static final String MASTODON_ACCESSTOKEN_TOKEN = "Put your own Access Token here";
JComboBox<String> visibilityComboBox; //Scope of posting
JTextField tootField;
JButton tootButton;
Client client;
public MainWindow() {
setTitle(APP_NAME);
setSize(APP_WIDTH, APP_HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// TLSv1.I couldn't connect to Streaming without using 2, so I changed it.
System.out.println("HTTPS:" + System.getProperty("https.protocols"));
System.setProperty("https.protocols", "TLSv1.2");
System.out.println("HTTPS:" + System.getProperty("https.protocols"));
client = ClientBuilder.newBuilder().register(SseFeature.class).build();
Container container = getContentPane();
JPanel parentPanel = new JPanel();
container.add(parentPanel);
visibilityComboBox = new JComboBox<String>();
visibilityComboBox.addItem("public"); //Release(Come out in Union TL)
visibilityComboBox.addItem("unlisted");//Release(Does not appear in Union TL)
visibilityComboBox.addItem("private"); //private(I can only see myself and my followers)
visibilityComboBox.addItem("direct"); //I do not understand(Is it like Twitter DM?)
parentPanel.add(visibilityComboBox);
tootField = new JTextField(10); //Defeat Toot For character string input
parentPanel.add(tootField);
tootButton = new JButton("Toot");
tootButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
String msg = tootField.getText();
System.out.println("Toot: " + msg);
//It seems to make a header with Access Token
MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
headers.putSingle("Authorization", "Bearer " + MASTODON_ACCESSTOKEN_TOKEN);
//Put the text in status and the disclosure range of posts in visibility
Entity<Form> entity = Entity.entity(new Form().param("status", msg)
.param("visibility",
(String) visibilityComboBox.getSelectedItem()),
MediaType.APPLICATION_FORM_URLENCODED_TYPE);
//throw
String result = client.target(HOST_MASTODON)
.path("/api/v1/statuses")
.request()
.headers(headers)
.post(entity, String.class);
System.out.println("----------Execution result----------");
System.out.println(result);
//tootField.setText(""); //If you want to empty the input field after Toot, do it
}
});
parentPanel.add(tootButton);
//I don't know if this is okay, but for the time being, I picked up Streaming in another thread
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("----------Streaming Thread----------");
//Prepare Access Token
MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
headers.putSingle("Authorization", "Bearer " + MASTODON_ACCESSTOKEN_TOKEN);
headers.putSingle("Content-Type", "application/json; charset=UTF-8");
WebTarget target = client.target(HOST_MASTODON);
//Connect to Union TL
EventInput eventInput = target.path("/api/v1/streaming/public")
.request()
.headers(headers)
.get(EventInput.class);
//Just let the console keep receiving
//JSON A decent string comes out so I have to parse it later
while (!eventInput.isClosed()) {
final InboundEvent inboundEvent = eventInput.read();
if (inboundEvent == null) {
// connection has been closed
System.out.println("----------End of Streaming Thread----------");
break;
}
System.out.println("----------Response----------");
System.out.println(inboundEvent.getName() + "; ");
System.out.println(inboundEvent.readData(String.class));
}
}
}).start();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new MainWindow().setVisible(true);
}
});
}
}
When you receive the Union TL, it will flow at a tremendous momentum, so it may be easier to confirm if you try it with Home TL. Addendum: ~~ While continuing to pick up Streaming JSON in Thread at the end of the above code, [15.5.2. Asynchronous SSE processing with EventSource](https://jersey.java.net/documentation/latest/ As shown in sse.html # d0e12060), it seems that it can be defined as onEvent, so that seems to be better ~~ As a result of searching variously, EventSource seems to be unable to connect with a request header so far, so either write the code to generate an event from the above While, or write the code to put the header with AccessToken in EventSource somehow. It seems that it will correspond
Recommended Posts