Frontend Integration
ThrillConnect
Connecting and Subscribing
- Player socket:
wss://<thrillconnect>/v1/events/{operator_id}/{brand_id}?token=<player_token>¤cy=<player_ccy>(player token is validated with ThrillGate). - After the socket is open, subscribe to ThrillDrops by sending:
{
"SubscribeRequest": {
"events": [
{ "source": "thrilldrops", "event_type": "*" }
]
}
}
event_type can be one of the individual names below or * to receive all ThrillDrops events.
Message Envelope
All ThrillDrops events are sent with msg_type: "Event" and source: "thrilldrops":
{
"msg_type": "Event",
"source": "thrilldrops",
"msg_name": "CampaignDropWin",
"operator_id": "thrilltech",
"brand_id": "brand1",
"player_id": "player_00001",
"data": { /* event-specific payload */ },
"timestamp": 1715355347345
}
- Player sockets receive messages matching their operator/brand. Service sockets receive all ThrillDrops messages.
timestampcomes from the originating ThrillDrops message header.
Event Catalogue
CampaignDropWin
- When: A player wins a reward in a ThrillDrops campaign.
- Recipients: Targeted to the winning player’s operator/brand (and any subscribed service sockets).
- msg_name:
CampaignDropWin - data:
reward_id: Unique reward identifier within ThrillTech.reward_valid_from: UNIX timestamp (ms) when the reward becomes valid.reward_valid_to: Optional UNIX timestamp (ms) when the reward expires.name: Reward name.currency: Currency code for the reward value.value: Reward amount (decimal).image: Optional URI to an image for the reward.animation: Optional animation name for the reward.- Note: The source event includes a
campaign_id, but it is not forwarded in the websocket payload.
- Example:
{
"msg_type": "Event",
"source": "thrilldrops",
"msg_name": "CampaignDropWin",
"operator_id": "thrilltech",
"brand_id": "brand1",
"player_id": "player_00001",
"data": {
"reward_id": "reward-abc",
"reward_valid_from": 1715355000000,
"reward_valid_to": 1715441400000,
"name": "First Deposit Award",
"currency": "EUR",
"value": "20.00",
"image": "https://cdn.example.com/rewards/deposit-reward.png",
"animation": "realMoney"
},
"timestamp": 1715355347345
}
CampaignStarted
- When: A ThrillDrops campaign moves into the started state.
- Recipients: Broadcast to every brand listed in the campaign’s
allowed_brands. - msg_name:
CampaignStarted - data:
campaign_id: Identifier of the campaign that started.
- Example:
{
"msg_type": "Event",
"source": "thrilldrops",
"msg_name": "CampaignStarted",
"operator_id": "thrilltech",
"brand_id": "brand1",
"player_id": null,
"data": { "campaign_id": "cmp_2024_05" },
"timestamp": 1715355347345
}
CampaignEnded
- When: A ThrillDrops campaign ends.
- Recipients: Broadcast to every brand listed in the campaign’s
allowed_brands. - msg_name:
CampaignEnded - data:
campaign_id: Identifier of the campaign that ended.
- Example:
{
"msg_type": "Event",
"source": "thrilldrops",
"msg_name": "CampaignEnded",
"operator_id": "thrilltech",
"brand_id": "brand1",
"player_id": null,
"data": { "campaign_id": "cmp_2024_05" },
"timestamp": 1715355347345
}
Animation Driver
ThrillTech supplies a default Drops win animation to enrich the player experience during a Drop win. The animations driver is a JS library that takes care of win animations loading and playback. Animations are easily customizable and the driver allows for flexible cusomizations of the playback.
Source
Source code is avaiable for review & fork for all ThrilTech customers. You can find the driver at https://github.com/thrilltech-io/drops-animations-driver.
Overview
The JS driver exposes two functions:
preload(config, tier, muted)- loads the required assets per pased configuration object. when muted, sounds will not be loaded.run(config, tier, imgUrl, muted)- starts the animation sequence defined in the configuration. run will do load if assets are not already loaded.
The preload function is intended to provide separation of the loading phase, so that in case of unreasonably slow connection, stale loading can be detected and acted upon (for example using a fallback alert / win message if assets load didnt complete in a certain period).
Mute state cannot be controlled after the animation is run. The current sound preference should be passed to the run ( and optionally preload ) and based on that the defined in configuration sfx are either loaded or not.
Usage
import { preload, run } from "./main.js"
const config = "/configs/example.json"
const tier = "realMoney"
const imgUrl = "https://cdn.example.com/rewards/deposit-reward.png"
const muted = false
preload(config, tier, muted).then(()=>{
run(config, tier, imgUrl, amount)
})
Configuration
See example configurations in ./public/configs
Following is a full possible configuration with all settings commented inline.
{
"dom": {
// optional - skip "top" section if no header is required
"top": {
// id of top container
"id": "top-container",
// messages to display during presentation phase
"message": {
"id":"top-message",
"loading": "Loading...",
"starting": "Mystery Drop",
"looping": "Congratulations"
}
},
// optional - skip "bottom" section if no footer is required
"bottom": {
// id of bottom container
"id": "bottom-container",
// action button
"button": {
// id of the action button
"id": "action-button",
// actions after tickup
"end": {
"close": "CLOSE"
}
}
},
// enable touch controls during phase
"touch": {
// touch during tickup acts as skip
"close": true
},
// drop animation skin -
// skin provided and customised by thrilltech
"drops": {
"realMoney":{
// path of the spine export containing the mini tier animation
"source": "/drops/realMoney/realMoney.json",
// prefix of the animation for this tier
"prefix": ""
}
}
}
}
SFX
Sfx playback is triggered on animation events. Events are defined in the animation sources. Config contains top-level sfx section that defines all the available sounds. All sounds are optional.
Sound sources are defined as an array. All elements of the array refer to the same sfx. The intention is to provide multiple sfx formats and the runtime will automatically pick the one supported on the client system. Recommended formats to use are webm, wav and mp3. wav has the widest support accross devices, but is not as optimal as webm and mp3 in terms of filesize.
"sfx": {
"intro": ["/sfx/base/epic/intro.webm", "/sfx/base/epic/intro.wav"],
"outro": ["/sfx/base/epic/outro.webm", "/sfx/base/epic/outro.wav"]
}