!7 lib 1400206 // jSlack 1.4.2 (fat jar) import com.github.seratch.jslack.*; import com.github.seratch.jslack.api.rtm.*; import com.github.seratch.jslack.api.model.User; import com.github.seratch.jslack.api.methods.request.users.*; import com.github.seratch.jslack.api.methods.request.chat.*; import com.github.seratch.jslack.api.methods.response.chat.*; import com.github.seratch.jslack.api.methods.response.users.*; static Slack slack; sbool slackDump = true; // no cmodule because of doPost / loadPage module SlackModule > DynPrintLogAndEnabled { switchable S token; S botID; transient new ThreadLocal msgJSON; transient RTMClient rtm; start { if (!enabled) ret with print("Not enabled"); vm_cleanPrints(); // avoid Swing Unicode problem logModuleOutput(); // good idea for chat bots dm_registerAs('slackModule); if (nempty(token)) ret with startSlack(); inputText("Please enter Slack bot token", voidfunc(S s) { setField(token := s); startSlack(); }); } void startSlack enter { ownResource(rtm = initSlackBot()); } void getMyOwnUserInfo() ctex { User botUser = rtm.getConnectedBotUser(); UsersInfoResponse response = slack.methods().usersInfo( UsersInfoRequest.builder().token(token).user(botUser.getId()) .build()); //print(response); setField(botID := response.getUser().getProfile().getBotId()); print("My bot ID: " + botID); } RTMClient initSlackBot() ctex { if (slack != null) fail("Slack already started"); fixContextClassLoader(); slack = new Slack; RTMClient rtm = slack.rtm(token); rtm.addErrorHandler(error -> { print("Got Slack error: " + error); appendToTextFile("slack-errors.txt", "\n " + getStackTrace(error) + "\n"); print("...reconnecting to be sure."); thread "Reconnect to Slack" { fixContextClassLoader(); pcall { rtm.disconnect(); } print("Disconnected (hopefully)"); print("Waiting 10, then reconnecting."); sleepSeconds(10); print("Reconnecting to Slack"); try { rtm.connect(); print("Done"); } catch e { printStackTrace(e); print("Connect failed, restarting module."); dm_reloadModule(); } } }); rtm.addMessageHandler((message) -> { temp enter(); Map json = jsonDecodeMap(message); if (slackDump) pnlStruct(json); if (eq(json.get("type"), "hello")) pcall { vmBus_send('slackConnected, this); getMyOwnUserInfo(); } if (eq(json.get("type"), "message")) pcall { bool bot = eq(json.get("subtype"), "bot_message"); S channelID = cast json.get("channel"); S ts = cast json.get("ts"); S text = cast json.get("text"); vmBus_send('incomingSlackMessage, litmapparams( token := shorten(token, 10), myBotID := botID, module := dm_moduleID(), fromBot := bot, msgID := ts, +channelID, content := text, +json /*+isPrivate*/)); } }); // must connect within 30 seconds after issuing wss endpoint rtm.connect(); print("Slack connect initiated"); ret rtm; } }