[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:
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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&utm_medium=email" style="color: #875A7B;">Odoo</a>
|
||||
</td></tr>
|
||||
</table>
|
||||
</template>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user