Last active
January 10, 2018 19:51
-
-
Save eknowlton/010c008773ecacc53da3 to your computer and use it in GitHub Desktop.
ReactJS Chat integration with Slack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define(['react', 'jquery', 'moment'], function(React, jquery, moment) { | |
var ChatApp = { | |
users: [], | |
user: [], | |
messageCount: 0, | |
channel: [], | |
Message: React.createClass({ | |
render: function () { | |
if(this.props.status == 'visible'){ | |
messageClass = 'message messageVisible'; | |
}else{ | |
messageClass = 'message messagePending'; | |
} | |
if(this.props.ts){ | |
var date = moment.unix(this.props.ts).format("h:mm:ss a"); | |
} | |
return ( | |
<div className={messageClass} data-message-id={this.props.id}> | |
<img src={this.props.img} /> | |
<span><strong>{this.props.name}</strong> <small> {date}</small></span> | |
<div className='messageText'> {this.props.children} </div> | |
</div> | |
); | |
} | |
}), | |
MessageList: React.createClass({ | |
componentDidUpdate: function(){ | |
var messageListNode = React.findDOMNode(this.refs.messageList); | |
var $messageListNode = $(messageListNode); | |
var scrollheight = $messageListNode[0].scrollHeight; | |
$messageListNode.scrollTop(scrollheight); | |
}, | |
render: function () { | |
var messages = this.props.data.map(function (message) { | |
return ( | |
<ChatApp.Message name={message.name} key={message.id} id={message.id} status={message.status} ts={message.ts} img={message.img}> | |
{message.text} | |
</ChatApp.Message> | |
); | |
}); | |
return ( | |
<div className='messageList' ref='messageList'> | |
<div className='alert alert-success'>Welcome to Reporting support. Please use this chat for issues you experience with Reporting.</div> | |
{messages} | |
</div> | |
); | |
} | |
}), | |
MessageForm: React.createClass({ | |
handleSubmit: function(e){ | |
e.preventDefault(); | |
var text = React.findDOMNode(this.refs.message).value.trim(); | |
if (!text) { | |
return; | |
} | |
ChatApp.messageCount++; | |
var messageSendData = { | |
"id": ChatApp.messageCount, | |
"type": "message", | |
"channel": ChatApp.channel.id, | |
"text": text | |
}; | |
ChatApp.socket.send(JSON.stringify(messageSendData)); | |
this.props.onMessageSubmit({text: text, id: ChatApp.messageCount}); | |
React.findDOMNode(this.refs.message).value = ''; | |
return; | |
}, | |
componentDidMount: function(){ | |
var text = $(React.findDOMNode(this.refs.message)).on('keydown', function(e){ | |
if (e.keyCode == 13) { | |
$(React.findDOMNode(this.refs.messageSubmitForm)).submit(); | |
} | |
}.bind(this)); | |
}, | |
render: function () { | |
if(this.props.socketState){ | |
textarea = ( <input type='text' className='messageInput input-block-level' ref='message' /> ); | |
}else{ | |
textarea = ( <input type='text' className='messageInput input-block-level' ref='message' disabled='disabled' /> ); | |
} | |
return ( | |
<div className='messageForm'> | |
<form onSubmit={this.handleSubmit} className='form-inline' refs='messageSubmitForm'> | |
{textarea} | |
</form> | |
</div> | |
); | |
} | |
}), | |
ChatBox: React.createClass({ | |
getInitialState: function() { | |
return {messages: [], socket: false}; | |
}, | |
componentDidMount: function() { | |
if(window.appConfig.slackToken){ | |
$.get( 'https://slack.com/api/channels.join' ,{ | |
token: window.appConfig.slackToken, | |
name: 'allboutmoney' | |
}).done(function(data){ | |
if(data.ok) { | |
ChatApp.channel = data.channel; | |
$.get('https://slack.com/api/rtm.start?token=' + window.appConfig.slackToken) | |
.done(function (data) { | |
if (data.ok) { | |
ChatApp.socket = new WebSocket(data.url); | |
this.getUserInfo(data.self.id, function(user){ | |
ChatApp.user = user; | |
}); | |
// Open the socket | |
ChatApp.socket.onopen = function (event) { | |
this.setState({message: [], socket: true}); | |
ChatApp.socket.onmessage = function (event) { | |
this.messageRecieve(event.data); | |
}.bind(this); | |
ChatApp.socket.onclose = function (event) { | |
console.log('The client has disconnected!'); | |
}; | |
}.bind(this); | |
} else { | |
alert('An error has occured. ( JS Error 4 )'); | |
} | |
}.bind(this)).fail(function () { | |
console.log('Failed'); | |
}); | |
}else{ | |
alert('An error occured. ( JS Error 5 ) '); | |
} | |
}.bind(this)).fail(function(){ | |
alert('An error occured. ( JS Error 6 ) '); | |
}.bind(this)); | |
}else{ | |
$(document).on('click', this.refs.linkAccount.getDOMNode(), function(){ | |
window.location = 'https://slack.com/oauth/authorize?client_id=' + encodeURIComponent(window.appConfig.slackClientId) + '&redirect_uri=' + encodeURIComponent(window.appConfig.slackRedirectUri) + '&state=' + encodeURIComponent(window.appConfig.slackState) + '&team=T03L85TS3&scope=client'; | |
}.bind(this)); | |
} | |
}, | |
getUserInfo: function(userid, finished){ | |
if(ChatApp.users[userid] == undefined) { | |
$.get('https://slack.com/api/users.info', { | |
token: window.appConfig.slackToken, | |
user: userid | |
}).success(function (data) { | |
if (data.ok) { | |
ChatApp.users[userid] = data.user; | |
finished(data.user); | |
} else { | |
alert('An error has occurred. ( JS Error 2 ) '); | |
} | |
}).error(function () { | |
alert('An error has occurred. ( JS Error 1 ) '); | |
}); | |
}else{ | |
finished(ChatApp.users[userid]); | |
} | |
}, | |
handleSubmit: function(e){ | |
e.preventDefault(); | |
var Messages = this.state.messages; | |
var text = React.findDOMNode(this.refs.message).value.trim(); | |
Messages.push({name: ChatApp.user.name, text: text}); | |
this.setState({messages: Messages}); | |
}, | |
messageRecieve: function(data){ | |
message = JSON.parse(data); | |
console.log('messageReceive: ', message); | |
var Messages = this.state.messages; | |
// only show messages from this channel | |
if(message.channel == ChatApp.channel.id && message.type == 'message' && !message.subtype) { | |
var Messages = this.state.messages; | |
this.getUserInfo(message.user, function(user){ | |
Messages.push({name: user.name, text: message.text, id: message.ts, status: "visible", ts: message.ts, img: user.profile.image_24}); | |
this.setState({messages: Messages}); | |
}.bind(this)); | |
} | |
if(message.reply_to != undefined){ | |
$.each(Messages, function(index, value){ | |
if(value.id == message.reply_to){ | |
if(message.ok){ | |
value.status = 'visible'; | |
value.ts = message.ts; | |
} | |
} | |
}); | |
this.setState({messages: Messages}); | |
} | |
}, | |
handleMessageSubmit: function(message){ | |
var Messages = this.state.messages; | |
Messages.push({name: "Me", text: message.text, id: message.id, status: "pending", img: ChatApp.user.profile.image_24}); | |
this.setState({messages: Messages}); | |
}, | |
render: function() { | |
if(window.appConfig.slackToken) { | |
return ( | |
<div className='chatBox'> | |
<ChatApp.MessageList data={this.state.messages} /> | |
<ChatApp.MessageForm onMessageSubmit={this.handleMessageSubmit} socketState={this.state.socket} /> | |
</div> | |
); | |
}else{ | |
return ( | |
<a href='#' className='btn btn-success btn-block' ref='linkAccount'>Link your Slack account</a> | |
) | |
} | |
} | |
}) | |
}; | |
return ChatApp; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment