Plugins can store their website user settings via the REST API, and retrieve them later on. Those settings are submitted by users or plugins to the API, and validated with a schema.
What Are Plugin Settings?
Storing settings directly on Crisp systems, instead of relying on a local database, makes plugins extremely easy to build. A few lines of code, coupled with our API Libraries, can get you very far.
Settings schemas are built with JSON Schema, which let you easily restrict the types of each JSON key, their syntax with regular expressions, and much more.
Each website subscribed to your plugin has its own private settings. Your integration can acquire those settings (for each website), when it starts, or when a new website is subscribed (or settings get updated).
Your integration can also update those settings, for each subscribed website.
Manage Website Settings
Retrieve settings
Settings for each website should be retrieved when your plugin first starts, or when a plugin just subscribed to your plugin.
1. Retrieve settings on start
Upon starting the plugin, you should load up the settings of each website that is subscribed to your plugin.
Using the go-crisp-api
library (from the API Libraries guide, also make sure to follow the Quickstart guide), this gives:
// (Make sure that the client variable is set there)
func LoadWebsitesOnStart() {
var pageNumber uint
pageNumber = 0
resultCounter := -1
for resultCounter != 0 {
pageNumber++
resultCounter = 0
// Configure this to either 'true' or 'false' if you need to return settings for non-configured plugins as well
configured = true
websites, _, err := client.Plugin.ListAllConnectWebsites(pageNumber, configured)
if err == nil {
fmt.Printf("Loaded page #%d of website results (%d websites)", pageNumber, len(*websites))
for _, websiteItem := range *websites {
resultCounter++
// Here: store the website settings in-memory with: websiteItem.WebsiteID and websiteItem.Settings
}
} else {
fmt.Printf("Could not list bound websites because: %+v", err)
}
}
}
2. Refresh local settings whenever they get updated
Once your plugin is started, you need to schedule a background settings refresh, for the plugins that have just subscribed to your plugin, or updated their settings. This will also give you a chance to clear out the websites that unsubscribed as well.
Using the go-crisp-api
library, this gives:
func ScheduleMaintainWebsites() {
fmt.Printf("Scheduled websites maintain")
lastCheckTime := time.Now()
for {
// Check for settings changes every 20 seconds
// You may adjust this, but note that this counts against your daily quota
time.Sleep(20 * time.Second)
err := TickMaintainWebsites(lastCheckTime)
// If refresh failed, dont bump last check time to re-schedule it later.
// This avoids losing some ops in the wild.
if err == nil {
lastCheckTime = time.Now()
}
}
}
func TickMaintainWebsites(lastCheckTime time.Time) (error) {
// List websites differential
fmt.Printf("Fetching websites maintain list since: %d", lastCheckTime)
// Configure this to either 'true' or 'false' if you need to return settings for non-configured plugins as well
configured = true
websites, _, err := client.Plugin.ListConnectWebsitesSince(lastCheckTime, configured)
if err == nil {
countResults := len(*websites)
if countResults > 0 {
fmt.Printf("Fetched websites maintain list with changes (%d websites)", countResults)
for _, websiteItem := range *websites {
switch *websiteItem.Difference {
case "added":
// Here: store the website settings in-memory with: websiteItem.WebsiteID and websiteItem.Settings
case "updated":
// Here: update the website settings in-memory with: websiteItem.WebsiteID and websiteItem.Settings
case "removed":
// Here: remove the website settings from memory
}
}
} else {
fmt.Printf("Fetched websites maintain list without changes")
}
} else {
fmt.Printf("Could not fetch websites maintain list because: %+v", err)
}
return err
}
Now, at the end of the LoadWebsitesOnStart()
method, add:
func LoadWebsitesOnStart() {
// <previous code eluded>
// Maintain list of websites up to date in time
// Important: start this in a Goroutine
go ScheduleMaintainWebsites()
}
ScheduleMaintainWebsites()
should be called after the initial LoadWebsitesOnStart()
of settings has completed. It must be called in a Goroutine background task, as not to block e the main thread.plugin:settings:saved
event from the RTM API, and avoid polling the REST API for settings updates too frequently. However, this will not provide you with a list of websites that uninstalled your plugin, therefore you would need to keep polling, but much less frequently, eg. every 10 minute (for cleanup purposes).Update settings
Whenever settings need to be updated for a given website, you may re-submitted them to the REST API, as a single JSON object.
Make sure that the settings submitted are valid against your settings schema, otherwise the REST API will reject your save request with an error.
Using the go-crisp-api
library, this gives:
// This structure contains example settings keys that map to JSON
// Adjust it with your own settings structure
type pluginSettings struct {
AccessToken string `json:"access_token"`
EnableAlerts bool `json:"enable_alerts"`
}
func CommitPluginSettings(pluginID string, websiteID string, settings pluginSettings) (error) {
fmt.Printf("Saving plugin settings for website: %s with data: %+v", websiteID, settings)
// Commit subscription settings
// You need to pass your Plugin ID, as well as Website ID there
_, err := client.Plugin.SaveSubscriptionSettings(websiteID, pluginID, settings)
if err != nil {
fmt.Printf("Failed saving plugin settings for website: %s with data: %+v, because: %s", websiteID, settings, err)
}
return err
}
TickMaintainWebsites()
call that will occur to refresh the settings. For most integrations, waiting for the next REST API poll request is probably more convenient and less error-prone.Settings Schemas
Settings schema let the REST API validate settings data that either users or your plugin attempt to save. The settings schema is pre-configured in advance, and is defined using JSON Schema.
Settings schema examples
An in-depth guide page is dedicated to providing plugin settings schema examples. You may read this guide on Examples.
Validating my schema
Before you can save your schema in the Marketplace, you need to make sure they are valid against the JSON Schema specification.
The Marketplace lets you do this easily:
- Go to the Crisp Marketplace;
- Select your plugin, and go to the Settings tab;
- In the Settings section, enter your schema data;
- Hit the Test Settings button;
- Your schema may either be confirmed as valid, or invalid (we provide an explanation of what's wrong in this case);
Configuring the plugin schema
After you validated your plugin schema from the Marketplace, the Save Settings button becomes clickable.
Simply click on the Save Settings button. Once saved, scroll up and create a new Submission in the notification that shows.