mirror of https://github.com/zulip/zulip.git
Send feedback to a queue to be forwarded to staging.
(imported from commit 4a9a1bfc6c95763a816263a726cc61b3ca90bf15)
This commit is contained in:
parent
1fa65915f2
commit
e552307511
|
@ -342,6 +342,13 @@ def do_send_messages(messages):
|
||||||
if message['stream'].invite_only:
|
if message['stream'].invite_only:
|
||||||
data['invite_only'] = True
|
data['invite_only'] = True
|
||||||
tornado_callbacks.send_notification(data)
|
tornado_callbacks.send_notification(data)
|
||||||
|
if message['message'].recipient.type == Recipient.PERSONAL and \
|
||||||
|
message['recipients'][0].email == "feedback@zulip.com":
|
||||||
|
queue_json_publish(
|
||||||
|
'feedback_messages',
|
||||||
|
message['message'].to_dict(apply_markdown=False),
|
||||||
|
lambda x: None
|
||||||
|
)
|
||||||
|
|
||||||
# Note that this does not preserve the order of message ids
|
# Note that this does not preserve the order of message ids
|
||||||
# returned. In practice, this shouldn't matter, as we only
|
# returned. In practice, this shouldn't matter, as we only
|
||||||
|
|
|
@ -15,12 +15,14 @@ from zerver.decorator import JsonableError
|
||||||
from confirmation.models import Confirmation
|
from confirmation.models import Confirmation
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import ujson
|
import ujson
|
||||||
import traceback
|
import traceback
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import time
|
import time
|
||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
|
import simplejson
|
||||||
|
|
||||||
def assign_queue(queue_name):
|
def assign_queue(queue_name):
|
||||||
def decorate(clazz):
|
def decorate(clazz):
|
||||||
|
@ -159,6 +161,27 @@ class MissedMessageWorker(QueueProcessingWorker):
|
||||||
# of messages
|
# of messages
|
||||||
time.sleep(2 * 60)
|
time.sleep(2 * 60)
|
||||||
|
|
||||||
|
@assign_queue('feedback_messages')
|
||||||
|
class FeedbackBot(QueueProcessingWorker):
|
||||||
|
def start(self):
|
||||||
|
sys.path.append(os.path.join(os.path.dirname(__file__), '../../api'))
|
||||||
|
import zulip
|
||||||
|
self.staging_client = zulip.Client(
|
||||||
|
email=settings.DEPLOYMENT_ROLE_NAME,
|
||||||
|
api_key=settings.DEPLOYMENT_ROLE_KEY,
|
||||||
|
verbose=True,
|
||||||
|
site=settings.FEEDBACK_TARGET)
|
||||||
|
self.staging_client._register(
|
||||||
|
'forward_feedback',
|
||||||
|
method='POST',
|
||||||
|
url='deployments/feedback',
|
||||||
|
make_request=(lambda request: {'message': simplejson.dumps(request)}),
|
||||||
|
)
|
||||||
|
QueueProcessingWorker.start(self)
|
||||||
|
|
||||||
|
def consume(self, ch, method, properties, event):
|
||||||
|
self.staging_client.forward_feedback(event)
|
||||||
|
|
||||||
@assign_queue('slow_queries')
|
@assign_queue('slow_queries')
|
||||||
class SlowQueryWorker(QueueProcessingWorker):
|
class SlowQueryWorker(QueueProcessingWorker):
|
||||||
def start(self):
|
def start(self):
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
from django.conf.urls import patterns, url, include
|
||||||
|
|
||||||
|
urlpatterns = patterns('zilencer.views',
|
||||||
|
url('^feedback$', 'rest_dispatch',
|
||||||
|
{'POST': 'submit_feedback'}),
|
||||||
|
)
|
|
@ -0,0 +1,48 @@
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from django.views.decorators.csrf import csrf_exempt, csrf_protect
|
||||||
|
|
||||||
|
from zerver.models import get_realm
|
||||||
|
from zerver.lib.actions import internal_send_message
|
||||||
|
from zerver.decorator import has_request_variables, REQ, json_to_dict
|
||||||
|
from zilencer.models import Deployment
|
||||||
|
|
||||||
|
from zerver.lib.rest import rest_dispatch as _rest_dispatch
|
||||||
|
rest_dispatch = csrf_exempt((lambda request, *args, **kwargs: _rest_dispatch(request, globals(), *args, **kwargs)))
|
||||||
|
|
||||||
|
|
||||||
|
def get_ticket_number():
|
||||||
|
fn = '/var/tmp/.feedback-bot-ticket-number'
|
||||||
|
try:
|
||||||
|
ticket_number = int(open(fn).read()) + 1
|
||||||
|
except:
|
||||||
|
ticket_number = 1
|
||||||
|
open(fn, 'w').write('%d' % ticket_number)
|
||||||
|
return ticket_number
|
||||||
|
|
||||||
|
@has_request_variables
|
||||||
|
def submit_feedback(request, deployment, message=REQ(converter=json_to_dict)):
|
||||||
|
domainish = message["sender_domain"]
|
||||||
|
if get_realm("zulip.com") not in deployment.realms.all():
|
||||||
|
domainish += " via " + deployment.realms.get(0).domain
|
||||||
|
subject = "feedback: %s (%s)" % (message["sender_email"], domainish)
|
||||||
|
|
||||||
|
if len(subject) > 60:
|
||||||
|
subject = subject[:57].rstrip() + "..."
|
||||||
|
|
||||||
|
|
||||||
|
ticket_number = get_ticket_number()
|
||||||
|
content = '@support, Please ack this new request.'
|
||||||
|
content += '\n~~~'
|
||||||
|
content += '\nticket Z%03d' % (ticket_number,)
|
||||||
|
content += '\nsender: %s' % (message['sender_full_name'],)
|
||||||
|
content += '\nemail: %s' % (message['sender_email'],)
|
||||||
|
if 'sender_domain' in message:
|
||||||
|
content += '\nrealm: %s' % (message['sender_domain'],)
|
||||||
|
content += '\n~~~'
|
||||||
|
|
||||||
|
content += '\n\n'
|
||||||
|
content += message['content']
|
||||||
|
|
||||||
|
internal_send_message("feedback@zulip.com", "stream", "support", subject, content)
|
||||||
|
|
||||||
|
return HttpResponse(message['sender_email'])
|
|
@ -65,6 +65,11 @@ else:
|
||||||
|
|
||||||
EMBEDLY_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
EMBEDLY_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
|
||||||
|
if DEPLOYED:
|
||||||
|
FEEDBACK_TARGET="https://staging.zulip.com/api"
|
||||||
|
else:
|
||||||
|
FEEDBACK_TARGET="http://localhost:9991/api"
|
||||||
|
|
||||||
# For now, LOCALSERVER is only testing, so write to our test buckets
|
# For now, LOCALSERVER is only testing, so write to our test buckets
|
||||||
if DEPLOYED and not LOCALSERVER:
|
if DEPLOYED and not LOCALSERVER:
|
||||||
S3_KEY="xxxxxxxxxxxxxxxxxxxx"
|
S3_KEY="xxxxxxxxxxxxxxxxxxxx"
|
||||||
|
|
|
@ -211,7 +211,13 @@ v1_api_and_json_patterns = patterns('zerver.views',
|
||||||
{'GET': 'get_updates_backend'}),
|
{'GET': 'get_updates_backend'}),
|
||||||
url(r'^events$', 'rest_dispatch',
|
url(r'^events$', 'rest_dispatch',
|
||||||
{'GET': 'get_events_backend'}),
|
{'GET': 'get_events_backend'}),
|
||||||
|
|
||||||
)
|
)
|
||||||
|
if not settings.LOCALSERVER:
|
||||||
|
v1_api_and_json_patterns += patterns('',
|
||||||
|
# Still scoped to api/v1/, but under a different project
|
||||||
|
url(r'^deployments/', include('zilencer.urls.api')),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
urlpatterns += patterns('zerver.tornadoviews',
|
urlpatterns += patterns('zerver.tornadoviews',
|
||||||
|
|
Loading…
Reference in New Issue