Support zform-based widget content in the server.

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
This commit is contained in:
Steve Howell
2018-05-21 13:23:46 +00:00
committed by Tim Abbott
parent 1b57e568ff
commit 69517f5ac5
5 changed files with 130 additions and 5 deletions

View File

@@ -237,3 +237,48 @@ def validate_choice_field(var_name: str, field_data: str, value: object) -> None
if value not in field_data_dict:
msg = _("'{value}' is not a valid choice for '{field_name}'.")
return msg.format(value=value, field_name=var_name)
def check_widget_content(widget_content: object) -> Optional[str]:
if not isinstance(widget_content, dict):
return 'widget_content is not a dict'
if 'widget_type' not in widget_content:
return 'widget_type is not in widget_content'
if 'extra_data' not in widget_content:
return 'extra_data is not in widget_content'
widget_type = widget_content['widget_type']
extra_data = widget_content['extra_data']
if not isinstance(extra_data, dict):
return 'extra_data is not a dict'
if widget_type == 'zform':
if 'type' not in extra_data:
return 'zform is missing type field'
if extra_data['type'] == 'choices':
check_choices = check_list(
check_dict([
('short_name', check_string),
('long_name', check_string),
('reply', check_string),
]),
)
checker = check_dict([
('heading', check_string),
('choices', check_choices),
])
msg = checker('extra_data', extra_data)
if msg:
return msg
return None
return 'unknown zform type: ' + extra_data['type']
return 'unknown widget type: ' + widget_type