[IMP] im_livechat: allow visitors to get a transcript of their live chat

after this commit user can get a copy of the conversation with operator

task-2029660
closes #34620

closes odoo/odoo#35083

Signed-off-by: Martin Geubelle (mge) <mge@openerp.com>
This commit is contained in:
mgh-odoo
2019-08-14 12:25:12 +00:00
parent 3d9abe6332
commit 737746c05c
7 changed files with 205 additions and 16 deletions
+1
View File
@@ -20,6 +20,7 @@ Help your customers with this chat, and analyse their feedback.
""",
'data': [
"data/mail_shortcode_data.xml",
"data/mail_data.xml",
"data/im_livechat_channel_data.xml",
"security/im_livechat_channel_security.xml",
"security/ir.model.access.csv",
+6
View File
@@ -148,3 +148,9 @@ class LivechatController(http.Controller):
Channel = request.env['mail.channel']
channel = Channel.sudo().search([('uuid', '=', uuid)], limit=1)
channel.notify_typing(is_typing=is_typing, is_website_user=True)
@http.route('/im_livechat/email_livechat_transcript', type='json', auth='public', cors="*")
def email_livechat_transcript(self, uuid, email):
channel = request.env['mail.channel'].sudo().search([('uuid', '=', uuid)], limit=1)
if channel:
channel._email_livechat_transcript(email)
+96
View File
@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<template id="livechat_email_template">
<table border="0" cellpadding="0" cellspacing="0" style="padding-top: 16px; background-color: #F1F1F1; font-family:Verdana, Arial,sans-serif; color: #454748; width: 100%; border-collapse:separate;"><tr><td align="center">
<table border="0" cellpadding="0" cellspacing="0" width="590" style="padding: 24px; background-color: white; color: #454748; border-collapse:separate;">
<tbody>
<!-- HEADER -->
<tr>
<td align="center" style="min-width: 590px;">
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="background-color: white; padding: 0; border-collapse:separate;">
<tr><td valign="middle">
<span style="font-size: 10px;">Livechat Conversation</span><br/>
<span style="font-size: 20px; font-weight: bold;">
<t t-esc="company.name"/>
</span>
</td><td valign="middle" align="right">
<img t-att-src="'/logo.png?company=%s' % company.id" style="padding: 0px; margin: 0px; height: 48px;" t-att-alt="'%s' % company.name"/>
</td></tr>
<tr><td colspan="2" style="text-align:center;">
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin:4px 0px 32px 0px;"/>
</td></tr>
</table>
</td>
</tr>
<!-- CONTENT -->
<t t-set="top" t-value="'border-top: thin solid #dee2e6;'" />
<t t-set="bottom" t-value="'border-bottom: thin solid #dee2e6;'" />
<t t-set="right" t-value="'border-right: thin solid #dee2e6;'" />
<t t-set="left" t-value="'border-left: thin solid #dee2e6;'" />
<tr>
<td style="padding: 0 50px;">
<div style="font-size: 13px; padding: 10px 0;">
<span>Hello,</span><br />Here's a copy of your conversation with
<span t-field="channel.livechat_operator_id.name"/>, on the
<span t-field="channel.livechat_channel_id.create_date"/>
</div>
<table cellspacing="0" cellpadding="0" style="width:100%; border-collapse: collapse;">
<t t-foreach="channel.message_ids.sorted(key=lambda m: m.date)" t-as="message" >
<t t-set="author_name" t-value="message.author_id.name if message.author_id else 'You'" />
<tr>
<td valign="top" align="center" rowspan="2" t-att-style="'width: 70px;' + top + bottom + left">
<t t-if="message.author_avatar">
<img t-attf-alt="{{author_name}}" height="64" width="64" t-attf-src="data:image/png;base64,{{message.author_avatar}}"/>
</t>
<t t-else="">
<img t-attf-alt="{{author_name}}" height="64" width="64" src="/mail/static/src/img/smiley/avatar.jpg"/>
</t>
</td>
<td t-att-style="'padding-left: 5px; margin: 0px;' + top">
<strong t-esc="author_name"/>
</td>
<td t-att-style="'font-size: 13px; padding: 5px;' + top + right" align="right"><span t-field="message.date"/></td>
</tr>
<tr>
<td valign="top" colspan="2" t-att-style="'padding-left: 5px;' + bottom + right">
<span t-field="message.body" style="font-size: 13px;"/>
</td>
</tr>
</t>
</table>
<div style="font-size: 13px; padding: 30px 0;">
<span>Best regards,</span><br /><br />
<span t-field="company.name"/>
</div>
</td>
</tr>
<!-- FOOTER -->
<tr>
<td align="center" style="min-width: 590px; padding: 0 8px 0 8px; font-size:11px;">
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 4px 0px;"/>
<b t-esc="company.name"/><br/>
<div style="color: #999999;">
<t t-esc="company.phone"/>
<t t-if="company.email"> |
<a t-att-href="'mailto:%s' % company.email" style="text-decoration:none; color: #999999;"><t t-esc="company.email"/></a>
</t>
<t t-if="company.website"> |
<a t-att-href="'%s' % company.website" style="text-decoration:none; color: #999999;">
<t t-esc="company.website"/>
</a>
</t>
</div>
</td>
</tr>
</tbody>
</table>
</td></tr>
<!-- POWERED BY -->
<tr><td align="center" style="min-width: 590px;">
Powered by <a target="_blank" href="https://www.odoo.com?utm_source=db&amp;utm_medium=email" style="color: #875A7B;">Odoo</a>
</td></tr>
</table>
</template>
</data>
</odoo>
+17
View File
@@ -159,3 +159,20 @@ class MailChannel(models.Model):
def _rating_get_parent_field_name(self):
return 'livechat_channel_id'
def _email_livechat_transcript(self, email):
company = self.env.user.company_id
render_context = {
"company": company,
"channel": self,
}
template = self.env.ref('im_livechat.livechat_email_template')
mail_body = template.render(render_context, engine='ir.qweb', minimal_qcontext=True)
mail_body = self.env['mail.thread']._replace_local_links(mail_body)
mail = self.env['mail.mail'].create({
'subject': _('Conversation with %s') % self.livechat_operator_id.name,
'email_from': self.env.company.email,
'email_to': email,
'body_html': mail_body,
})
mail.send()
@@ -410,6 +410,8 @@ var Feedback = Widget.extend({
'click .o_livechat_rating_choices img': '_onClickSmiley',
'click .o_livechat_no_feedback span': '_onClickNoFeedback',
'click .o_rating_submit_button': '_onClickSend',
'click .o_email_chat_button': '_onEmailChat',
'click .o_livechat_email_error .alert-link': '_onTryAgain',
},
/**
@@ -451,6 +453,15 @@ var Feedback = Widget.extend({
}
});
},
/**
* @private
*/
_showThanksMessage: function () {
this.$('.o_livechat_rating_box').empty().append($('<div />', {
text: _t('Thank you for your feedback'),
class: 'text-muted'
}));
},
//--------------------------------------------------------------------------
// Handlers
@@ -466,6 +477,7 @@ var Feedback = Widget.extend({
* @private
*/
_onClickSend: function () {
this._showThanksMessage();
if (_.isNumber(this.rating)) {
this._sendFeedback({ reason: this.$('textarea').val(), close: true });
}
@@ -480,14 +492,48 @@ var Feedback = Widget.extend({
this.$('.o_livechat_rating_choices img[data-value="'+this.rating+'"]').addClass('selected');
// only display textearea if bad smiley selected
var shouldCloseChatWindow = false;
if (this.rating !== 10) {
this.$('.o_livechat_rating_reason').show();
} else {
this.$('.o_livechat_rating_reason').hide();
shouldCloseChatWindow = true;
this._showThanksMessage();
}
this._sendFeedback({ close: shouldCloseChatWindow });
this._sendFeedback({ close: false });
},
/**
* @private
*/
_onEmailChat: function () {
var self = this;
var $email = this.$('#o_email');
if (utils.is_email($email.val())) {
$email.removeAttr('title').removeClass('is-invalid').prop('disabled', true);
this.$('.o_email_chat_button').prop('disabled', true);
this._rpc({
route: '/im_livechat/email_livechat_transcript',
params: {
uuid: this._livechat.getUUID(),
email: $email.val(),
}
}).then(function () {
self.$('.o_livechat_email').html($('<strong />', { text: _t('Conversation Sent') }));
}).guardedCatch(function () {
self.$('.o_livechat_email').hide();
self.$('.o_livechat_email_error').show();
});
} else {
$email.addClass('is-invalid').prop('title', _t('Invalid email address'));
}
},
/**
* @private
*/
_onTryAgain: function () {
this.$('#o_email').prop('disabled', false);
this.$('.o_email_chat_button').prop('disabled', false);
this.$('.o_livechat_email_error').hide();
this.$('.o_livechat_email').show();
},
});
@@ -32,17 +32,25 @@
padding: 15px;
font-size: 14px;
.o_livechat_email {
font-size: 12px;
> div {
padding: 5px 0;
}
}
.o_livechat_no_feedback {
text-decoration: underline;
cursor: pointer;
margin: 20px 0;
}
.o_livechat_rating_feedback_text {
margin-top: 65px;
.o_livechat_rating_box {
margin: 40px 0 30px 0;
}
.o_livechat_rating_choices {
margin: 40px 0;
margin: 10px 0;
> img {
width: 65px;
@@ -4,16 +4,15 @@
<t t-name="im_livechat.FeedBack">
<div class="o_livechat_rating text-center">
<div class="o_livechat_rating_feedback_text">
Did we correctly answer your question ?
</div>
<div class="o_livechat_rating_choices">
<img t-att-src="widget.server_origin + '/rating/static/src/img/rating_10.png'" alt="Good" data-value="10"/>
<img t-att-src="widget.server_origin + '/rating/static/src/img/rating_5.png'" alt="OK" data-value="5"/>
<img t-att-src="widget.server_origin + '/rating/static/src/img/rating_1.png'" alt="Bad" data-value="1" />
</div>
<div class="o_livechat_no_feedback text-muted">
<span> I don't want to rate this conversation</span>
<div class="o_livechat_rating_box">
<div class="o_livechat_rating_feedback_text">
Did we correctly answer your question ?
</div>
<div class="o_livechat_rating_choices">
<img t-att-src="widget.server_origin + '/rating/static/src/img/rating_10.png'" alt="Good" data-value="10"/>
<img t-att-src="widget.server_origin + '/rating/static/src/img/rating_5.png'" alt="OK" data-value="5"/>
<img t-att-src="widget.server_origin + '/rating/static/src/img/rating_1.png'" alt="Bad" data-value="1" />
</div>
</div>
<div class="o_livechat_rating_reason">
<textarea id="reason" placeholder="Explain your note"></textarea>
@@ -21,6 +20,22 @@
<input type="button" class="o_rating_submit_button" value="Send" />
</div>
</div>
<div class="o_livechat_email">
<span class="text-muted">Receive a copy of this conversation</span>
<div class="input-group">
<input id="o_email" type="text" class="form-control"/>
<button type="button" class="o_email_chat_button btn btn-primary rounded-0">
<i class="fa fa-paper-plane"/>
</button>
</div>
</div>
<div class="alert alert-danger px-0 o_livechat_email_error" style="display: none;" role="alert">
Oops! Something went wrong.<br />Please check your internet connection.<br />
<a href="#" class="alert-link">Try again</a>
</div>
<div class="o_livechat_no_feedback text-muted">
<span>Close conversation</span>
</div>
</div>
</t>