Messaging System Schemas

Docs

More information about Messaging System.

Messages

There are JSON schemas for each type of message that the Firefox Messaging System handles:

Together, they are combined into the Messaging Experiments via a script. This is the schema used for Nimbus experiments that target messaging features. All incoming messaging experiments will be validated against this schema.

Schema Changes

To add a new message type to the Messaging Experiments schema:

  1. Add your message template schema.

    Your message template schema only needs to define the following fields at a minimum:

    • template: a string field that defines an identifier for your message. This must be either a const or enum field.

      For example, the template field of Spotlight looks like:

      { "type": "string", "const": "spotlight" }
      
    • content: an object field that defines your per-message unique content.

    If your message requires targeting, you must add a targeting field.

    If your message supports triggering, there is a definition you can reference the MessageTrigger shared definition.

    The groups, frequency, and priority fields will automatically be inherited by your message.

  2. Ensure the schema has an $id member. This allows for references (e.g., { "$ref": "#!/$defs/Foo" }) to work in the bundled schema. See docs on bundling JSON schemas for more information.

  3. Add the new schema to the list in make-schemas.py.

  4. Build the new schema by running:

cd browser/components/newtab/content-src/asrouter/schemas/
../../../../../../mach python make-schemas.py
  1. Commit the results.

Likewise, if you are modifying a message schema you must rebuild the generated schema:

cd browser/components/newtab/content-src/asrouter/schemas/
../../../../../../mach python make-schemas.py

If you do not, the Firefox MS Schemas CI job will fail.

You can run this locally via:

cd browser/components/newtab/content-src/asrouter/schemas/
../../../../../../mach xpcshell extract-test-corpus.js
../../../../../../mach python make-schemas.py --check

This test will re-generate the schema and compare it to MessagingExperiment.schema.json. If there is a difference, it will fail. The test will also validate the list of in-tree messages with the same schema validator that Experimenter uses to ensure that our schemas are compatible with Experimenter.

Shared Definitions

Some definitions are shared across multiple schemas. Instead of copying and pasting the definitions between them and then having to manually keep them up to date, we keep them in a common schema that contains these defintitions: FxMsCommon.schema.json. Any definition that will be re-used across multiple schemas should be added to the common schema, which will have its definitions bundled into the generated schema. All references to the common schema will be rewritten in the generated schema.

The definitions listed in this file are:

  • Message, which defines the common fields present in each FxMS message;

  • MessageTrigger, which defines a method that may trigger the message to be presented to the user;

  • localizableText, for when either a string or a string ID (for translation purposes) can be used; and

  • localizedText, for when a string ID is required.

An example of using the localizableText definition in a message schema follows:

{
  "type": "object",
  "properties": {
    "message": {
      "$ref": "file:///FxMSCommon.schema.json#/$defs/localizableText"
      "description": "The message as a string or string ID"
    },
  }
}

Schema Tests

We have in-tree tests (Test_CFRMessageProvider, Test_OnboardingMessageProvider, and Test_PanelTestProvider), which validate existing messages with the generated schema.

We also have compatibility tests for ensuring that our schemas work in Experimenter. Experimenter uses a different JSON schema validation library, which is reused in the Firefox MS Schemas CI job. This test validates a test corpus from CFRMessageProvider, OnboardingMessageProvider, and PanelTestProvider with the same JSON schema validation library and configuration as Experimenter.

See how to run these tests above.