Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NEW] Livechat webhook request on message #9870

Merged
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -1709,6 +1709,8 @@
"Send_request_on_chat_close": "Send Request on Chat Close",
"Send_request_on_lead_capture": "Send request on lead capture",
"Send_request_on_offline_messages": "Send Request on Offline Messages",
"Send_request_on_visitor_message": "Send Request on Visitor Messages",
"Send_request_on_agent_message": "Send Request on Agent Messages",
"Send_Test": "Send Test",
"Send_welcome_email": "Send welcome email",
"Send_your_JSON_payloads_to_this_URL": "Send your JSON payloads to this URL.",
Expand Down
2 changes: 2 additions & 0 deletions packages/rocketchat-i18n/i18n/pt-BR.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,8 @@
"Send_invitation_email_success": "Você enviou com sucesso um convite por e-mail para os seguintes endereços:",
"Send_request_on_chat_close": "Enviar requisição ao fechar conversa",
"Send_request_on_offline_messages": "Enviar requisição para mensagens off-line",
"Send_request_on_visitor_message": "Enviar requisição para mensagens do Visitante",
"Send_request_on_agent_message": "Enviar requisição para mensagens do Agente",
"Send_Test": "Enviar teste",
"Send_welcome_email": "Enviar e-mail de boas-vindas",
"Send_your_JSON_payloads_to_this_URL": "Envie seu payload JSON para esta URL.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ <h2>{{_ "Webhooks"}}</h2>
{{_ "Send_request_on_offline_messages"}}
</label>
</div>
<div class="input-line">
<label for="sendOnVisitorMessage">
<input type="checkbox" name="sendOnVisitorMessage" id="sendOnVisitorMessage" value="1" checked="{{sendOnVisitorMessageChecked}}">
{{_ "Send_request_on_visitor_message"}}
</label>
</div>
<div class="input-line">
<label for="sendOnAgentMessage">
<input type="checkbox" name="sendOnAgentMessage" id="sendOnAgentMessage" value="1" checked="{{sendOnAgentMessageChecked}}">
{{_ "Send_request_on_agent_message"}}
</label>
</div>
<div class="submit">
<button class="button danger reset-settings" type="button"><i class="icon-ccw"></i>{{_ "Reset"}}</button>
<button class="button secondary test" type="button" disabled="{{disableTest}}">{{_ "Send_Test"}}</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ Template.livechatIntegrationWebhook.helpers({
sendOnOfflineChecked() {
const setting = LivechatIntegration.findOne('Livechat_webhook_on_offline_msg');
return setting && setting.value;
},
sendOnVisitorMessageChecked() {
const setting = LivechatIntegration.findOne('Livechat_webhook_on_visitor_message');
return setting && setting.value;
},
sendOnAgentMessageChecked() {
const setting = LivechatIntegration.findOne('Livechat_webhook_on_agent_message');
return setting && setting.value;
}
});

