Skip to content

Integration | Joystick for Google Sheets™ Usage

Transform the way operate your app or game; save hours of time. Ever wish you could make a change in Google Sheets™ then it is instantly reflected in your app or game?

Export content from any Google Sheets™ document as JSON into Joystick with one click. Joystick for Google Sheets™ gives you and your team direct control of your app or game. Make changes in your spreadsheet, then instantly have configuration and parameter updates available to your application at scale over our powerful API platform. No waiting.

Benefits of Joystick for Google Sheets™

Joystick for Google Sheets™ helps you take data in any Google Sheets™ document the exported it seamlessly as JSON into Joystick with one-click. It is then immediately available for delivery at scale so your app, game or system. Access configuration updates as soon as they are made in Google Sheets™!

  • One-click export from Google Sheets™ as JSON into Joystick for distribution at scale.
  • Define and export to multiple JSON configurations from the same Google Sheets™ document.
  • Each config can be built from multiple tables and named ranges of the Google Sheets™ document; you are not restricted to just one data table per config.
  • Create and export complex JSON structures, not just single-level tables.
  • Schema and data type validation and protection; no headaches about missing data or type mismatches.

Core Concepts and Features

Gsheets Schematic

There are three components to setup.

Component Description
Joystick for Google Sheets™ Add-on You have to install, give permissions and configure the Google Add-on.
Data Transform Definition The Data Transform Definition config contains the schema and instructions on how to map the tabular data in Google Sheets™ to JSON. This should be a config placed in Joystick, in the same environment that you want to push to.
Target Content in Joystick This is the final output config(s) that is going to available for delivery over the Joystick API.

Setting Up Joystick for Google Sheets™

Install the Add-on

If you have not installed the add-on, view our installation guide first.

Accessing Settings

Clicking "Settings" when the add-on panel is open.

Accessing Settings

Settings: Add the API Key

Add an API Key generated in the environment your target config ContentId is held.

API Key Note

  • The API key must be created with Read + Write permissions.

Set API Key

Settings: Add the Data Transform Definition

Before you can use Joystick for Google Sheets™, you have to create a data transform definition config, placed in the same environment you plan to push the Google Sheets™ data to. After you have created that config, you need to add it to the connector settings. See "The Data Transform Definition" section below for how to create the data mapping config.

Note

  • The environment must already contain a config with the ContentId that you want to push in from Google Sheets. i.e. You cannot create a brand new ContentId using the add-on.
  • The ContentId of the Data Transform Definition is not that of your target/output config.

Add Data Transform Definition

Usage

When everything is setup, you will see two green indicators on the homepage of the add-on. Simply click the orange "Push Content to Joystick" button to use the add-on to push data into Joystick.

Read to Use

The Data Transform Definition

The Data Transform Definition is a configuration (JSON format) that specifies how to transform and compose the tabular data in your Google Sheets™ document as one or more pieces of JSON content.

Saving the Data Transform Definition

You must save the Data Transform Definition in Joystick. Make sure it is in the same environment as the other pieces of content you want to push to from your Google Sheets™ document.

Explaining the Data Transform Definition

The root of the Data Transform Definition is the dataBlocks array of objects.

{
    "dataBlocks":[{}]
}

Each object in the array represents one config or piece of content you want to push to from your Google Sheet

{
    "dataBlocks":[
        {
            "contentId": "",
            "template": {},
            "components": {}
        }
    ]
}

Parameter Description
contentId The contentId for the target piece of content to push to.
template The template is the structure of your output JSON. The template can integrate one or more components. It will have dynamic declarations using the convention of #...# where the dynamic data from your google sheets document should placed (see below for details). You must have a template defined.
components A Component defines how to take the tabular data in your Google Sheets™ document then structure it as JSON for export. You can define multiple components, then stich/compose them together in one final output JSON. You must have at least one component defined.

This is the most basic 'skeleton' setup with a simple template. The location of the value #data_table# will be replaced by a components object defined with the same parameter name, in this case components.data_table.

{
    "dataBlocks": [
        {
            "contentId": "myContent",
            "template": {
                "myData": "#data_table#"
            },
            "components": {
                "data_table": {}
            }
        }
    ]
}

Putting it all Together

Below you can see a simple data table in Google Sheets™ with some annotations.

Please Note

For "table", you must have a row above your data table where there is a label that corresponds to where the data should go within the component. In the screenshot these are in orange. In the Data Transform Definition, you can see them under the properties object.

Sample Google Sheet

