mirror of https://github.com/zulip/zulip.git
slash commands: Add /ping command (via zcommand).
This adds a /ping command that will be useful for users to see what the round trip to the Zulip server is (including only a tiny bit of actual server time to basically give a 200). It also introduce the "/zcommand" endpoint and zcommand.js module.
This commit is contained in:
parent
87ba752758
commit
4b2e8b83c4
|
@ -74,6 +74,7 @@
|
|||
"typing_status": false,
|
||||
"sent_messages": false,
|
||||
"transmit": false,
|
||||
"zcommand": false,
|
||||
"compose": false,
|
||||
"compose_actions": false,
|
||||
"compose_state": false,
|
||||
|
|
|
@ -55,6 +55,7 @@ set_global('reminder', {
|
|||
global.document.location.protocol = 'https:';
|
||||
global.document.location.host = 'foo.com';
|
||||
|
||||
zrequire('zcommand');
|
||||
zrequire('compose_ui');
|
||||
zrequire('util');
|
||||
zrequire('common');
|
||||
|
|
|
@ -299,11 +299,21 @@ exports.finish = function () {
|
|||
exports.clear_private_stream_alert();
|
||||
notifications.clear_compose_notifications();
|
||||
|
||||
var message_content = compose_state.message_content();
|
||||
|
||||
// Skip normal validation for zcommands, since they aren't
|
||||
// actual messages with recipients; users only send them
|
||||
// from the compose box for convenience sake.
|
||||
if (zcommand.process(message_content)) {
|
||||
exports.do_post_send_tasks();
|
||||
clear_compose_box();
|
||||
return;
|
||||
}
|
||||
|
||||
if (! compose.validate()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var message_content = compose_state.message_content();
|
||||
if (reminder.is_deferred_delivery(message_content)) {
|
||||
reminder.schedule_message();
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
var zcommand = (function () {
|
||||
|
||||
var exports = {};
|
||||
|
||||
/*
|
||||
|
||||
What in the heck is a zcommand?
|
||||
|
||||
A zcommand is basically a specific type of slash
|
||||
command where the client does almost no work and
|
||||
the server just does something pretty simple like
|
||||
flip a setting.
|
||||
|
||||
The first zcommand we wrote is for "/ping", and
|
||||
the server just responds with a 200 for that.
|
||||
|
||||
Not all slash commands use zcommand under the hood.
|
||||
For more exotic things like /poll see submessage.js
|
||||
and widgetize.js
|
||||
|
||||
*/
|
||||
|
||||
exports.send = function (opts) {
|
||||
var command = opts.command;
|
||||
var on_success = opts.on_success;
|
||||
var data = {
|
||||
command: command,
|
||||
};
|
||||
|
||||
channel.post({
|
||||
url: '/json/zcommand',
|
||||
data: data,
|
||||
success: function (data) {
|
||||
on_success(data);
|
||||
},
|
||||
error: function () {
|
||||
exports.tell_user('server did not respond');
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
exports.tell_user = function (msg) {
|
||||
// This is a bit hacky, but we don't have a super easy API now
|
||||
// for just telling users stuff.
|
||||
$('#compose-send-status').removeClass(common.status_classes)
|
||||
.addClass('alert-error')
|
||||
.stop(true).fadeTo(0, 1);
|
||||
$('#compose-error-msg').text(msg);
|
||||
};
|
||||
|
||||
exports.process = function (message_content) {
|
||||
|
||||
var content = message_content.trim();
|
||||
|
||||
if (content === '/ping') {
|
||||
var start_time = new Date();
|
||||
|
||||
exports.send({
|
||||
command: 'ping',
|
||||
on_success: function () {
|
||||
var end_time = new Date();
|
||||
var diff = end_time - start_time;
|
||||
diff = Math.round(diff);
|
||||
var msg = "ping time: " + diff + "ms";
|
||||
exports.tell_user(msg);
|
||||
},
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
// It is incredibly important here to return false
|
||||
// if we don't see an actual zcommand, so that compose.js
|
||||
// knows this is a normal message.
|
||||
return false;
|
||||
};
|
||||
|
||||
return exports;
|
||||
}());
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = zcommand;
|
||||
}
|
|
@ -999,6 +999,17 @@ class SewMessageAndReactionTest(ZulipTestCase):
|
|||
|
||||
class MessagePOSTTest(ZulipTestCase):
|
||||
|
||||
def test_zcommand(self) -> None:
|
||||
self.login(self.example_email("hamlet"))
|
||||
|
||||
payload = dict(command="boil-ocean")
|
||||
result = self.client_post("/json/zcommand", payload)
|
||||
self.assert_json_error(result, "No such command: boil-ocean")
|
||||
|
||||
payload = dict(command="ping")
|
||||
result = self.client_post("/json/zcommand", payload)
|
||||
self.assert_json_success(result)
|
||||
|
||||
def test_message_to_self(self) -> None:
|
||||
"""
|
||||
Sending a message to a stream to which you are subscribed is
|
||||
|
|
|
@ -681,6 +681,15 @@ def find_first_unread_anchor(sa_conn: Any,
|
|||
|
||||
return anchor
|
||||
|
||||
@has_request_variables
|
||||
def zcommand_backend(request: HttpRequest, user_profile: UserProfile,
|
||||
command: str=REQ('command')) -> HttpResponse:
|
||||
if command == 'ping':
|
||||
ret = dict() # type: Dict[str, Any]
|
||||
return json_success(ret)
|
||||
|
||||
raise JsonableError(_('No such command: %s') % (command,))
|
||||
|
||||
@has_request_variables
|
||||
def get_messages_backend(request: HttpRequest, user_profile: UserProfile,
|
||||
anchor: int=REQ(converter=int),
|
||||
|
|
|
@ -968,6 +968,7 @@ JS_SPECS = {
|
|||
'js/compose_state.js',
|
||||
'js/compose_actions.js',
|
||||
'js/transmit.js',
|
||||
'js/zcommand.js',
|
||||
'js/compose.js',
|
||||
'js/upload.js',
|
||||
'js/stream_color.js',
|
||||
|
|
|
@ -162,6 +162,9 @@ v1_api_and_json_patterns = [
|
|||
url(r'^mark_topic_as_read$', rest_dispatch,
|
||||
{'POST': 'zerver.views.messages.mark_topic_as_read'}),
|
||||
|
||||
url(r'^zcommand$', rest_dispatch,
|
||||
{'POST': 'zerver.views.messages.zcommand_backend'}),
|
||||
|
||||
# messages -> zerver.views.messages
|
||||
# GET returns messages, possibly filtered, POST sends a message
|
||||
url(r'^messages$', rest_dispatch,
|
||||
|
|
Loading…
Reference in New Issue