diff --git a/packages/rocketchat-livechat/client/stylesheets/livechat.less b/packages/rocketchat-livechat/client/stylesheets/livechat.less index 61f1df5723e..90899d12217 100644 --- a/packages/rocketchat-livechat/client/stylesheets/livechat.less +++ b/packages/rocketchat-livechat/client/stylesheets/livechat.less @@ -506,3 +506,16 @@ color: @status-offline; } } + +.external-message { + padding: 10px; + position: relative; + &:after { + content: " "; + position: absolute; + border-bottom: 1px solid #CCC; + left: 10px; + right: 10px; + bottom: 0; + } +} diff --git a/packages/rocketchat-livechat/client/ui.js b/packages/rocketchat-livechat/client/ui.js index 751f4947aab..d2bc62dd385 100644 --- a/packages/rocketchat-livechat/client/ui.js +++ b/packages/rocketchat-livechat/client/ui.js @@ -44,3 +44,12 @@ RocketChat.TabBar.addGroup('message-search', ['livechat']); RocketChat.TabBar.addGroup('starred-messages', ['livechat']); RocketChat.TabBar.addGroup('uploaded-files-list', ['livechat']); RocketChat.TabBar.addGroup('push-notifications', ['livechat']); + +RocketChat.TabBar.addButton({ + groups: ['livechat'], + id: 'external-search', + i18nTitle: 'External_Search', + icon: 'icon-lightbulb', + template: 'externalSearch', + order: 10 +}); diff --git a/packages/rocketchat-livechat/client/views/app/tabbar/externalSearch.html b/packages/rocketchat-livechat/client/views/app/tabbar/externalSearch.html new file mode 100644 index 00000000000..ed2110df5b1 --- /dev/null +++ b/packages/rocketchat-livechat/client/views/app/tabbar/externalSearch.html @@ -0,0 +1,15 @@ + diff --git a/packages/rocketchat-livechat/client/views/app/tabbar/externalSearch.js b/packages/rocketchat-livechat/client/views/app/tabbar/externalSearch.js new file mode 100644 index 00000000000..cde7f5f9862 --- /dev/null +++ b/packages/rocketchat-livechat/client/views/app/tabbar/externalSearch.js @@ -0,0 +1,23 @@ +Template.externalSearch.helpers({ + messages() { + console.log('messages helper'); + return RocketChat.models.LivechatExternalMessage.findByRoomId(this.rid, { ts: 1 }); + } +}); + +Template.externalSearch.events({ + 'click a.pick-message'(event, instance) { + event.preventDefault(); + + $('#chat-window-' + instance.roomId + ' .input-message').val(this.msg).focus(); + } +}); + +Template.externalSearch.onCreated(function() { + this.roomId = null; + // console.log('externalSearch.this ->',this); + this.autorun(() => { + this.roomId = Template.currentData().rid; + this.subscribe('livechat:externalMessages', Template.currentData().rid); + }); +}); diff --git a/packages/rocketchat-livechat/config.js b/packages/rocketchat-livechat/config.js index d8788f9bc6c..36fdd74384b 100644 --- a/packages/rocketchat-livechat/config.js +++ b/packages/rocketchat-livechat/config.js @@ -5,4 +5,28 @@ Meteor.startup(function() { RocketChat.settings.add('Livechat_enabled', false, { type: 'boolean', group: 'Livechat', public: true }); RocketChat.settings.add('Livechat_registration_form', true, { type: 'boolean', group: 'Livechat', public: true, i18nLabel: 'Show_preregistration_form' }); RocketChat.settings.add('Livechat_guest_count', 1, { type: 'int', group: 'Livechat' }); + + RocketChat.settings.add('Livechat_Knowledge_Enabled', false, { + type: 'boolean', + group: 'Livechat', + section: 'Knowledge Base', + public: true, + i18nLabel: 'Knowledge_Enabled' + }); + + RocketChat.settings.add('Livechat_Knowledge_Apiai_Key', '', { + type: 'string', + group: 'Livechat', + section: 'Knowledge Base', + public: true, + i18nLabel: 'Apiai_Key' + }); + + RocketChat.settings.add('Livechat_Knowledge_Apiai_Language', 'en', { + type: 'string', + group: 'Livechat', + section: 'Knowledge Base', + public: true, + i18nLabel: 'Apiai_Language' + }); }); diff --git a/packages/rocketchat-livechat/package.js b/packages/rocketchat-livechat/package.js index 68f0530ef68..da8d8dc2d89 100644 --- a/packages/rocketchat-livechat/package.js +++ b/packages/rocketchat-livechat/package.js @@ -25,6 +25,7 @@ Package.onUse(function(api) { api.use('rocketchat:ui'); api.use('kadira:flow-router', 'client'); api.use('templating', 'client'); + api.use('http'); api.use('mongo'); api.use('rocketchat:sms'); api.use('less@2.5.1'); @@ -73,6 +74,8 @@ Package.onUse(function(api) { api.addFiles('client/views/app/livechatUsers.html', 'client'); api.addFiles('client/views/app/livechatUsers.js', 'client'); + api.addFiles('client/views/app/tabbar/externalSearch.html', 'client'); + api.addFiles('client/views/app/tabbar/externalSearch.js', 'client'); api.addFiles('client/views/app/tabbar/visitorInfo.html', 'client'); api.addFiles('client/views/app/tabbar/visitorInfo.js', 'client'); @@ -109,6 +112,7 @@ Package.onUse(function(api) { // models api.addFiles('server/models/Users.js', 'server'); api.addFiles('server/models/Rooms.js', 'server'); + api.addFiles('server/models/LivechatExternalMessage.js', ['client', 'server']); api.addFiles('server/models/LivechatCustomField.js', 'server'); api.addFiles('server/models/LivechatDepartment.js', 'server'); api.addFiles('server/models/LivechatDepartmentAgents.js', 'server'); @@ -118,11 +122,13 @@ Package.onUse(function(api) { // server lib api.addFiles('server/lib/Livechat.js', 'server'); api.addFiles('server/sendMessageBySMS.js', 'server'); + api.addFiles('server/externalMessageHook.js', 'server'); // publications api.addFiles('server/publications/availableDepartments.js', 'server'); api.addFiles('server/publications/customFields.js', 'server'); api.addFiles('server/publications/departmentAgents.js', 'server'); + api.addFiles('server/publications/externalMessages.js', 'server'); api.addFiles('server/publications/livechatAgents.js', 'server'); api.addFiles('server/publications/livechatDepartments.js', 'server'); api.addFiles('server/publications/livechatManagers.js', 'server'); diff --git a/packages/rocketchat-livechat/server/externalMessageHook.js b/packages/rocketchat-livechat/server/externalMessageHook.js new file mode 100644 index 00000000000..4c21e7758f1 --- /dev/null +++ b/packages/rocketchat-livechat/server/externalMessageHook.js @@ -0,0 +1,62 @@ +/* globals HTTP, SystemLogger */ + +var knowledgeEnabled = false; +var apiaiKey = ''; +var apiaiLanguage = 'en'; +RocketChat.settings.get('Livechat_Knowledge_Enabled', function(key, value) { + knowledgeEnabled = value; +}); +RocketChat.settings.get('Livechat_Knowledge_Apiai_Key', function(key, value) { + apiaiKey = value; +}); +RocketChat.settings.get('Livechat_Knowledge_Apiai_Language', function(key, value) { + apiaiLanguage = value; +}); + +RocketChat.callbacks.add('afterSaveMessage', function(message, room) { + // skips this callback if the message was edited + if (message.editedAt) { + return message; + } + + if (!knowledgeEnabled) { + return message; + } + + if (!(typeof room.t !== 'undefined' && room.t === 'l' && room.v && room.v.token)) { + return message; + } + + // if the message hasn't a token, it was not sent by the visitor, so ignore it + if (!message.token) { + return message; + } + + Meteor.defer(() => { + try { + const response = HTTP.post('https://api.api.ai/api/query?v=20150910', { + data: { + query: message.msg, + lang: apiaiLanguage + }, + headers: { + 'Content-Type': 'application/json; charset=utf-8', + 'Authorization': 'Bearer ' + apiaiKey + } + }); + + if (response.data && response.data.status.code === 200 && !_.isEmpty(response.data.result.fulfillment.speech)) { + RocketChat.models.LivechatExternalMessage.insert({ + rid: message.rid, + msg: response.data.result.fulfillment.speech, + orig: message._id, + ts: new Date() + }); + } + } catch (e) { + SystemLogger.error('Error using Api.ai ->', e); + } + }); + + return message; +}, RocketChat.callbacks.priority.LOW); diff --git a/packages/rocketchat-livechat/server/models/LivechatExternalMessage.js b/packages/rocketchat-livechat/server/models/LivechatExternalMessage.js new file mode 100644 index 00000000000..0b8fd708b2e --- /dev/null +++ b/packages/rocketchat-livechat/server/models/LivechatExternalMessage.js @@ -0,0 +1,15 @@ +class LivechatExternalMessage extends RocketChat.models._Base { + constructor() { + super(); + this._initModel('livechat_external_message'); + } + + // FIND + findByRoomId(roomId, sort = { ts: -1 }) { + const query = { rid: roomId }; + + return this.find(query, { sort: sort }); + } +} + +RocketChat.models.LivechatExternalMessage = new LivechatExternalMessage(); diff --git a/packages/rocketchat-livechat/server/publications/externalMessages.js b/packages/rocketchat-livechat/server/publications/externalMessages.js new file mode 100644 index 00000000000..3cd8defdbac --- /dev/null +++ b/packages/rocketchat-livechat/server/publications/externalMessages.js @@ -0,0 +1,3 @@ +Meteor.publish('livechat:externalMessages', function(roomId) { + return RocketChat.models.LivechatExternalMessage.findByRoomId(roomId); +}); diff --git a/packages/rocketchat-theme/assets/stylesheets/base.less b/packages/rocketchat-theme/assets/stylesheets/base.less index 0a8f8cf9b16..68bb4a0269a 100644 --- a/packages/rocketchat-theme/assets/stylesheets/base.less +++ b/packages/rocketchat-theme/assets/stylesheets/base.less @@ -2920,6 +2920,15 @@ body:not(.is-cordova) { width: 100%; height: 100%; } + > .title { + height: @header-min-height; + h2 { + padding: 0 20px; + font-size: 20px; + line-height: @header-min-height; + font-weight: 300; + } + } } footer { position: absolute;