2017-03-06 08:35:57 +01:00
|
|
|
|
2017-03-06 08:40:34 +01:00
|
|
|
from django.conf import settings
|
2017-03-06 08:43:20 +01:00
|
|
|
from django.core.mail import EmailMessage
|
2017-03-06 08:40:34 +01:00
|
|
|
from typing import Any, Mapping, Optional, Text
|
2017-03-06 08:35:57 +01:00
|
|
|
|
|
|
|
from zerver.lib.actions import internal_send_message
|
2017-07-02 05:27:01 +02:00
|
|
|
from zerver.lib.send_email import FromAddress
|
2017-03-06 08:35:57 +01:00
|
|
|
from zerver.lib.redis_utils import get_redis_client
|
2017-05-22 23:37:15 +02:00
|
|
|
from zerver.models import get_realm, get_system_bot, \
|
2017-03-06 08:59:23 +01:00
|
|
|
UserProfile, Realm
|
2017-03-06 08:35:57 +01:00
|
|
|
|
|
|
|
import time
|
|
|
|
|
|
|
|
client = get_redis_client()
|
|
|
|
|
|
|
|
def has_enough_time_expired_since_last_message(sender_email, min_delay):
|
|
|
|
# type: (Text, float) -> bool
|
|
|
|
# This function returns a boolean, but it also has the side effect
|
|
|
|
# of noting that a new message was received.
|
|
|
|
key = 'zilencer:feedback:%s' % (sender_email,)
|
|
|
|
t = int(time.time())
|
2017-08-26 00:54:25 +02:00
|
|
|
last_time = client.getset(key, t) # type: Optional[bytes]
|
2017-03-06 08:35:57 +01:00
|
|
|
if last_time is None:
|
|
|
|
return True
|
|
|
|
delay = t - int(last_time)
|
|
|
|
return delay > min_delay
|
|
|
|
|
|
|
|
def get_ticket_number():
|
|
|
|
# type: () -> int
|
|
|
|
num_file = '/var/tmp/.feedback-bot-ticket-number'
|
|
|
|
try:
|
|
|
|
ticket_number = int(open(num_file).read()) + 1
|
|
|
|
except Exception:
|
|
|
|
ticket_number = 1
|
|
|
|
open(num_file, 'w').write('%d' % (ticket_number,))
|
|
|
|
return ticket_number
|
|
|
|
|
|
|
|
def deliver_feedback_by_zulip(message):
|
2017-03-06 08:40:34 +01:00
|
|
|
# type: (Mapping[str, Any]) -> None
|
2017-03-06 08:35:57 +01:00
|
|
|
subject = "%s" % (message["sender_email"],)
|
|
|
|
|
|
|
|
if len(subject) > 60:
|
|
|
|
subject = subject[:57].rstrip() + "..."
|
|
|
|
|
2017-11-03 03:12:25 +01:00
|
|
|
content = ''
|
2017-03-06 08:35:57 +01:00
|
|
|
sender_email = message['sender_email']
|
|
|
|
|
|
|
|
# We generate ticket numbers if it's been more than a few minutes
|
|
|
|
# since their last message. This avoids some noise when people use
|
|
|
|
# enter-send.
|
|
|
|
need_ticket = has_enough_time_expired_since_last_message(sender_email, 180)
|
|
|
|
|
|
|
|
if need_ticket:
|
|
|
|
ticket_number = get_ticket_number()
|
|
|
|
content += '\n~~~'
|
|
|
|
content += '\nticket Z%03d (@support please ack)' % (ticket_number,)
|
|
|
|
content += '\nsender: %s' % (message['sender_full_name'],)
|
|
|
|
content += '\nemail: %s' % (sender_email,)
|
2017-03-14 23:31:05 +01:00
|
|
|
if 'sender_realm_str' in message:
|
|
|
|
content += '\nrealm: %s' % (message['sender_realm_str'],)
|
2017-03-06 08:35:57 +01:00
|
|
|
content += '\n~~~'
|
|
|
|
content += '\n\n'
|
|
|
|
|
|
|
|
content += message['content']
|
|
|
|
|
2017-05-22 23:37:15 +02:00
|
|
|
user_profile = get_system_bot(settings.FEEDBACK_BOT)
|
2017-03-06 08:59:23 +01:00
|
|
|
internal_send_message(user_profile.realm, settings.FEEDBACK_BOT,
|
2017-03-06 08:40:34 +01:00
|
|
|
"stream", settings.FEEDBACK_STREAM, subject, content)
|
2017-03-06 08:43:20 +01:00
|
|
|
|
|
|
|
def handle_feedback(event):
|
|
|
|
# type: (Mapping[str, Any]) -> None
|
|
|
|
if not settings.ENABLE_FEEDBACK:
|
|
|
|
return
|
|
|
|
if settings.FEEDBACK_EMAIL is not None:
|
|
|
|
to_email = settings.FEEDBACK_EMAIL
|
|
|
|
subject = "Zulip feedback from %s" % (event["sender_email"],)
|
|
|
|
content = event["content"]
|
2017-07-02 05:27:01 +02:00
|
|
|
from_email = '"%s" <%s>' % (event["sender_full_name"], FromAddress.SUPPORT)
|
2017-03-06 08:43:20 +01:00
|
|
|
headers = {'Reply-To': '"%s" <%s>' % (event["sender_full_name"], event["sender_email"])}
|
|
|
|
msg = EmailMessage(subject, content, from_email, [to_email], headers=headers)
|
|
|
|
msg.send()
|
|
|
|
if settings.FEEDBACK_STREAM is not None:
|
|
|
|
deliver_feedback_by_zulip(event)
|