Expand Down Expand Up @@ -62,11 +70,15 @@ Template.livechatIntegrationWebhook.events({
const secretToken = LivechatIntegration.findOne('Livechat_secret_token');
const webhookOnClose = LivechatIntegration.findOne('Livechat_webhook_on_close');
const webhookOnOfflineMsg = LivechatIntegration.findOne('Livechat_webhook_on_offline_msg');
const webhookOnVisitorMessage = LivechatIntegration.findOne('Livechat_webhook_on_visitor_message');
const webhookOnAgentMessage = LivechatIntegration.findOne('Livechat_webhook_on_agent_message');

instance.$('#webhookUrl').val(webhookUrl && webhookUrl.value);
instance.$('#secretToken').val(secretToken && secretToken.value);
instance.$('#sendOnClose').get(0).checked = webhookOnClose && webhookOnClose.value;
instance.$('#sendOnOffline').get(0).checked = webhookOnOfflineMsg && webhookOnOfflineMsg.value;
instance.$('#sendOnVisitorMessage').get(0).checked = webhookOnVisitorMessage && webhookOnVisitorMessage.value;
instance.$('#sendOnAgentMessage').get(0).checked = webhookOnAgentMessage && webhookOnAgentMessage.value;

instance.disableTest.set(!webhookUrl || _.isEmpty(webhookUrl.value));
},
Expand All @@ -77,7 +89,9 @@ Template.livechatIntegrationWebhook.events({
'Livechat_webhookUrl': s.trim(instance.$('#webhookUrl').val()),
'Livechat_secret_token': s.trim(instance.$('#secretToken').val()),
'Livechat_webhook_on_close': instance.$('#sendOnClose').get(0).checked,
'Livechat_webhook_on_offline_msg': instance.$('#sendOnOffline').get(0).checked
'Livechat_webhook_on_offline_msg': instance.$('#sendOnOffline').get(0).checked,
'Livechat_webhook_on_visitor_message': instance.$('#sendOnVisitorMessage').get(0).checked,
'Livechat_webhook_on_agent_message': instance.$('#sendOnAgentMessage').get(0).checked
};
Meteor.call('livechat:saveIntegration', settings, (err) => {
if (err) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ <h2>{{_ "Webhooks"}}</h2>
{{_ "Send_request_on_offline_messages"}}
</label>
</div>
<div class="input-line">
<label for="sendOnVisitorMessage">
<input type="checkbox" name="sendOnVisitorMessage" id="sendOnVisitorMessage" value="1" checked="{{sendOnVisitorMessageChecked}}">
{{_ "Send_request_on_visitor_message"}}
</label>
</div>
<div class="input-line">
<label for="sendOnAgentMessage">
<input type="checkbox" name="sendOnAgentMessage" id="sendOnAgentMessage" value="1" checked="{{sendOnAgentMessageChecked}}">
{{_ "Send_request_on_agent_message"}}
</label>
</div>
<div class="submit">
<button class="button danger reset-settings" type="button"><i class="icon-ccw"></i>{{_ "Reset"}}</button>
<button class="button secondary test" type="button" disabled="{{disableTest}}">{{_ "Send_Test"}}</button>
Expand Down
14 changes: 14 additions & 0 deletions packages/rocketchat-livechat/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,20 @@ Meteor.startup(function() {
i18nLabel: 'Send_request_on_offline_messages'
});

RocketChat.settings.add('Livechat_webhook_on_visitor_message', false, {
type: 'boolean',
group: 'Livechat',
section: 'CRM_Integration',
i18nLabel: 'Send_request_on_visitor_message'
});

RocketChat.settings.add('Livechat_webhook_on_agent_message', false, {
type: 'boolean',
group: 'Livechat',
section: 'CRM_Integration',
i18nLabel: 'Send_request_on_agent_message'
});

RocketChat.settings.add('Livechat_webhook_on_capture', false, {
type: 'boolean',
group: 'Livechat',
Expand Down
40 changes: 37 additions & 3 deletions packages/rocketchat-livechat/server/hooks/sendToCRM.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,24 @@ function sendToCRM(type, room, includeMessages = true) {

postData.messages = [];

if (includeMessages) {
RocketChat.models.Messages.findVisibleByRoomId(room._id, { sort: { ts: 1 } }).forEach((message) => {
let messages;
if (typeof includeMessages === 'boolean' && includeMessages) {
messages = RocketChat.models.Messages.findVisibleByRoomId(room._id, { sort: { ts: 1 } });
} else if (includeMessages instanceof Array) {
messages = includeMessages;
}

if (messages) {
messages.forEach((message) => {
if (message.t) {
return;
}
const msg = {
Copy link
Contributor Author

@hmagarotto hmagarotto Mar 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sampaiodiego here I added _id and editedAt fields. This is the payload sent on webhook request. Now, these new fields will be sent in all events.

_id: message._id,
username: message.u.username,
msg: message.msg,
ts: message.ts
ts: message.ts,
editedAt: message.editedAt
};

if (message.u.username !== postData.visitor.username) {
Expand Down Expand Up @@ -49,6 +58,31 @@ RocketChat.callbacks.add('livechat.saveInfo', (room) => {
return sendToCRM('LivechatEdit', room);
}, RocketChat.callbacks.priority.MEDIUM, 'livechat-send-crm-save-info');

RocketChat.callbacks.add('afterSaveMessage', function(message, room) {
// only call webhook if it is a livechat room
if (!(typeof room.t !== 'undefined' && room.t === 'l' && room.v && room.v.token)) {
return message;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will pass if room.t === undefined, I'd suggest this:

if (room.t !== 'l' || room.v == null || room.v.token == null)) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rodrigok, fix was done according to suggestion.
This code is a copy from sendToFacebook.js and sendMessageBySMS.js, maybe these callbacks need the same changes.


// if the message has a token, it was sent from the visitor
// if not, it was sent from the agent
if (message.token) {
if (!RocketChat.settings.get('Livechat_webhook_on_visitor_message')) {
return message;
}
} else if (!RocketChat.settings.get('Livechat_webhook_on_agent_message')) {
return message;
}

// if the message has a type means it is a special message (like the closing comment), so skips
if (message.t) {
return message;
}

sendToCRM('Message', room, [message]);
return message;
}, RocketChat.callbacks.priority.MEDIUM, 'sendMessageToFacebook');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The callback ID/name is wrong sendMessageToFacebook

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rodrigok, fixed callback ID to livechat-send-crm-message


RocketChat.callbacks.add('livechat.leadCapture', (room) => {
if (!RocketChat.settings.get('Livechat_webhook_on_capture')) {
return room;
Expand Down
1 change: 1 addition & 0 deletions packages/rocketchat-livechat/server/lib/Livechat.js
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ RocketChat.Livechat = {
customFields: room.livechatData,
visitor: {
_id: visitor._id,
token: visitor.token,
name: visitor.name,
username: visitor.username,
email: null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ Meteor.methods({
RocketChat.settings.updateById('Livechat_webhook_on_offline_msg', !!values['Livechat_webhook_on_offline_msg']);
}

if (typeof values['Livechat_webhook_on_visitor_message'] !== 'undefined') {
RocketChat.settings.updateById('Livechat_webhook_on_visitor_message', !!values['Livechat_webhook_on_visitor_message']);
}

if (typeof values['Livechat_webhook_on_agent_message'] !== 'undefined') {
RocketChat.settings.updateById('Livechat_webhook_on_agent_message', !!values['Livechat_webhook_on_agent_message']);
}

return;
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Meteor.publish('livechat:integration', function() {

const self = this;

const handle = RocketChat.models.Settings.findByIds(['Livechat_webhookUrl', 'Livechat_secret_token', 'Livechat_webhook_on_close', 'Livechat_webhook_on_offline_msg']).observeChanges({
const handle = RocketChat.models.Settings.findByIds(['Livechat_webhookUrl', 'Livechat_secret_token', 'Livechat_webhook_on_close', 'Livechat_webhook_on_offline_msg', 'Livechat_webhook_on_visitor_message', 'Livechat_webhook_on_agent_message']).observeChanges({
added(id, fields) {
self.added('livechatIntegration', id, fields);
},
Expand Down