2121import java .net .http .HttpRequest ;
2222import java .net .http .HttpResponse ;
2323import java .nio .charset .StandardCharsets ;
24- import java .util .HashMap ;
25- import java .util .List ;
26- import java .util .Map ;
27- import java .util .Set ;
24+ import java .util .*;
25+ import java .util .concurrent .CompletableFuture ;
2826import java .util .function .Predicate ;
2927import java .util .regex .Pattern ;
3028
3129/**
3230 * Listener that receives all sent help messages and uploads them to a share service if the message
3331 * contains a file with the given extension in the
34- * {@link FileSharingMessageListener#extensionFilter}
32+ * {@link FileSharingMessageListener#extensionFilter}.
3533 */
3634public class FileSharingMessageListener extends MessageReceiverAdapter {
3735
@@ -69,30 +67,42 @@ public void onMessageReceived(@NotNull MessageReceivedEvent event) {
6967 return ;
7068 }
7169
72- List <Message .Attachment > attachments =
73- event .getMessage ().getAttachments ().stream ().filter (attachment -> {
74- String extension = attachment .getFileExtension ();
75- if (extension == null ) {
76- return false ;
77- }
78- return extensionFilter .contains (extension );
79- }).toList ();
8070
81- processAttachments (event , attachments );
71+ List <Message .Attachment > attachments = event .getMessage ()
72+ .getAttachments ()
73+ .stream ()
74+ .filter (this ::isAttachmentRelevant )
75+ .toList ();
76+
77+ CompletableFuture .runAsync (() -> processAttachments (event , attachments ));
78+ }
79+
80+ private boolean isAttachmentRelevant (@ NotNull Message .Attachment attachment ) {
81+ String extension = attachment .getFileExtension ();
82+ if (extension == null ) {
83+ return false ;
84+ }
85+ return extensionFilter .contains (extension );
8286 }
8387
88+
8489 private void processAttachments (@ NotNull MessageReceivedEvent event ,
8590 @ NotNull List <Message .Attachment > attachments ) {
86- Map <String , GistFile > filesAsJson = new HashMap <>();
8791
92+ Map <String , GistFile > filesAsJson = Collections .synchronizedMap (new HashMap <>());
93+
94+ List <CompletableFuture <Void >> tasks = new ArrayList <>();
8895 for (Message .Attachment attachment : attachments ) {
89- attachment .retrieveInputStream ()
96+ CompletableFuture < Void > task = attachment .retrieveInputStream ()
9097 .thenApply (this ::readAttachment )
91- .thenAccept (content -> filesAsJson .put (createFileName (attachment ),
92- new GistFile (content )))
93- .join ();
98+ .thenAccept (
99+ content -> filesAsJson .put (getNameOf (attachment ), new GistFile (content )));
100+
101+ tasks .add (task );
94102 }
95103
104+ tasks .forEach (CompletableFuture ::join );
105+
96106 GistFiles files = new GistFiles (filesAsJson );
97107 GistRequest request = new GistRequest (event .getAuthor ().getName (), false , files );
98108 String url = uploadToGist (request );
@@ -107,7 +117,7 @@ private void processAttachments(@NotNull MessageReceivedEvent event,
107117 }
108118 }
109119
110- private @ NotNull String createFileName (@ NotNull Message .Attachment attachment ) {
120+ private @ NotNull String getNameOf (@ NotNull Message .Attachment attachment ) {
111121 String fileName = attachment .getFileName ();
112122 String fileExtension = attachment .getFileExtension ();
113123
@@ -126,13 +136,14 @@ private void processAttachments(@NotNull MessageReceivedEvent event,
126136 try {
127137 body = JSON .writeValueAsString (jsonRequest );
128138 } catch (JsonProcessingException e ) {
129- throw new IllegalStateException ("Couldn't parse json request!" , e );
139+ throw new IllegalStateException (
140+ "Attempting to upload a file to gist, but unable to create the JSON request." ,
141+ e );
130142 }
131143
132144 HttpRequest request = HttpRequest .newBuilder ()
133145 .uri (URI .create (SHARE_API ))
134- .header ("Accept" , "application/json" )
135- .header ("Authorization" , "token " + gistApiKey )
146+ .headers ("Accept" , "application/json" , "Authorization" , "token " + gistApiKey )
136147 .POST (HttpRequest .BodyPublishers .ofString (body ))
137148 .build ();
138149
@@ -143,7 +154,8 @@ private void processAttachments(@NotNull MessageReceivedEvent event,
143154 throw new UncheckedIOException (e );
144155 } catch (InterruptedException e ) {
145156 Thread .currentThread ().interrupt ();
146- throw new IllegalStateException ("HttpResponse interrupted!" , e );
157+ throw new IllegalStateException (
158+ "Attempting to upload a file to gist, but the request got interrupted." , e );
147159 }
148160
149161 int statusCode = apiResponse .statusCode ();
@@ -157,17 +169,18 @@ private void processAttachments(@NotNull MessageReceivedEvent event,
157169 try {
158170 gistResponse = JSON .readValue (apiResponse .body (), GistResponse .class );
159171 } catch (JsonProcessingException e ) {
160- throw new IllegalStateException ("Couldn't parse response!" , e );
172+ throw new IllegalStateException (
173+ "Attempting to upload file to gist, but unable to parse its JSON response." , e );
161174 }
162175 return gistResponse .getHtmlUrl ();
163176 }
164177
165178 private void sendResponse (@ NotNull MessageReceivedEvent event , @ NotNull String url ) {
166179 Message message = event .getMessage ();
167- String replyContent =
168- "I uploaded your file(s) as gist, it is much easier to read for everyone like that , especially for mobile users" ;
180+ String messageContent =
181+ "I uploaded your attachments as ** gist**. That way, they are easier to read for everyone, especially mobile users 👍 " ;
169182
170- message .reply (replyContent ).setActionRow (Button .link (url , "gist" )).queue ();
183+ message .reply (messageContent ).setActionRow (Button .link (url , "gist" )).queue ();
171184 }
172185
173186 private boolean isHelpThread (@ NotNull MessageReceivedEvent event ) {
0 commit comments