mirror of
https://github.com/zulip/zulip.git
synced 2025-11-05 14:35:27 +00:00
API users, particularly bots, can now send a field
called "widget_content" that will be turned into
a submessage for the web app to look at. (Other
clients can still rely on "content" to be there,
although it's up to the bot author to make the
experience good for those clients as well.)
Right now widget_content will be a JSON string that
encodes a "zform" widget with "choices." Our first
example will be a trivia bot, where users will see
something like this:
Which fruit is orange in color?
[A] orange
[B] blackberry
[C] strawberry
The letters will be turned into buttons on the webapp
and have canned replies.
This commit has a few parts:
- receive widget_content in the request (simply
validating that it's a string)
- parse the JSON in check_message and deeply
validate its structure
- turn it into a submessage in widget.py
69 lines
2.1 KiB
Python
69 lines
2.1 KiB
Python
from typing import MutableMapping, Any
|
|
from django.conf import settings
|
|
|
|
import re
|
|
import json
|
|
|
|
from zerver.models import SubMessage
|
|
|
|
|
|
def do_widget_pre_save_actions(message: MutableMapping[str, Any]) -> None:
|
|
if not settings.ALLOW_SUB_MESSAGES:
|
|
return
|
|
|
|
# this prevents errors of cyclical imports
|
|
from zerver.lib.actions import do_set_user_display_setting
|
|
content = message['message'].content
|
|
user_profile = message['message'].sender
|
|
|
|
if content == '/stats':
|
|
message['message'].content = 'We are running **1 server**.'
|
|
return
|
|
|
|
if content == '/night':
|
|
message['message'].content = 'Changed to night mode! To revert night mode, type `/day`.'
|
|
do_set_user_display_setting(user_profile, 'night_mode', True)
|
|
return
|
|
|
|
if content == '/day':
|
|
message['message'].content = 'Changed to day mode! To revert day mode, type `/night`.'
|
|
do_set_user_display_setting(user_profile, 'night_mode', False)
|
|
return
|
|
|
|
def do_widget_post_save_actions(message: MutableMapping[str, Any]) -> None:
|
|
'''
|
|
This is experimental code that only works with the
|
|
webapp for now.
|
|
'''
|
|
if not settings.ALLOW_SUB_MESSAGES:
|
|
return
|
|
content = message['message'].content
|
|
sender_id = message['message'].sender_id
|
|
message_id = message['message'].id
|
|
|
|
widget_type = None
|
|
extra_data = None
|
|
if content in ['/poll', '/tictactoe']:
|
|
widget_type = content[1:]
|
|
|
|
widget_content = message.get('widget_content')
|
|
if widget_content is not None:
|
|
# Note that we validate this data in check_message,
|
|
# so we can trust it here.
|
|
widget_type = widget_content['widget_type']
|
|
extra_data = widget_content['extra_data']
|
|
|
|
if widget_type:
|
|
content = dict(
|
|
widget_type=widget_type,
|
|
extra_data=extra_data
|
|
)
|
|
submessage = SubMessage(
|
|
sender_id=sender_id,
|
|
message_id=message_id,
|
|
msg_type='widget',
|
|
content=json.dumps(content),
|
|
)
|
|
submessage.save()
|
|
message['submessages'] = SubMessage.get_raw_db_rows([message_id])
|