import { Message, Helper, BotManager, User, IMessagingAdaptor, IMessageBus, IChannelProvider, IUserProvider } from "../Core"; var Rx = require("rx"); Rx.config.longStackSupport = true; var RtmClient = require("@slack/client").RtmClient; var CLIENT_EVENTS = require("@slack/client").CLIENT_EVENTS; var RTM_EVENTS = require("@slack/client").RTM_EVENTS; var assert = require("assert"); var Language = require("../Language").Language; export class SlackConnector implements IMessagingAdaptor, IMessageBus, IChannelProvider, IUserProvider { userProvider: IUserProvider; channelProvider: IChannelProvider; messageBus: IMessageBus; defaultChannel: string = "#general"; messages$: any; name: string; userId: string; observable: any; rtm: any; connected: boolean; timeout: number; constructor(botToken, connected) { this.messages$ = new Rx.Subject(); this.userProvider = this; this.channelProvider = this; this.messageBus = this; this.rtm = new RtmClient(botToken); this.name = null; this.userId = null; this.connected = false; this.timeout = 15000; this.rtm.on(CLIENT_EVENTS.RTM.AUTHENTICATED, rtmStartData => { this.name = "@" + rtmStartData.self.name; this.userId = rtmStartData.self.id; }); this.rtm.on(CLIENT_EVENTS.RTM.RTM_CONNECTION_OPENED, () => { this.connected = true; if (connected) connected(this); }); this.rtm.on(CLIENT_EVENTS.RTM.DISCONNECT, e => { this.connected = false; }); this.rtm.on(RTM_EVENTS.MESSAGE, incoming => { if (incoming.type == "message" && !incoming.subtype) { var user = this.rtm.dataStore.users[incoming.user]; var channel = this.rtm.dataStore.channels[incoming.channel]; var privateMessage = false; if (channel) { var channelName = "#" + channel.name; } else { privateMessage = true; var channelName = "@" + user.name; } var username = "@" + user.name; var msg: Message = { channel: channelName, user: { id: incoming.user, name: username, displayName: "<@" + incoming.user + ">" }, text: incoming.text, privateMessage: privateMessage }; this.messages$.onNext(msg); } }); this.rtm.start(); } // on(event: any) { // return Rx.Observable.create(o => { // this.rtm.on(event, incoming => { // var payload = new Message(); // if ( // event == Bot.Events.CHANNEL_JOINED || // event == Bot.Events.CHANNEL_LEFT // ) // payload.channel = this.getChannelId(incoming.channel.id); // if (payload) o.onNext(payload); // }); // }); // } getChannelId(name) { //todo handle private groups for (var p in this.rtm.dataStore.channels) { if (this.rtm.dataStore.channels[p].name == name) { return this.rtm.dataStore.channels[p].id; } } throw new Error("Unrecognised channel name: " + name); } getUserId(name) { for (var p in this.rtm.dataStore.users) { if (this.rtm.dataStore.users[p].name == name) { return this.rtm.dataStore.users[p].id; } } throw new Error("Unrecognised user: " + name); } getUsers(): User[]{ return null; } getUserById(id: string): User { for (var p in this.rtm.dataStore.users) { if (this.rtm.dataStore.users[p].id == id) { return { displayName: "<@" + this.rtm.dataStore.users[p].id + ">", name: "@" + this.rtm.dataStore.users[p].name, id: this.rtm.dataStore.users[p].id }; } } return null; } getChannels():string[] { return null; } say(where, text, user) { if (where.substring(0, 1) == "#") { var name = where.substring(1, where.length); var id = this.getChannelId(name); var userId: string = ""; if (user) { userId = user.id; //this.getUserId(user.substring(1, user.length)); text = "<@" + userId + "> " + text; } return new Promise((resolve, reject) => { this.rtm.sendMessage(text, id, (err, s) => { if (err) reject(err); else resolve(); }); }); } if (where.substring(0, 1) == "@") { var name = where.substring(1, where.length); userId = ""; for (var p in this.rtm.dataStore.users) { if (this.rtm.dataStore.users[p].name == name) { userId = this.rtm.dataStore.users[p].id; } } var dmId = ""; for (var p in this.rtm.dataStore.dms) { if (this.rtm.dataStore.dms[p].user == userId) { dmId = this.rtm.dataStore.dms[p].id; } } this.rtm.sendMessage(text, dmId); } } }