Come creare un plugin Slack in Java

Java Top

Ho appena annunciato il nuovo corso Learn Spring , incentrato sui fondamenti di Spring 5 e Spring Boot 2:

>> SCOPRI IL CORSO

1. Introduzione

Slack è un popolare sistema di chat utilizzato da persone e aziende in tutto il mondo. Una delle cose che lo rende così popolare è la possibilità di scrivere i nostri plugin personalizzati in grado di interagire con persone e canali all'interno di un singolo gioco. Questo utilizza la loro API HTTP.

Slack non offre un SDK ufficiale per la scrittura di plugin con Java. Tuttavia, esiste un SDK della community approvato ufficialmente che utilizzeremo. Questo ci dà accesso a quasi tutte le API Slack da una base di codice Java senza che dobbiamo preoccuparci dei dettagli esatti dell'API.

Lo utilizzeremo per creare un piccolo bot di monitoraggio del sistema. Ciò recupererà periodicamente lo spazio su disco per il computer locale e avviserà le persone se le unità si stanno riempiendo troppo.

2. Ottenere le credenziali API

Prima di poter fare qualsiasi cosa con Slack, dobbiamo creare una nuova App e un Bot e collegarli ai nostri canali .

In primo luogo, visitiamo //api.slack.com/apps. Questa è la base da cui gestiamo le nostre app Slack. Da qui possiamo creare una nuova app.

Quando lo facciamo, dobbiamo inserire un nome per l'app e un'area di lavoro Slack in cui crearla.

Una volta fatto ciò, l'app è stata creata ed è pronta per essere utilizzata. La schermata successiva ci permette di creare un Bot. Questo è un utente falso con cui agirà il plugin.

Come con qualsiasi utente normale, dobbiamo dare a questo un nome visualizzato e un nome utente. Queste sono le impostazioni che gli altri utenti nell'area di lavoro Slack vedranno per questo utente bot se interagiscono con esso.

Ora che abbiamo fatto ciò, possiamo selezionare "Installa App" dal menu laterale e aggiungere l'App nel nostro spazio di lavoro Slack . Una volta fatto ciò, l'app può interagire con il nostro spazio di lavoro.

Questo ci darà quindi i token di cui abbiamo bisogno per il nostro plugin per comunicare con Slack.

Ogni bot che interagisce con una diversa area di lavoro di Slack avrà un diverso set di token. La nostra applicazione necessita del valore "Bot User OAuth Access Token" per quando viene eseguita.

Infine, dobbiamo invitare il bot a tutti i canali in cui dovrebbe essere coinvolto . Funziona semplicemente inviandolo messaggi dal canale - @system_monitoring in questo caso.

3. Aggiunta di Slack al nostro progetto

Prima di poterlo utilizzare, dobbiamo prima aggiungere le dipendenze di Slack SDK al nostro file pom.xml :

 com.hubspot.slack slack-base ${slack.version}   com.hubspot.slack slack-java-client ${slack.version} 

3. Struttura dell'applicazione

Il cuore della nostra applicazione è la capacità di verificare la presenza di errori nel sistema. Lo rappresenteremo con il concetto di un controllo errori. Questa è una semplice interfaccia con un unico metodo, attivato per verificare la presenza di errori e segnalarli:

public interface ErrorChecker { void check(); }

Vogliamo anche avere i mezzi per segnalare eventuali errori riscontrati. Questa è un'altra semplice interfaccia che prenderà una dichiarazione del problema e la segnalerà in modo appropriato:

public interface ErrorReporter { void reportProblem(String problem); }

L'uso di un'interfaccia qui ci consente di avere diversi modi per segnalare i problemi. Ad esempio, potremmo averne uno che invia e-mail, contatta un sistema di segnalazione degli errori o invia messaggi al nostro sistema Slack per consentire alle persone di ricevere una notifica immediata.

Il design alla base di questo è che a ogni istanza ErrorChecker viene assegnato il proprio ErrorReporter da utilizzare. Questo ci dà la flessibilità di avere diversi reporter degli errori da utilizzare per diversi controllori perché alcuni errori potrebbero essere più importanti di altri. Ad esempio, se i dischi sono pieni per oltre il 90% che potrebbe richiedere un messaggio a un canale Slack, ma se sono pieni per oltre il 98%, potremmo invece voler inviare messaggi privati ​​a persone specifiche.

4. Controllo dello spazio su disco

Il nostro correttore di errori controllerà la quantità di spazio su disco sul sistema locale. Qualsiasi file system che ha meno di una particolare percentuale libera è considerato un errore e verrà segnalato come tale.

Faremo uso dell'API FileStore NIO2 introdotta in Java 7 per ottenere queste informazioni in modo multipiattaforma.

Ora, diamo un'occhiata al nostro controllo degli errori:

public class DiskSpaceErrorChecker implements ErrorChecker { private static final Logger LOG = LoggerFactory.getLogger(DiskSpaceErrorChecker.class); private ErrorReporter errorReporter; private double limit; public DiskSpaceErrorChecker(ErrorReporter errorReporter, double limit) { this.errorReporter = errorReporter; this.limit = limit; } @Override public void check() { FileSystems.getDefault().getFileStores().forEach(fileStore -> { try { long totalSpace = fileStore.getTotalSpace(); long usableSpace = fileStore.getUsableSpace(); double usablePercentage = ((double) usableSpace) / totalSpace; if (totalSpace > 0 && usablePercentage < limit) { String error = String.format("File store %s only has %d%% usable disk space", fileStore.name(), (int)(usablePercentage * 100)); errorReporter.reportProblem(error); } } catch (IOException e) { LOG.error("Error getting disk space for file store {}", fileStore, e); } }); } }

