Adapters
An adapter, such as described previously, is defined using the Adapter
class exposed by the JavaScript file present at the following address:
https://obs.multistream.tools/v1/adapters.js
This file/module also exports a number of handy constants and utilities for modeling adapters for platforms of your choice.
The API described below allows you to develop your own adapters to add support for any platform to our generic system. You are free to implement these, for example, directly using the Twitch API or any other available online. Your adapters will simply need to be executed in HTML pages served over HTTPS and respect at least the expected data types.
API
The TypeScript signature of the Adapter
class is as follows:
type Id = string;
type Event = string;
type Alerts = Event[];
type Filters = {
alerts?: false;
chat?: false;
session?: true;
other?: true;
[key: Event]: false;
};
declare class Platform {
constructor(filters?: Filters, extraAlerts?: Alerts);
get id(): Id;
has(event: Event): boolean;
}
type AlertData = {
name: string;
sender?: string;
message?: string;
tier?: string;
amount?: number;
};
type SessionData = {
[key: string]: object | object[];
};
type LoadData = {
session: SessionData;
};
type ChatData = object;
type MessageData = {
renderedText: string;
data: {
userId: Id;
msgId: Id;
nick: string;
displayName: string;
};
};
type DeleteMessageData = {
msgId: Id;
};
type DeleteMessagesData = {
userId: Id;
};
type OtherData = object;
declare class Adapter {
constructor(PlatformClass: typeof Platform, filters?: Filters, extraAlerts?: Alerts);
has(event: Event): boolean;
load(data: LoadData): void;
session(data: SessionData): void;
alerts(event: Event, data: AlertData, group?: Id, root?: true): void;
chat(event: Event, data: ChatData): void;
message(data: MessageData): void;
'delete-message'(data: DeleteMessageData): void;
'delete-messages'(data: DeleteMessagesData): void;
other(event: Event, data: OtherData): void;
$load?(data: LoadData): void | LoadData;
$session?(data: SessionData): void | SessionData;
$alerts?(data: AlertData, event: Event, group?: Id, root?: true): void | AlertData;
$chat?(data: ChatData, event: Event): void | ChatData;
$other?(data: OtherData, event: Event): void | OtherData;
}
The data structures (type
) listed above describe all the mandatory and optional properties that must be present, you can obviously add new ones!
Parameters
Each parameter listed below can no longer be modified once the adapter has been instantiated (read-only).
An adapter needs to be linked to a platform so that the system can identify the source of the emitted events; this is the role of the first parameter named PlatformClass
referring to a platform constructor that the adapter will be responsible for instantiating.
import {
Platform,
Adapter
} from 'https://obs.multistream.tools/v1/adapters.js';
class CustomPlatform extends Platform {
constructor(...args) {
super('custom', ['alert'], ...args);
}
}
class CustomPlatformAdapter extends Adapter {
constructor(...args) {
super(CustomPlatform, ...args);
// Implement custom integration logic here.
}
}
The optional filters
and extraAlerts
parameters will be directly passed to the PlatformClass
constructor for which they are intended.
import {
Platform,
Adapter
} from 'https://obs.multistream.tools/v1/adapters.js';
const customAlert = 'alert';
class CustomPlatform extends Platform {
constructor(...args) {
super('custom', [customAlert], ...args);
}
}
class CustomAdapter extends Adapter {
constructor(PlatformClass, filters) {
super(PlatformClass, filters, ['commonAlert']);
// Implement custom integration logic here.
}
}
const customPlatformAdapter = new CustomAdapter(CustomPlatform, {
[customAlert]: false
});
Methods
The method named has
is a simple proxy to that of the instance of the Platform
class associated with the adapter.
Events emitted by a platform must be sorted according to categories in order to be processed correctly by our system. This sorting is carried out at the adapter level in its custom integration logic. The system categories are as follows:
'load'
; the load event must be emitted only once to indicate that the platform has been loaded correctly'session'
; the session event should be emitted each time that the platform-related session data has been modified, generally after each alert'alerts'
; the alerts event must be emitted for each alert triggered on the platform by the action of a spectator'chat'
; the chat event must be emitted for each message posted or deleted in the platform's chat'other'
; the other event can be emitted to cover possible other cases
The methods present on an instance of the Adapter
class correspond to the categories listed above and are therefore intended to be called at the right time and with the right data so that the associated events can pass correctly through our system.
import {
subscriber,
message,
botCounter,
Twitch,
Adapter
} from 'https://obs.multistream.tools/v1/adapters.js';
class CustomAdapter extends Adapter {
constructor(PlatformClass, ...args) {
super(PlatformClass, ...args);
// Implement custom integration logic here.
this.load({ session: { /* ... */ } });
}
}
const customTwitchAdapter = new CustomAdapter(Twitch);
const name = 'TheFrenchBiff';
const subscriberData = { name };
customTwitchAdapter.alerts(subscriber, subscriberData);
customTwitchAdapter.session({ [`${subscriber}-latest`]: subscriberData });
customTwitchAdapter.chat(botCounter, { counter: 'power', value: 9001 });
const userId = crypto.randomUUID();
const msgId = crypto.randomUUID();
customTwitchAdapter.message({
renderedText: `test ${message}`,
data: {
userId,
msgId,
nick: name.toLowerCase(),
displayName: name
}
});
customTwitchAdapter['delete-message']({ msgId });
customTwitchAdapter['delete-messages']({ userId });
customTwitchAdapter.other('notCategorized', { /* ... */ });
The optional parameters, named group
and root
, of the alerts
method allow linking several events together, in particular for display in our dock. A root event - indicated by the root
parameter - must always be emitted first, followed by all those to be grouped; the value of the group
parameter must therefore be a unique identifier shared by all these events. This can be used for example in the case of gifted subscriptions:
const group = crypto.randomUUID();
customTwitchAdapter.alerts(subscriber, { name, amount: 2 }, group, true);
customTwitchAdapter.alerts(subscriber, { name: 'userA', sender: name }, group);
customTwitchAdapter.alerts(subscriber, { name: 'userB', sender: name }, group);
The message
, delete-message
and delete-messages
methods internally call the chat
method by passing respectively 'message'
, 'delete-message'
and 'delete- messages'
to it as its first parameter for greater convenience. These are therefore preferred shortcuts.
The optional $load
, $session
, $alerts
, $chat
and $other
methods allow transforming the received data before it is sent to our system. This can be useful to fix possible consistency issues, either by directly mutating the data
object passed as the first parameter, or by returning a new object. These methods are never called for alerts/categories disabled through filters
.
For a practical example, go to our page dedicated to adapter development.
Pre-configured adapters
We provide the following adapters exposed by the same JavaScript file cited throughout this page. To view their respective installation instructions, go to the dedicated page.
class | platform | integration |
---|---|---|
FacebookStreamElementsAdapter | Facebook | StreamElements |
TrovoStreamElementsAdapter | Trovo | StreamElements |
TwitchStreamElementsAdapter | Twitch | StreamElements |
YouTubeStreamElementsAdapter | YouTube | StreamElements |
TikFinityAdapter | TikTok | TikFinity |
Their TypeScript signatures are as follows:
type WidgetLoadData = {
session: {
data: SessionData;
};
};
type SessionUpdateData = {
session: SessionData;
};
type EventReceivedData = {
listener: Event;
event: AlertsData | ChatData | OtherData;
};
declare class StreamElementsAdapter extends Adapter {
constructor(PlatformClass: typeof Platform, filters?: Filters);
$load(data: LoadData): void | LoadData;
$alerts(data: AlertData, event: Event, group?: Id, root?: true): void | AlertData;
onWidgetLoad(data: WidgetLoadData): void;
onEventReceived(data: EventReceivedData): void;
onSessionUpdate(data: SessionUpdateData): void;
}
declare class FacebookStreamElementsAdapter extends StreamElementsAdapter {
constructor(filters?: Filters);
}
declare class TrovoStreamElementsAdapter extends StreamElementsAdapter {
constructor(filters?: Filters);
}
declare class TwitchStreamElementsAdapter extends StreamElementsAdapter {
constructor(filters?: Filters);
}
declare class YouTubeStreamElementsAdapter extends StreamElementsAdapter {
constructor(filters?: Filters);
}
type ChatEventData = {
comment: string;
userId: Id;
msgId: Id;
uniqueId: string;
nickname: string;
};
type LikeEventData = {
nickname: string;
likeCount: number;
};
type ShareEventData = {
nickname: string;
};
type GiftEventData = {
repeatEnd: boolean;
nickname: string;
giftName: string;
diamondCount: number;
};
type FollowerEventData = {
nickname: string;
};
type SubscriberEventData = {
nickname: string;
subMonth: number;
};
declare class TikFinityAdapter extends Adapter {
constructor(filters?: Filters);
load(): void;
message(data: ChatEventData): void;
like(data: LikeEventData): void;
share(data: ShareEventData): void;
gift(data: GiftEventData): void;
follower(data: FollowerEventData): void;
subscriber(data: SubscriberEventData): void;
}
The onWidgetLoad
, onEventReceived
and onSessionUpdate
methods of the StreamElementsAdapter
class correspond to the events of custom widgets, functionality offered by the StreamElements third-party service.
The data passed to the methods of the TikFinityAdapter
class correspond to the data sent by the TikTok Live Connector library, functionality offered by the TikFinity third-party Windows desktop application.
Ready-to-use adapters
We provide the following adapters, ready-to-use and customizable. These are open source and can therefore also be used as examples for creating your own adapters.
📄️ TikFinity
This adapter, ready to use in our dock, allows you to receive events from the TikTok platform via the TikFinity Windows desktop application; it is therefore necessary to configure the latter on the same computer as your OBS installation, create an account, and take care to start it for each stream.