View Sample Google Sheets™ Document for this example.

{
    "dataBlocks": [
        {
            "contentId": "city-information", // The destination ContentId in Joystick
            "template": { // The template with the shape of the destination content.
            "cities": "#cities#"
        },
            "components": {
                "cities": {
                    "type": "table",
                    "source": "sheet",
                    "sheetName": "City Information", // If source is "sheet", this is the sheet name on the Google Sheets bottom tab
                    "propertiesLabelRow": 3, // The row in the data range where the property labels are. If not defined, default is 1.
                    "dataStartRow": 9, // The row in the data range where the first row of data to be exported is.
                    "properties": // Matches basic JSON Schema structure.
                    {
                        "cityName": {
                            "type": "string",
                            "ignoreRowIfEmpty": true
                        },
                        "info": {
                            "type": "object",
                            "properties": {
                                "country": {
                                "type": "string"
                                },
                                "population": {
                                "type": "string"
                                },
                                "area": {
                                "type": "number"
                                },
                                "timezone": {
                                "type": "string"
                                }
                            }
                        }
                    }
                }
            }
        }
    ]
}
{
    "cities": [
        {
            "cityName": "Vancouver",
            "info": {
                "country": "Canada",
                "population": "700000",
                "area": 115,
                "timezone": "UTC -8"
            }
        },
        {
            "cityName": "Toronto",
            "info": {
                "country": "Canada",
                "population": "2900000",
                "area": 630,
                "timezone": "UTC -5"
            }
        },
        {
            "cityName": "Valencia",
            "info": {
                "country": "Spain",
                "population": "800000",
                "area": 134,
                "timezone": "UTC +1"
            }
        },
        {
            "cityName": "Venice",
            "info": {
                "country": "Italy",
                "population": "260000",
                "area": 414,
                "timezone": "UTC +1"
            }
        },
        {
            "cityName": "Tokyo",
            "info": {
                "country": "Japan",
                "population": "13960000",
                "area": 2194,
                "timezone": "UTC +9"
            }
        }
    ]
}

Extended Example with All Features

Below is a full example showing the three components: Google Sheet, Data Transform Definition Config and the Output JSON.

What's happening...

  • The extended example shows a single piece of content (Final Result) being built from three separate Google Sheets™ document tabs.
  • "Level 3" in the final result is skipped because the Opponent Id is empty on that row and ignoreRowIfEmpty is applied to that field.

Features Available

  • Data can come from a sheet/tab.
  • Data can come from a named range.
  • Build rich, multi-level objects in JSON.
  • The final output JSON can be assembled using data from multiple locations within the Google Sheets™ document.
  • The data transformation/mapping is described by the straight-forward Data Transform Definition.

View Sample Google Sheets™ Document

