├── .gitignore ├── ruby ├── json_schemas ├── DEPLOY.md ├── lib │ └── any_channel_json_schemas.rb ├── any_channel_json_schemas.gemspec └── README.md ├── .github └── PULL_REQUEST_TEMPLATE ├── json_schemas ├── event_callback_create_integration_instance.json ├── event_callback_activate_integration_instance.json ├── event_callback_destroy_integration_instance.json ├── event_callback_create_integration.json ├── event_callback_destroy_integration.json ├── channelback_payload.json ├── channelback_payload_v2.json ├── pull_payload.json ├── push_parameters.json ├── report_channelback_error.json ├── event_callback_channelback.json ├── event_callback_destroy_user.json ├── event_callback_deactivate_integration_instance.json ├── event_callback_any.json ├── event_callback_pull_request.json ├── event_callback_base.json ├── manifest.json ├── event_callback_resources_created_from_external_ids.json └── external_resource.json ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | -------------------------------------------------------------------------------- /ruby/json_schemas: -------------------------------------------------------------------------------- 1 | ./../json_schemas -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE: -------------------------------------------------------------------------------- 1 | :ocean: 2 | 3 | /cc @zendesk/ocean 4 | 5 | ### Description 6 | * 7 | 8 | ### References 9 | * JIRA: https://zendesk.atlassian.net/browse/ 10 | 11 | ### Risks 12 | * 13 | -------------------------------------------------------------------------------- /json_schemas/event_callback_create_integration_instance.json: -------------------------------------------------------------------------------- 1 | { 2 | "$ref": "event_callback_base.json#/definitions/event_callback_base", 3 | "properties": { 4 | "data": { 5 | "type": "object", 6 | "required": ["metadata"], 7 | "properties": { 8 | "metadata": {"type": "string"} 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /json_schemas/event_callback_activate_integration_instance.json: -------------------------------------------------------------------------------- 1 | { 2 | "$ref": "event_callback_base.json#/definitions/event_callback_base", 3 | "properties": { 4 | "data": { 5 | "type": "object", 6 | "required": ["metadata"], 7 | "properties": { 8 | "metadata": {"type": "string"} 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /json_schemas/event_callback_destroy_integration_instance.json: -------------------------------------------------------------------------------- 1 | { 2 | "$ref": "event_callback_base.json#/definitions/event_callback_base", 3 | "properties": { 4 | "data": { 5 | "type": "object", 6 | "required": ["metadata"], 7 | "properties": { 8 | "metadata": {"type": "string"} 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /json_schemas/event_callback_create_integration.json: -------------------------------------------------------------------------------- 1 | { 2 | "$ref": "event_callback_base.json#/definitions/event_callback_base", 3 | "properties": { 4 | "data": { 5 | "type": "object", 6 | "required": ["manifest_url"], 7 | "properties": { 8 | "manifest_url": {"type": "string", "format": "https-url"} 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /json_schemas/event_callback_destroy_integration.json: -------------------------------------------------------------------------------- 1 | { 2 | "$ref": "event_callback_base.json#/definitions/event_callback_base", 3 | "properties": { 4 | "data": { 5 | "type": "object", 6 | "required": ["manifest_url"], 7 | "properties": { 8 | "manifest_url": {"type": "string", "format": "https-url"} 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /json_schemas/channelback_payload.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": ["external_id"], 4 | "properties": { 5 | "external_id": {"type": "string", "maxLength": 255, "format": "external-id"}, 6 | "allow_channelback": {"type": "boolean"}, 7 | "metadata_needs_update": {"type": "boolean"}, 8 | "metadata": {"type": "string", "maxLength": 5000} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /json_schemas/channelback_payload_v2.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": ["external_id"], 4 | "properties": { 5 | "external_id": {"type": "string", "minLength": 1, "maxLength": 255, "format": "external-id"}, 6 | "allow_channelback": {"type": "boolean"}, 7 | "metadata_needs_update": {"type": "boolean"}, 8 | "metadata": {"type": "string", "maxLength": 5000} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /json_schemas/pull_payload.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": ["external_resources"], 4 | "properties": { 5 | "state": {"type": "string", "maxLength": 5000}, 6 | "external_resources": {"type": "array", "maxItems": 256, "items": { "$ref": "external_resource.json"} }, 7 | "metadata_needs_update": {"type": "boolean"}, 8 | "metadata": {"type": "string", "maxLength": 5000} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /json_schemas/push_parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": ["instance_push_id", "external_resources"], 4 | "properties": { 5 | "instance_push_id": {"type": "string", "minLength": 1, "maxLength": 255}, 6 | "request_id": {"type": "string", "minLength": 1, "maxLength": 64}, 7 | "external_resources": {"type": "array", "maxItems": 256, "items": { "$ref": "external_resource.json"} } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /json_schemas/report_channelback_error.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": ["instance_push_id", "external_id"], 4 | "properties": { 5 | "instance_push_id": { "type": "string", "minLength": 1, "maxLength": 255 }, 6 | "external_id": { "type": "string", "maxLength": 255, "format": "external-id" }, 7 | "request_id": { "type": "string", "minLength": 1, "maxLength": 64 }, 8 | "description": { "type": "string", "maxLength": 511 } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /json_schemas/event_callback_channelback.json: -------------------------------------------------------------------------------- 1 | { 2 | "$ref": "event_callback_base.json#/definitions/event_callback_base", 3 | "properties": { 4 | "data": { 5 | "type": "object", 6 | "required": ["integration_instance_name", "url", "request_id"], 7 | "properties": { 8 | "integration_instance_name": {"type": "string"}, 9 | "url": {"type": "string", "format": "https-url"}, 10 | "request_id": {"type": "string"} 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /json_schemas/event_callback_destroy_user.json: -------------------------------------------------------------------------------- 1 | { 2 | "$ref": "event_callback_base.json#/definitions/event_callback_base", 3 | "properties": { 4 | "data": { 5 | "type": "object", 6 | "required": ["author"], 7 | "properties": { 8 | "author": { 9 | "type": "object", 10 | "required": ["external_id"], 11 | "properties": { 12 | "external_id": {"type": "string"} 13 | } 14 | }, 15 | "metadata": {"type": "string"} 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2016 Zendesk. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /ruby/DEPLOY.md: -------------------------------------------------------------------------------- 1 | # Deployment 2 | 3 | The gem is publically hosted so you will need a [ruby gems account](https://rubygems.org/sign_up). 4 | Then reach out to any of the gem owners (run `gem owner any_channel_json_schemas` to get the full list) and ask them to add you with `gem owner --add any_channel_json_schemas`. 5 | 6 | To push a new version the steps are: 7 | 8 | 1. Update the version in the gemspec file. 9 | 2. Navigate to ./ruby directory. 10 | 2. Run `gem build any_channel_json_schemas.gemspec` *this will create a .gem file* 11 | 3. Run `gem push any_channel_json_schemas-.gem` 12 | -------------------------------------------------------------------------------- /json_schemas/event_callback_deactivate_integration_instance.json: -------------------------------------------------------------------------------- 1 | { 2 | "$ref": "event_callback_base.json#/definitions/event_callback_base", 3 | "properties": { 4 | "data": { 5 | "type": "object", 6 | "required": ["metadata", "deactivated_by"], 7 | "properties": { 8 | "metadata": {"type": "string"}, 9 | "deactivated_by": { 10 | "type": "string", 11 | "enum": [ 12 | "error", 13 | "api" 14 | ] 15 | }, 16 | "deactivating_error": { 17 | "type": "string" 18 | } 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ruby/lib/any_channel_json_schemas.rb: -------------------------------------------------------------------------------- 1 | # The AnyChannelJSONSchemas module exposes a single method for each json schema file in the json_schemas directory. 2 | # Each method returns the full file path as a string. 3 | # 4 | # eg. 5 | # AnyChannelJSONSchemas.manifest 6 | # => "/manifest.json" 7 | module AnyChannelJSONSchemas 8 | Dir["#{File.dirname(File.expand_path(__FILE__))}/../json_schemas/*.json"].each do |file_path| 9 | basename = File.basename(file_path, '.json') 10 | 11 | define_method(basename) do 12 | file_path 13 | end 14 | module_function basename.to_sym 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /json_schemas/event_callback_any.json: -------------------------------------------------------------------------------- 1 | { 2 | "anyOf": [ 3 | { "$ref": "event_callback_create_integration.json" }, 4 | { "$ref": "event_callback_destroy_integration.json" }, 5 | { "$ref": "event_callback_activate_integration_instance.json" }, 6 | { "$ref": "event_callback_deactivate_integration_instance.json" }, 7 | { "$ref": "event_callback_create_integration_instance.json" }, 8 | { "$ref": "event_callback_destroy_integration_instance.json" }, 9 | { "$ref": "event_callback_destroy_user.json" }, 10 | { "$ref": "event_callback_pull_request.json" }, 11 | { "$ref": "event_callback_resources_created_from_external_ids.json" }, 12 | { "$ref": "event_callback_channelback.json" } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /ruby/any_channel_json_schemas.gemspec: -------------------------------------------------------------------------------- 1 | Gem::Specification.new do |gem| 2 | gem.authors = ['JaredShay'] 3 | gem.email = ['jshay@zendesk.com'] 4 | gem.description = %q{JSON schema files for the Zendesk Channels Framework.} 5 | gem.summary = %q{JSON schema files for the Zendesk Channels Framework.} 6 | gem.homepage = 'https://github.com/zendesk/any_channel_json_schemas/ruby' 7 | 8 | gem.files = %w{lib/any_channel_json_schemas.rb README.md} + Dir.glob('json_schemas/*') 9 | gem.test_files = `git ls-files -- spec/*`.split("\n") 10 | gem.name = 'any_channel_json_schemas' 11 | gem.require_paths = ['lib'] 12 | gem.version = '0.15.0' 13 | gem.license = 'Apache-2.0' 14 | end 15 | -------------------------------------------------------------------------------- /json_schemas/event_callback_pull_request.json: -------------------------------------------------------------------------------- 1 | { 2 | "$ref": "event_callback_base.json#/definitions/event_callback_base", 3 | "properties": { 4 | "data": { 5 | "type": "object", 6 | "required": ["integration_instance_name", "url", "request_id", "duplicate_external_ids"], 7 | "properties": { 8 | "integration_instance_name": {"type": "string"}, 9 | "url": {"type": "string", "format": "https-url"}, 10 | "request_id": {"type": "string"}, 11 | "duplicate_external_ids": { 12 | "type": "array", 13 | "items": { 14 | "type": "object", 15 | "required": ["external_id", "request_id"], 16 | "properties": { 17 | "external_id": {"type": "string"}, 18 | "request_id": {"type": "string"}, 19 | "ticket_id": {"type": "number"}, 20 | "comment_id": {"type": "number"} 21 | } 22 | } 23 | } 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /json_schemas/event_callback_base.json: -------------------------------------------------------------------------------- 1 | { 2 | "$ref": "#/definitions/event_callback_base", 3 | "definitions": { 4 | "event_callback_base": { 5 | "type": "object", 6 | "required": ["type_id", "timestamp", "subdomain", "integration_name", "integration_id", "data"], 7 | "properties": { 8 | "type_id": { 9 | "type": "string", 10 | "enum": [ 11 | "create_integration", 12 | "destroy_integration", 13 | "activate_integration_instance", 14 | "deactivate_integration_instance", 15 | "create_integration_instance", 16 | "destroy_integration_instance", 17 | "destroy_user_identity", 18 | "pull_request", 19 | "resources_created_from_external_ids", 20 | "channelback" 21 | ] 22 | }, 23 | "timestamp": {"type": "time"}, 24 | "subdomain": {"type": "string"}, 25 | "integration_name": {"type": "string"}, 26 | "integration_id": {"type": "string"}, 27 | "data": {"type": "object"}, 28 | "error": {"type": "string"} 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /json_schemas/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$ref": "#/definitions/manifest", 3 | "definitions": { 4 | "manifest": { 5 | "type": "object", 6 | "required": ["name", "id", "urls"], 7 | "properties": { 8 | "name": {"type": "string", "minLength": 1, "maxLength": 255}, 9 | "id": {"type": "string", "minLength": 1, "maxLength": 511}, 10 | "version": {"type": "string", "minLength": 1, "maxLength": 255}, 11 | "author": {"type": "string", "minLength": 1, "maxLength": 255}, 12 | "push_client_id": {"type": "string", "minLength": 1, "maxLength": 128}, 13 | "channelback_files": {"type": "boolean"}, 14 | "create_followup_tickets": {"type": "boolean"}, 15 | "urls": { "$ref": "#/definitions/manifest/definitions/urls"} 16 | }, 17 | "definitions": { 18 | "urls": { 19 | "type": "object", 20 | "required": ["admin_ui"], 21 | "properties": { 22 | "admin_ui": {"type": "string", "maxLength": 511, "format": "https-url"}, 23 | "pull_url": {"type": "string", "maxLength": 511, "format": "https-url"}, 24 | "channelback_url": {"type": "string", "maxLength": 511, "format": "https-url"}, 25 | "clickthrough_url": {"type": "string", "maxLength": 511, "format": "https-url"}, 26 | "healthcheck_url": {"type": "string", "maxLength": 511, "format": "https-url"}, 27 | "about_url": {"type": "string", "maxLength": 511, "format": "https-url"}, 28 | "dashboard_url": {"type": "string", "maxLength": 511, "format": "https-url"}, 29 | "event_callback_url": {"type": "string", "maxLength": 511, "format": "https-url"} 30 | } 31 | } 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ruby/README.md: -------------------------------------------------------------------------------- 1 | # Any Channel JSON Schemas 2 | 3 | This is a gem that lets you reference JSON Schema files for the [Zendesk AnyChannel Framework](https://developer.zendesk.com/apps/docs/channels-framework/introduction) in your ruby projects. 4 | 5 | ### Installation 6 | 7 | ``` 8 | gem install any_channel_json_schemas 9 | ``` 10 | 11 | ### Usage 12 | 13 | The gem exposes a single module with the following methods: 14 | 15 | ```ruby 16 | manifest 17 | pull_payload 18 | external_resource 19 | push_parameters 20 | channelback_payload 21 | report_channelback_error 22 | event_callback_any 23 | event_callback_base 24 | event_callback_create_integration 25 | event_callback_create_integration_instance 26 | event_callback_destroy_integration 27 | event_callback_destroy_integration_instance 28 | event_callback_destroy_user 29 | event_callback_pull_request 30 | event_callback_resources_created_from_external_ids 31 | ``` 32 | 33 | Each of these returns an absolute path to a schema file. We use these in our own code base with the [json-schema](https://github.com/ruby-json-schema/json-schema) gem both in our test suite and to validate json payloads real-time. 34 | 35 | Here's an example of how use the schemas to validate a [manifest](https://developer.zendesk.com/apps/docs/channels-framework/integration_manifest). 36 | 37 | ```ruby 38 | validation_errors = JSON::Validator.fully_validate(AnyChannelJSONSchemas.manifest, manifest) 39 | 40 | if validation_errors.empty? 41 | # Manifest conforms to the published schema. 42 | else 43 | # There are validation errors and we can't proceed. 44 | end 45 | ``` 46 | 47 | ### Contributing 48 | 49 | Feel free to open an issue or fork the repo and submit a PR. 50 | 51 | ### Contact 52 | 53 | ocean@zendesk.com 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JSON Schemas for the AnyChannel Framework 2 | 3 | This repo contains [JSON Schemas](http://json-schema.org/) and supporting libraries for the [Zendesk AnyChannel Framework](https://developer.zendesk.com/apps/docs/channels-framework/introduction). 4 | 5 | ### Usage 6 | 7 | The schemas define the various contracts specified by the channels framework. We use them internally at Zendesk to validate the interactions that take place between a Channels Framework integration and Zendesk. 8 | 9 | Feel free to use them in your own test suites or production code. There are supporting libraries for specific languages to help you include them in your integrations. Please reach out or make a pull request if you'd like to see another language included. 10 | 11 | ### Contact 12 | 13 | jshay@zendesk.com 14 | 15 | ### Why is this called AnyChannel, isn't it called the Channels Framework?? 16 | 17 | The schemas and libraries in this repo and intended to be used in code and we want the naming to stay constant. 18 | 19 | To make sure this is always the case we're letting the community in on our super secret internal code name. Don't tell anyone ;) 20 | 21 | ### Custom formats 22 | 23 | These schemas use some custom formats 24 | 25 | * https-url 26 | * external-id 27 | 28 | #### https-url 29 | 30 | This custom format enforces that the URL uses the HTTPS scheme. For example, 'https://www.test.com/document' passes, but 'http://www.test.com/document' does not. 31 | 32 | #### external-id 33 | 34 | * This custom format enforces that the string does not include leading or trailing whitespace. For example '123' passes, but '123 ' does not. 35 | * The [Channel Payload V2](./json_schemas/channelback_payload_v2.json) enforces the value as non-nil. For example '123' passes, but '' does not. 36 | 37 | ### License 38 | 39 | [Apache License](./LICENSE) 40 | -------------------------------------------------------------------------------- /json_schemas/event_callback_resources_created_from_external_ids.json: -------------------------------------------------------------------------------- 1 | { 2 | "$ref": "event_callback_base.json#/definitions/event_callback_base", 3 | "properties": { 4 | "type_id": {"type": "string", "pattern": "^resources_created_from_external_ids$"}, 5 | "data": { 6 | "type": "object", 7 | "required": ["request_id", "resource_events"], 8 | "properties": { 9 | "request_id": {"type": "string"}, 10 | "resource_events": { 11 | "type": "array", 12 | "items": { 13 | "anyOf": [ 14 | {"$ref": "#/definitions/comment_on_new_ticket"}, 15 | {"$ref": "#/definitions/comment_on_existing_ticket"}, 16 | {"$ref": "#/definitions/comment_on_new_follow_up_ticket"}, 17 | {"$ref": "#/definitions/external_id_associated_with_channelback"} 18 | ] 19 | } 20 | } 21 | } 22 | } 23 | }, 24 | "definitions": { 25 | "resource_created_from_external_id": { 26 | "type": "object", 27 | "required": ["type_id", "external_id", "comment_id", "ticket_id"], 28 | "properties": { 29 | "external_id": {"type": "string"}, 30 | "comment_id": {"type": "number"}, 31 | "ticket_id": {"type": "number"} 32 | } 33 | }, 34 | "comment_on_new_ticket": { 35 | "$ref": "#/definitions/resource_created_from_external_id", 36 | "properties": { 37 | "type_id": {"type": "string", "pattern": "^comment_on_new_ticket$"} 38 | } 39 | }, 40 | "comment_on_existing_ticket": { 41 | "$ref": "#/definitions/resource_created_from_external_id", 42 | "properties": { 43 | "type_id": {"type": "string", "pattern": "^comment_on_existing_ticket$"} 44 | } 45 | }, 46 | "comment_on_new_follow_up_ticket": { 47 | "$ref": "#/definitions/resource_created_from_external_id", 48 | "required": ["follow_up_ticket_id"], 49 | "properties": { 50 | "type_id": {"type": "string", "pattern": "^comment_on_follow_up_ticket$"}, 51 | "follow_up_ticket_id": {"type": "number"} 52 | } 53 | }, 54 | "external_id_associated_with_channelback": { 55 | "$ref": "#/definitions/resource_created_from_external_id", 56 | "properties": { 57 | "type_id": {"type": "string", "pattern": "^external_id_associated_with_channelback$"} 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /json_schemas/external_resource.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": ["external_id", "message", "author", "created_at"], 4 | "properties": { 5 | "external_id": {"type": "string", "minLength": 1, "maxLength": 255, "format": "external-id"}, 6 | "internal_note": {"type": "boolean"}, 7 | "message": {"type": "string", "minLength": 1, "maxLength": 65535}, 8 | "html_message": {"type": "string", "minLength": 1, "maxLength": 65535}, 9 | "parent_id": {"type": "string", "minLength": 1, "maxLength": 255, "format": "external-id"}, 10 | "thread_id": {"type": "string", "minLength": 1, "maxLength": 255, "format": "external-id"}, 11 | "created_at": {"type": "string", "maxLength": 255, "format": "date-time"}, 12 | "author": {"$ref": "#/definitions/author"}, 13 | "display_info": {"type": "array", "maxItems": 16, "items": {"$ref": "#/definitions/display_info"} }, 14 | "allow_channelback": {"type":"boolean"}, 15 | "fields": {"type": "array", "maxItems": 64, "items": {"$ref": "#/definitions/field_value"} }, 16 | "file_urls": {"type": "array", "maxItems": 64, "items": {"$ref": "#/definitions/file_url"} } 17 | }, 18 | "definitions": { 19 | "external_resource": { 20 | }, 21 | "author": { 22 | "type": "object", 23 | "required": ["external_id"], 24 | "properties": { 25 | "external_id": {"type": "string", "minLength": 1, "maxLength": 255, "format": "external-id"}, 26 | "name": {"type": "string", "minLength": 1, "maxLength": 255}, 27 | "image_url": {"type": "string", "minLength": 1, "maxLength": 511}, 28 | "locale": {"type": "string", "minLength": 1, "maxLength": 255}, 29 | "fields": {"type": "array", "maxItems": 64, "items": {"$ref": "#/definitions/field_value"} } 30 | } 31 | }, 32 | "display_info": { 33 | "type": "object", 34 | "required": ["type", "data"], 35 | "properties": { 36 | "type": {"type": "string", "minLength": 1, "maxLength": 255}, 37 | "data": {"type": "object"} 38 | } 39 | }, 40 | "field_value": { 41 | "type": "object", 42 | "required": ["id", "value"], 43 | "properties": { 44 | "id": {"type": ["integer", "string"], "minLength": 1, "maxLength": 255}, 45 | "value": {"type": "any"} 46 | } 47 | }, 48 | "file_url": { 49 | "type": "string", 50 | "format": "https-url", 51 | "maxLength": 511 52 | } 53 | } 54 | } 55 | --------------------------------------------------------------------------------