Qui, stiamo ottenendo l'elenco di tutti gli archivi di file sul sistema locale e quindi controlliamo ciascuno individualmente. Tutto ciò che ha meno del nostro limite definito come spazio utilizzabile genererà un errore utilizzando il nostro reporter degli errori.

5. Invio di errori ai canali Slack

Ora dobbiamo essere in grado di segnalare i nostri errori. Il nostro primo reporter sarà uno che invia messaggi a un canale Slack. Ciò consente a chiunque nel canale di vedere il messaggio, nella speranza che qualcuno reagisca ad esso.

Questo utilizza uno SlackClient , da Slack SDK, e il nome del canale a cui inviare i messaggi. Implementa anche la nostra interfaccia ErrorReporter in modo che possiamo collegarlo facilmente a qualsiasi verificatore di errori desideri utilizzarlo:

public class SlackChannelErrorReporter implements ErrorReporter { private SlackClient slackClient; private String channel; public SlackChannelErrorReporter(SlackClient slackClient, String channel) { this.slackClient = slackClient; this.channel = channel; } @Override public void reportProblem(String problem) { slackClient.postMessage( ChatPostMessageParams.builder() .setText(problem) .setChannelId(channel) .build() ).join().unwrapOrElseThrow(); } }

6. Cablaggio dell'applicazione

We are now in a position to wire up the application and have it monitor our system. For the sake of this tutorial, we're going to use the Java Timer and TimerTask that are part of the core JVM, but we could just as easily use Spring or any other framework to build this.

For now, this will have a single DiskSpaceErrorChecker that reports any disks that are under 10% usable to our “general” channel, and which runs every 5 minutes:

public class MainClass { public static final long MINUTES = 1000 * 60; public static void main(String[] args) throws IOException { SlackClientRuntimeConfig runtimeConfig = SlackClientRuntimeConfig.builder() .setTokenSupplier(() -> "") .build(); SlackClient slackClient = SlackClientFactory.defaultFactory().build(runtimeConfig); ErrorReporter slackChannelErrorReporter = new SlackChannelErrorReporter(slackClient, "general"); ErrorChecker diskSpaceErrorChecker10pct = new DiskSpaceErrorChecker(slackChannelErrorReporter, 0.1); Timer timer = new Timer(); timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { diskSpaceErrorChecker10pct.check(); } }, 0, 5 * MINUTES); } }

We need to replace “” with the token that was obtained earlier, and then we're ready to run. As soon as we do, if everything is correct, our plugin will check the local drives and message the Slack if there are any errors.

7. Sending Errors as Private Messages

Next, we're going to add an error reporter that sends private messages instead. This can be useful for more urgent errors since it will immediately ping a specific user instead of relying on someone in the channel to react.

Our error reporter here is more complicated because it needs to interact with a single, targeted user:

public class SlackUserErrorReporter implements ErrorReporter { private SlackClient slackClient; private String user; public SlackUserErrorReporter(SlackClient slackClient, String user) { this.slackClient = slackClient; this.user = user; } @Override public void reportProblem(String problem) { UsersInfoResponse usersInfoResponse = slackClient .lookupUserByEmail(UserEmailParams.builder() .setEmail(user) .build() ).join().unwrapOrElseThrow(); ImOpenResponse imOpenResponse = slackClient.openIm(ImOpenParams.builder() .setUserId(usersInfoResponse.getUser().getId()) .build() ).join().unwrapOrElseThrow(); imOpenResponse.getChannel().ifPresent(channel -> { slackClient.postMessage( ChatPostMessageParams.builder() .setText(problem) .setChannelId(channel.getId()) .build() ).join().unwrapOrElseThrow(); }); } }

What we have to do here is to find the user that we are messaging — looked up by email address, since this is the one thing that can't be changed. Next, we open an IM channel to the user, and then we post our error message to that channel.

This can then be wired up in the main method, and we will alert a single user directly:

ErrorReporter slackUserErrorReporter = new SlackUserErrorReporter(slackClient, "[email protected]"); ErrorChecker diskSpaceErrorChecker2pct = new DiskSpaceErrorChecker(slackUserErrorReporter, 0.02); timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { diskSpaceErrorChecker2pct.check(); } }, 0, 5 * MINUTES);

Once done, we can run this up and get private messages for errors as well.

8. Conclusion

Abbiamo visto qui come possiamo incorporare Slack nei nostri strumenti in modo da poter avere un feedback inviato all'intero team o ai singoli membri. C'è molto di più che possiamo fare con l'API Slack, quindi perché non vedere cos'altro possiamo incorporare.

Come al solito, il codice sorgente di questo articolo può essere trovato su GitHub.

Fondo Java

Ho appena annunciato il nuovo corso Learn Spring , incentrato sui fondamenti di Spring 5 e Spring Boot 2:

>> SCOPRI IL CORSO