{
    // This example shows only one output content.
    // Each Data Transform Definition can output to multiple different pieces of content/configs.
    // Add more items to the "dataBlocks" array to do this.
    "dataBlocks": [
        {
            "contentId": "gsheets_sandbox", // The destination ContentId in Joystick. This must be already created.
            "template": { // The template with the shape of the intended JSON content.
                "singleData": [
                    {
                        "text": "Static text." // You can have static entries in the template.
                    },
                    {
                        "singleDataString": "#my_greeting#", // In the template, the #...# convention declares where dynamic data from the Google Sheets document should be used.
                        "singleDataNumber": "#my_number#", // Each #...# links to one component defined in the "components" object.
                        "singleArrayOfBoolean": [
                            "#my_boolean#"
                        ]
                    }
                ],
                "myGameData": {
                    "gameSettings": "#my_game_settings#",
                    "levels": "#my_levels#"
                }
            },
            "components": {
                "my_greeting": {
                    "type": "string", // can be "table", "dict", "string", "boolean", "number"
                    "source": "namedRange", // Can be "sheet", "namedRange"
                    "rangeName": "myGreeting" // If source is "namedRange", the name of the Named Range in the Google Sheet
                },
                "my_number": {
                    "type": "number",
                    "source": "namedRange",
                    "rangeName": "myNumber"
                },
                "my_boolean": {
                    "type": "boolean",
                    "source": "namedRange",
                    "rangeName": "myBoolean"
                },
                "my_levels": {
                    "type": "table",
                    "source": "sheet",
                    "sheetName": "Game Levels", // If source is "sheet", this is the sheet name on the Google Sheets™ bottom tab
                    "propertiesLabelRow": 3, // The row in the data range where the property labels are
                    "dataStartRow": 7, // The row in the data range where the first row of data to be exported is.
                    "properties": { // Matches basic JSON Schema structure.
                        "level": {
                            "type": "number",
                            "ignoreRowIfEmpty": true // if this is set, an entire row will be ignore if this property is empty.
                        },
                        "name": {
                            "type": "string",
                            "allowEmpty": true // If this is true, the property will be set even if in the Google Sheet it is a blank cell.
                        },
                        "theme": {
                            "type": "object",
                            "properties": {
                                "background": {
                                    "type": "string"
                                },
                                "foreground": {
                                    "type": "string"
                                },
                                "playMusic": {
                                    "type": "boolean",
                                    "allowEmpty": true
                                },
                                "trackName": {
                                    "type": "string",
                                    "allowEmpty": true
                                },
                                "trackId": {
                                    "type": "number",
                                    "allowEmpty": true
                                }
                            }
                        },
                        "goals": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "points": {
                                        "type": "number"
                                    }
                                }
                            }
                        },
                        "opponent": {
                            "type": "object",
                            "properties": {
                                "name": {
                                    "type": "string"
                                },
                                "id": {
                                    "type": "number",
                                    "ignoreRowIfEmpty": true
                                },
                                "hp": {
                                    "type": "number"
                                },
                                "boosted": {
                                    "type": "boolean"
                                },
                                "abilities": {
                                    "type": "array",
                                    "items": {
                                        "type": "string"
                                    }
                                }
                            }
                        }
                    }
                },
                "my_game_settings": {
                    "type": "dict", // Use this for a list of key:value pairs.
                    "source": "namedRange",
                    "rangeName": "myGameSettings",
                    "propertiesLabelRow": "2",
                    "dataStartRow": 5,
                    "properties": {
                        "gravity": {
                            "type": "number"
                        },
                        "movementSpeed": {
                            "type": "number",
                            "allowEmpty": true
                        },
                        "randomSpawn": {
                            "type": "boolean"
                        },
                        "mainBackgroundImage": {
                            "type": "string",
                            "allowEmpty": true
                        }
                    }
                }
            }
        }
    ]
}
{
    "singleData": [
        {
            "text": "Static text."
        },
        {
            "singleDataString": "Hello, world!",
            "singleDataNumber": 3.1415,
            "singleArrayOfBoolean": [
                false
            ]
        }
    ],
    "myGameData": {
        "gameSettings": {
            "gravity": 200,
            "movementSpeed": 12,
            "randomSpawn": true,
            "mainBackgroundImage": "forest.jpg"
        },
        "levels": [
            {
                "level": 1,
                "name": "First Level",
                "theme": {
                    "background": "stars.jpg",
                    "foreground": "purple",
                    "playMusic": true,
                    "trackName": "Forest Sounds",
                    "trackId": 1
                },
                "goals": [
                    {
                        "name": "Good",
                        "points": 100
                    },
                    {
                        "name": "Great",
                        "points": 200
                    },
                    {
                        "name": "Excellent",
                        "points": 300
                    }
                ],
                "opponent": {
                    "id": 1,
                    "name": "Heavy Hippo",
                    "boosted": true,
                    "hp": 837,
                    "abilities": [
                        "Lightning",
                        "Cloak"
                    ]
                }
            },
            {
                "level": 2,
                "name": "Beginner",
                "theme": {
                    "background": "sunnyday.jpg",
                    "foreground": "green",
                    "playMusic": null,
                    "trackName": "",
                    "trackId": null
                },
                "goals": [
                    {
                        "name": "Good",
                        "points": 150
                    },
                    {
                        "points": 300
                    },
                    {
                        "name": "Excellent",
                        "points": 600
                    }
                ],
                "opponent": {
                    "id": 2
                }
            },
            {
                "level": 4,
                "name": "Advanced",
                "theme": {
                    "background": "dusk.jpg",
                    "foreground": "blue",
                    "playMusic": true,
                    "trackName": "Desert Sounds",
                    "trackId": 3
                },
                "goals": [
                    {
                        "name": "Good",
                        "points": 500
                    },
                    {
                        "name": "Great",
                        "points": 900
                    },
                    {
                        "name": "Excellent",
                        "points": 1900
                    }
                ],
                "opponent": {
                    "id": 4,
                    "name": "Eli the Elephant",
                    "boosted": true,
                    "hp": 12000,
                    "abilities": [
                        "Earthquake"
                    ]
                }
            }
        ]
    }
}