### Extension with Deck Installation
Source: https://context7.com/sammisolutions/sammi-official/llms.txt
An example of a SAMMI extension that includes deck JSON for automatic button installation.
```APIDOC
## Extension with Deck Installation
Extensions can include deck JSON to automatically install buttons when the extension is added.
```
[extension_name]
Alert System Extension
[extension_info]
Provides customizable alert overlays
[extension_version]
2.0.0
[insert_external]
Alert System v2.0 - Ready
[insert_command]
SAMMI.extCommand('Show Custom Alert', 0x4488FF, 52, {
alertTitle: ['Title', 14, 'New Alert!'],
alertBody: ['Message', 0, 'Alert content here...'],
alertDuration: ['Duration (sec)', 14, '5']
}, false, false);
[insert_hook]
case 'Show Custom Alert':
showCustomAlert(SAMMIJSON.alertTitle, SAMMIJSON.alertBody, SAMMIJSON.alertDuration);
break;
[insert_script]
async function showCustomAlert(title, body, duration) {
const alertData = {
title: title,
message: body,
displayTime: parseInt(duration) * 1000
};
await SAMMI.setVariable('currentAlert', alertData);
await SAMMI.triggerExt('AlertTriggered', alertData);
SAMMI.alert('Alert displayed: ' + title);
}
[insert_over]
{"deck_name":"Alert Deck","sammi_version":"2024.2.0","bridge":true}
```
```
--------------------------------
### SAMMI Extension with Deck Installation
Source: https://context7.com/sammisolutions/sammi-official/llms.txt
An example of a SAMMI extension that includes deck JSON for automatic button installation upon extension addition. It defines a custom alert command and its associated script.
```text
[extension_name]
Alert System Extension
[extension_info]
Provides customizable alert overlays
[extension_version]
2.0.0
[insert_external]
Alert System v2.0 - Ready
[insert_command]
SAMMI.extCommand('Show Custom Alert', 0x4488FF, 52, {
alertTitle: ['Title', 14, 'New Alert!'],
alertBody: ['Message', 0, 'Alert content here...'],
alertDuration: ['Duration (sec)', 14, '5']
}, false, false);
[insert_hook]
case 'Show Custom Alert':
showCustomAlert(SAMMIJSON.alertTitle, SAMMIJSON.alertBody, SAMMIJSON.alertDuration);
break;
[insert_script]
async function showCustomAlert(title, body, duration) {
const alertData = {
title: title,
message: body,
displayTime: parseInt(duration) * 1000
};
await SAMMI.setVariable('currentAlert', alertData);
await SAMMI.triggerExt('AlertTriggered', alertData);
SAMMI.alert('Alert displayed: ' + title);
}
[insert_over]
{"deck_name":"Alert Deck","sammi_version":"2024.2.0","bridge":true}
```
--------------------------------
### Deck Installation JSON Keys for SAMMI
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/How to make an extension.txt
These keys can be added to your exported deck JSON to enable additional checks during extension installation. They help ensure compatibility with SAMMI version, bridge connection, OBS WebSocket, and required extensions.
```json
{
"sammi_version": "2.00.0",
"bridge": true,
"obswebsocket": "4.9.1",
"donot_include_deck": false,
"extension_triggers": ["TRG1", "TRG", ...],
"required_extension": ["Extension name", "Another extension name", ...]
}
```
--------------------------------
### Get Current Installed Extensions (JavaScript)
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/default.txt
Retrieves a list of currently installed extensions by querying the DOM. It filters out specific tab titles and extracts extension names and versions.
```javascript
function getCurrentExtensions() {
const tabs = document.querySelectorAll('#extensions-tabContent > .tab-pane');
const currentExtensions = [];
tabs.forEach((tab) => {
const tabTitle = tab.dataset.title.toLowerCase(); // Convert tab title to lowercase
if (['twitch triggers', 'youtube triggers', 'extensions', 'settings'].includes(tabTitle) || tabTitle === '') return;
currentExtensions.push({
extension_name: tab.dataset.title,
current_version: tab.getAttribute('data-version'),
});
});
return currentExtensions;
}
```
--------------------------------
### Initialize and Render Extension Table - JavaScript
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/default.txt
This snippet initializes the necessary DOM elements and global variables for managing extensions. It handles the case where no extensions are installed by displaying a message and hiding the extension table. For installed extensions, it sorts them, iterates through each, fetches corresponding latest version data, and dynamically creates table rows with details like name, author, versions, and update/download links. It also populates a global object `window.extensionVersions` for SAMMI integration and updates the overall status indicator.
```javascript
const tbody = document.getElementById('extensionTableBody');
const extensionTable = document.getElementById('extensionTable');
const versionSpan = document.getElementById('extensions_status');
const extensionIcon = document.getElementById('extensions_icon');
window.extensionVersions = {}; // Add this line to create a new object
let allUpToDate = true; // Flag to track if all extensions are up to date
// If there are no current extensions installed
if (currentExtensions.length === 0) {
const extensionTab = document.getElementById('content-extensions');
// Remove the table
extensionTable.style.display = 'none';
// Create a paragraph element and set its text
const p = document.createElement('p');
p.innerText = 'No extensions installed.';
// Append the paragraph to the body
extensionTab.appendChild(p);
versionSpan.innerText = 'No extensions installed.'; // Set the text of the version status
return; // Exit the function
}
currentExtensions.sort((a, b) => a.extension_name.localeCompare(b.extension_name));
currentExtensions.forEach((current) => {
const latest = extensionData.find((e) => {
const extensionNameMatch = e.extension_name.toLowerCase().trim() === current.extension_name.toLowerCase().trim();
const alternateNamesMatch = e.alternate_names ? e.alternate_names.map((n) => n.toLowerCase().trim()).includes(current.extension_name.toLowerCase().trim()) : false;
return extensionNameMatch || alternateNamesMatch;
});
const row = document.createElement('tr');
// Create the cell for the extension name
const nameCell = document.createElement('td');
nameCell.innerText = current.extension_name;
nameCell.style.cursor = 'pointer'; // make the cursor pointer
nameCell.title = latest && latest.details.description ? latest.details.description : 'No description available'; // set tooltip text
nameCell.addEventListener('click', () => {
const tabId = `content-${current.extension_name.replace(/ /g, '_')}-tab`;
const tabElement = document.getElementById(tabId);
const bsTab = new bootstrap.Tab(tabElement);
bsTab.show();
});
row.appendChild(nameCell);
// Author cell
const authorCell = document.createElement('td');
authorCell.className = 'd-none d-sm-table-cell';
authorCell.title = 'Extension Author';
authorCell.innerText = latest ? latest.details.author : 'N/A';
row.appendChild(authorCell);
// Current version cell
const currentVersionCell = document.createElement('td');
currentVersionCell.title = 'Installed Version';
currentVersionCell.innerText = current.current_version !== 'unknown' ? current.current_version : 'N/A';
row.appendChild(currentVersionCell);
// Latest version cell
const latestVersionCell = document.createElement('td');
latestVersionCell.title = 'Latest Version';
latestVersionCell.innerText = latest ? latest.details.latest_version : 'N/A';
row.appendChild(latestVersionCell);
// save to object to send to SAMMI
const extensionNameKey = toPascalCase(current.extension_name); // Convert extension name to Pascal Case key
window.extensionVersions[extensionNameKey] = {
latest: latest ? latest.details.latest_version : 'N/A',
current: current.current_version,
};
// Download/Update cell
const downloadCell = document.createElement('td');
if (latest && latest.details.download_link !== '') {
const updateAvail = !compareVersions(current.current_version, latest.details.latest_version);
downloadCell.innerHTML = `
${updateAvail ? 'Update' : 'Download'}
`;
} else {
// place holder to maintain table dimensions
downloadCell.innerHTML = `
Placeholder
`;
}
row.appendChild(downloadCell);
if (!latest) {
row.style.backgroundColor = '#afab68';
} else if (!compareVersions(current.current_version, latest.details.latest_version)) {
allUpToDate = false;
}
tbody.appendChild(row);
});
if (allUpToDate) {
extensionIcon.className = 'fas fa-check-circle me-1 d-md-none';
extensionIcon.style.color = '#4ad84a';
extensionIcon.title = 'Updates available';
versionSpan.innerText = 'All up to date';
versionSpan.style.color = '#4ad84a';
} else {
extensionIcon.className = 'fas fa-exclamation-circle me-1 d-md-none';
// The original code snippet was cut off here, assuming it would set appropriate styles/text for non-up-to-date status.
}
```
--------------------------------
### Get Current Installed Extensions (JavaScript)
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/bridge.html
A function to retrieve information about currently installed extensions by querying the DOM. It selects all elements with the class 'tab-pane' within the '#extensions-tabContent' element and extracts relevant data for each tab. This is used to determine which extensions are active.
```javascript
function getCurrentExtensions() {
const tabs = document.querySelectorAll('#extensions-tabContent > .tab-pane');
const currentExtensions = [];
tabs.forEach((tab) => {
const tabTit
```
--------------------------------
### Populate Extension Table and Manage Updates (JavaScript)
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/bridge.html
This JavaScript function populates an HTML table with extension data, compares installed versions with the latest available versions, and provides download/update links. It handles cases with no installed extensions and updates the UI to reflect the overall extension status. Dependencies include `bootstrap` for tab functionality, `compareVersions` for version comparison, and `toPascalCase` for key formatting.
```javascript
async function populateExtensionTable() {
const extensionData = await getExtensionsData();
const currentExtensions = getCurrentExtensions();
const tbody = document.getElementById('extensionTableBody');
const extensionTable = document.getElementById('extensionTable');
const versionSpan = document.getElementById('extensions_status');
const extensionIcon = document.getElementById('extensions_icon');
window.extensionVersions = {}; // Add this line to create a new object
let allUpToDate = true; // Flag to track if all extensions are up to date
// If there are no current extensions installed
if (currentExtensions.length === 0) {
const extensionTab = document.getElementById('content-extensions');
// Remove the table
extensionTable.style.display = 'none';
// Create a paragraph element and set its text
const p = document.createElement('p');
p.innerText = 'No extensions installed.';
// Append the paragraph to the body
extensionTab.appendChild(p);
versionSpan.innerText = 'No extensions installed.';
// Set the text of the version status
return; // Exit the function
}
currentExtensions.sort((a, b) => a.extension_name.localeCompare(b.extension_name));
currentExtensions.forEach((current) => {
const latest = extensionData.find((e) => {
const extensionNameMatch = e.extension_name.toLowerCase().trim() === current.extension_name.toLowerCase().trim();
const alternateNamesMatch = e.alternate_names ? e.alternate_names.map((n) => n.toLowerCase().trim()).includes(current.extension_name.toLowerCase().trim()) : false;
return extensionNameMatch || alternateNamesMatch;
});
const row = document.createElement('tr');
// Create the cell for the extension name
const nameCell = document.createElement('td');
nameCell.innerText = current.extension_name;
nameCell.style.cursor = 'pointer'; // make the cursor pointer
nameCell.title = latest && latest.details.description ? latest.details.description : 'No description available'; // set tooltip text
nameCell.addEventListener('click', () => {
const tabId = `content-${current.extension_name.replace(/ /g, '_')}-tab`;
const tabElement = document.getElementById(tabId);
const bsTab = new bootstrap.Tab(tabElement);
bsTab.show();
});
row.appendChild(nameCell);
// Author cell
const authorCell = document.createElement('td');
authorCell.className = 'd-none d-sm-table-cell';
authorCell.title = 'Extension Author';
authorCell.innerText = latest ? latest.details.author : 'N/A';
row.appendChild(authorCell);
// Current version cell
const currentVersionCell = document.createElement('td');
currentVersionCell.title = 'Installed Version';
currentVersionCell.innerText = current.current_version !== 'unknown' ? current.current_version : 'N/A';
row.appendChild(currentVersionCell);
// Latest version cell
const latestVersionCell = document.createElement('td');
latestVersionCell.title = 'Latest Version';
latestVersionCell.innerText = latest ? latest.details.latest_version : 'N/A';
row.appendChild(latestVersionCell);
// save to object to send to SAMMI
const extensionNameKey = toPascalCase(current.extension_name); // Convert extension name to Pascal Case key
window.extensionVersions[extensionNameKey] = {
latest: latest ? latest.details.latest_version : 'N/A',
current: current.current_version,
};
// Download/Update cell
const downloadCell = document.createElement('td');
if (latest && latest.details.download_link !== '') {
const updateAvail = !compareVersions(current.current_version, latest.details.latest_version);
downloadCell.innerHTML = ` ${updateAvail ? 'Update' : 'Download'} `;
} else {
// place holder to maintain table dimensions
downloadCell.innerHTML = ` Placeholder `;
}
row.appendChild(downloadCell);
if (!latest) {
row.style.backgroundColor = '#afab68';
} else if (!compareVersions(current.current_version, latest.details.latest_version)) {
allUpToDate = false;
}
tbody.appendChild(row);
});
if (allUpToDate) {
extensionIcon.className = 'fas fa-check-circle me-1 d-md-none';
extensionIcon.style.color = '#4ad84a';
extensionIcon.title = 'Updates available';
versionSpan.innerText = 'All up to date';
versionSpan.style.color = '#4ad84a';
} else {
extensionIcon.className = 'fas fa-exclamation-circle me-1 d-md-none';
extensionIco
```
--------------------------------
### SAMMI.getDeck - Get Full Deck Configuration
Source: https://context7.com/sammisolutions/sammi-official/llms.txt
Retrieves the complete configuration details for a specific deck, identified by its unique ID. This includes all buttons and their associated settings.
```APIDOC
## SAMMI.getDeck
### Description
Retrieves the complete configuration of a specific deck by its unique ID, including all buttons and their settings.
### Method
`await SAMMI.getDeck(deckId: string): object`
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Request Example
```javascript
// Get a specific deck's full configuration
const deckId = 'unique_deck_id_here';
const deckConfig = await SAMMI.getDeck(deckId);
console.log('Deck configuration:', deckConfig);
// Example: List all buttons in a deck
const deck = await SAMMI.getDeck('my_deck_id');
if (deck && deck.buttons) {
deck.buttons.forEach(button => {
console.log(`Button: ${button.text}, ID: ${button.id}`);
});
}
```
### Response
#### Success Response (200)
- **deckConfig** (object) - An object containing the full configuration of the specified deck, including its buttons and their settings.
#### Response Example
```json
{
"id": "unique_deck_id_here",
"name": "My Deck",
"buttons": [
{
"id": "button_1",
"text": "Click Me",
"color": "#FF0000"
}
]
}
```
```
--------------------------------
### Populate Extension Table (JavaScript)
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/default.txt
An asynchronous function that populates an extension table. It first fetches all extension data and then gets the currently installed extensions to compare and display.
```javascript
async function populateExtensionTable() {
const extensionData = await getExtensionsData();
const currentExtensions = getCurrentExtensions();
}
```
--------------------------------
### Handling Twitch Channel Point Redemptions with SAMMI
Source: https://context7.com/sammisolutions/sammi-official/llms.txt
Shows how to process Twitch channel point redemptions using SAMMI.trigger. The example includes details about the redemption, user, and any associated message or reward information.
```javascript
// Trigger type 3 = Channel Points
SAMMI.trigger(3, {
redeemname: 'Custom Reward',
message: 'User input text',
user_name: 'redeemer',
trigger_data: {
user_name: 'redeemer',
display_name: 'Redeemer',
user_id: '12345678',
channel_id: '98765432',
redeem_name: 'Custom Reward',
reward_description: 'A custom channel point reward',
redeemed_at: '2024-01-15T12:00:00.000000000Z',
status: 'unfulfilled',
message: 'User input text',
cost: 500,
reward_id: 'abc123-def456',
redeem_id: 'xyz789-uvw012'
}
});
```
--------------------------------
### Get Full Deck Configuration with SAMMI.getDeck
Source: https://context7.com/sammisolutions/sammi-official/llms.txt
Retrieves the complete configuration of a specific deck using its unique ID. This includes all buttons and their associated settings, allowing for detailed inspection or modification.
```javascript
// Get a specific deck's full configuration
const deckId = 'unique_deck_id_here';
const deckConfig = await SAMMI.getDeck(deckId);
console.log('Deck configuration:', deckConfig);
// Example: List all buttons in a deck
const deck = await SAMMI.getDeck('my_deck_id');
if (deck && deck.buttons) {
deck.buttons.forEach(button => {
console.log(`Button: ${button.text}, ID: ${button.id}`);
});
}
```
--------------------------------
### Handling Twitch Subscriptions and Gifts with SAMMI
Source: https://context7.com/sammisolutions/sammi-official/llms.txt
Provides examples for handling Twitch subscription events, including regular subs, resubs, and various types of gift subscriptions. It details the data available for each event type.
```javascript
// Trigger type 1 = Subscription
SAMMI.trigger(1, {
tier: 1, // 1=Tier1, 2=Tier2, 4=Tier3, 8=Prime
month: 6,
subtype: 1, // 1=sub/resub, 2=subgift, 4=anonsubgift
communitygift: 0,
trigger_data: {
user_name: 'subscriber',
display_name: 'Subscriber',
user_id: '12345678',
tier: 'Tier 1',
context: 'resub',
message: 'Thanks for the great streams!',
month: 6,
system_message: 'Subscriber subscribed with Tier 1.',
cumulative_total: 12,
name_color: '#9146FF',
duration_months: 1
}
});
// Trigger type 2 = Community Gift
SAMMI.trigger(2, {
tier: 1,
amount: 5,
trigger_data: {
user_name: 'gifter',
display_name: 'Gifter',
user_id: '12345678',
amount: 5,
tier: 'Tier 1',
cumulative_total: 25
}
});
```
--------------------------------
### Get Deck List
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/default.txt
Requests an array of all available decks. The response includes deck names, unique IDs, and CRC32 checksums for verification.
```APIDOC
## GET /api/getDeckList
### Description
Requests an array of all available decks. The response includes deck names, unique IDs, and CRC32 checksums for verification.
### Method
GET
### Endpoint
/api/getDeckList
### Parameters
None
### Request Example
```json
{
"action": "getDeckList"
}
```
### Response
#### Success Response (200)
- **decks** (array) - An array containing deck information. Each entry is typically `["Deck Name", "Unique ID", crc32]`.
#### Response Example
```json
{
"decks": [
"My Deck 1", "deck-uuid-1", 1234567890,
"My Deck 2", "deck-uuid-2", 9876543210
]
}
```
```
--------------------------------
### Sammi Core Helper Functions
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/bridge.html
These functions provide core functionalities to interact with the Sammi application, such as getting and setting variables, displaying messages, and sending extension commands.
```APIDOC
## Sammi Core Helper Functions
These functions allow you to interact with the Sammi application.
### Get Variable
Retrieves the value of a specified variable from Sammi.
- **Method**: `SAMMI.getVariable(name, buttonId)`
- **Parameters**:
- `name` (string) - The name of the variable to retrieve.
- `buttonId` (string, optional) - The ID of the button for local variables. Defaults to 'global' for global variables.
- **Returns**: A Promise that resolves with the variable's value.
### Set Variable
Sets the value of a specified variable in Sammi.
- **Method**: `SAMMI.setVariable(name, value, buttonId, instanceId)`
- **Parameters**:
- `name` (string) - The name of the variable to set.
- `value` (*|number|object|array|null*) - The new value for the variable.
- `buttonId` (string, optional) - The ID of the button for local variables. Defaults to 'global' for global variables.
- `instanceId` (number, optional) - The instance ID for the variable. Defaults to 0.
- **Returns**: A Promise that resolves when the variable is set.
### Popup Message
Displays a popup message to the user in Sammi.
- **Method**: `SAMMI.popUp(msg)`
- **Parameters**:
- `msg` (string) - The message to display in the popup.
- **Returns**: A Promise that resolves when the message is sent.
### Alert Message
Displays a yellow notification message to the user in Sammi.
- **Method**: `SAMMI.alert(msg)`
- **Parameters**:
- `msg` (string) - The message to display in the alert.
- **Returns**: A Promise that resolves when the alert is sent.
### Send Extension Command
Sends a command to a Sammi extension.
- **Method**: `SAMMI.extCommand(name, color, height, boxes, triggerButton, hidden)`
- **Parameters**:
- `name` (string) - The name of the extension command.
- `color` (string, optional) - The color of the box (hex or decimal). Defaults to 3355443.
- `height` (number, optional) - The height of the box in pixels (52 or 80). Defaults to 52.
- `boxes` (Object, optional) - An object where keys are box variables and values are arrays of box parameters (e.g., `boxName`, `boxType`, `defaultValue`, `selectOptions`).
- `triggerButton` (boolean, optional) - Whether to trigger the button associated with the command.
- `hidden` (boolean, optional) - Whether the extension command should be hidden.
- **Returns**: A Promise that resolves when the extension command is sent.
### Close Sammi Bridge
Closes the connection between the Sammi Bridge and Sammi Core.
- **Method**: `SAMMI.close()`
- **Returns**: A Promise that resolves when the connection is closed.
### Stay Informed
Enables or disables receiving updates from Sammi about deck and button changes.
- **Method**: `SAMMI.stayInformed(enabled)`
- **Parameters**:
- `enabled` (boolean) - `true` to enable updates, `false` to disable.
- **Returns**: A Promise that resolves when the setting is applied.
### Example Usage (Get Variable)
```javascript
SAMMI.getVariable('myVariable', 'someButtonID').then(reply => {
console.log('Variable value:', reply);
});
```
### Example Usage (Set Variable)
```javascript
SAMMI.setVariable('myVariable', 'new value', 'someButtonID').then(() => {
console.log('Variable updated.');
});
```
### Example Usage (Extension Command)
```javascript
SAMMI.extCommand('MyCustomCommand', 0xFF0000, 80, {
'myInputBox': ['Input Field', 14, 'Default Text']
}).then(() => {
console.log('Extension command sent.');
});
```
```
--------------------------------
### Initialize SAMMI Core Commands and Variables (JavaScript)
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/bridge.html
This snippet initializes the SAMMI Commands object and exposes it globally. It also defines and exposes global variables for SAMMI and LB, along with debug and modal functions. This setup is crucial for any SAMMI integration.
```javascript
/* eslint-disable */
(function() {
"use strict";
/* eslint-disable */
// Twitch client ID to use for Twitch API requests
window.TWITCH_CLIENT_ID = 'xolexwv18o8i5uqsga0bw3z39cpg0c';
// default Twitch user
window.defaultTwitchUser = {
display_name: "Default User",
login: "defaultuser",
user_id: "123456789",
}
// init object with all available SAMMI command methods
const SAMMI = new SAMMICommands();
window.SAMMI = SAMMI;
const LB = SAMMI;
window.LB = LB;
// Expose debug and sammiModal functions for global access
window.logIt = null;
window.sammiModal = null;
// SAMMI global object with variables
const SAMMIVars = {
SAMMIdebug: JSON.parse(localStorage.getItem('SAMMIdebug')) || {},
twitchList: {},
force_close: false,
force_open: false,
box_newline: 0,
box_checkbox: 2,
box_obs_scenes: 4,
box_obs_sources: 5,
box_obs_filters: 6,
box_keyboard: 7,
box_compare: 8,
box_math: 9,
cbox_sound: 10,
box_slider: 11,
box_normal: 14,
box_variable: 15,
box_color: 17,
box_selectvalue: 18,
box_selectstring: 19,
box_selectstringwritable: 20,
box_loadfile: 22,
box_imagefile: 23,
box_twitch_reward: 24,
box_nobox: 30,
box_obs_pull: 32,
box_select_deck: 33,
box_password: 34,
box_twitch_account: 35,
};
window.SAMMIVars = SAMMIVars;
const LBVars = SAMMIVars;
window.LBVars = LBVars;
})();
```
--------------------------------
### SAMMI Core Helper Functions (JavaScript)
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/bridge.html
Provides essential helper functions for interacting with SAMMI Core, including getting and setting variables, sending pop-up and alert messages, and executing extension commands. These functions can be called with promises for asynchronous responses.
```javascript
/** SAMMI Core Helper Functions * You can call them with SAMMI.{helperfunction} * Use promises if you want to get a reply back from SAMMI * No promise example: SAMMI.setVariable(myVariable, 'some value', 'someButtonID') * Promise example: SAMMI.getVariable(myVariable, 'someButtonID').then(reply=>console.log(reply)) */
function SAMMICommands() {
const SendCommand = {
/**
* Get a variable from SAMMI
* @param {string} name - name of the variable
* @param {string} buttonId - button ID for local variable, default = global variable
*/
async getVariable(name = '', buttonId = 'global') {
return sendToSAMMI('GetVariable', {
Variable: name,
ButtonId: buttonId,
});
},
/**
* Set a variable in SAMMI
* @param {string} name - name of the variable
* @param {(string|number|object|array|null)} value - new value of the variable
* @param {string} buttonId - button ID for local variable, default = global variable
*/
async setVariable(name = '', value = '', buttonId = 'global', instanceId = 0) {
instanceId = !isNaN(instanceId) ? parseInt(instanceId) : 0;
return sendToSAMMI('SetVariable', {
Variable: name,
Value: value,
ButtonId: buttonId,
instanceId,
});
},
/**
* Send a popup message to SAMMI
* @param {string} msg - message to send
*/
async popUp(msg = '') {
return sendToSAMMI('PopupMessage', {
Message: msg,
});
},
/**
* Send a yellow notification message to SAMMI
* @param {string} msg - message to send
*/
async alert(msg = '') {
return sendToSAMMI('AlertMessage', {
Message: msg,
});
},
/**
* send extension command to SAMMI
* @param {string} name - name of the extension command
* @param {string} color - box color, accepts hex/dec colors (include # for hex), default 3355443
* @param {string} height - height of the box in pixels, 52 for regular or 80 for resizable box, default 52
* @param {Object} boxes
* - one object per box, key = boxVariable, value = array of box params
* - boxVariable = variable to save the box value under
* - boxName = name of the box shown in the user interface
* - boxType = type of the box, 0 = resizable, 2 = checkbox (true/false), 14 = regular box, 15 = variable box, 18 = select box, see extension guide for more
* - defaultValue = default value of the variable
* - (optional) sizeModifier = horizontal box size, 1 is normal
* - (optional) [] selectOptions = array of options for the user to select (when using Select box type)
* @param {Array<[boxName: string, boxType: number, defaultValue: (string | number), sizeModifier: (number|undefined), selectOptions: Array|undefined]>} boxes.boxVariable
*/
async extCommand(name = '', color = 3355443, height = 52, boxes = {}, triggerButton = false, hidden = false) {
const ext = new SammiConstructExtCommand(name, color, height, triggerButton, hidden);
for (const [key, value] of Object.entries(boxes)) {
ext.addBox(key, value);
}
return sendToSAMMI('SendExtensionCommands', {
Data: [ext],
});
},
/**
* Close SAMMI Bridge connection to SAMMI Core.
*/
async close() {
return sendToSAMMI('Close');
},
/**
* Get deck and button updates
* @param {boolean} enabled - enable or disable updates
*/
async stayInformed(enabled) {
return sendToSAMMI('SetStayInformed', {
Enabled: enabled
});
}
};
}
```
--------------------------------
### SAMMI.httpRequest - Make HTTP Requests
Source: https://context7.com/sammisolutions/sammi-official/llms.txt
Performs HTTP requests from SAMMI Core, supporting common methods like GET, POST, PUT, and DELETE. It allows for custom headers and request body content.
```APIDOC
## SAMMI.httpRequest
### Description
Performs HTTP requests from SAMMI Core, supporting GET, POST, PUT, and DELETE methods with custom headers and body content.
### Method
`await SAMMI.httpRequest(url: string, method: string, headers?: object, body?: any): Promise`
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Request Example
```javascript
// Simple GET request
const response = await SAMMI.httpRequest('https://api.example.com/data', 'GET');
console.log('Response:', response);
// POST request with headers and body
const postResponse = await SAMMI.httpRequest(
'https://api.example.com/webhook',
'POST',
{ 'Content-Type': 'application/json', 'Authorization': 'Bearer token123' },
{ event: 'stream_start', timestamp: Date.now() }
);
// API call example
const apiData = await SAMMI.httpRequest(
'https://api.twitch.tv/helix/users',
'GET',
{ 'Client-ID': 'your_client_id', 'Authorization': 'Bearer your_token' }
);
```
### Response
#### Success Response (200)
- **response** (any) - The data returned from the HTTP request. The format depends on the API endpoint called.
#### Response Example
```json
{
"data": [
{
"id": "12345",
"login": "exampleuser"
}
]
}
```
```
--------------------------------
### SAMMI Core Constructor and Initialization
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/bridge.html
Initializes the SAMMI Core class by selecting DOM elements, loading connection settings from local storage, and detecting the browser. It then calls `initConnection` to set up event listeners and `connectToSAMMI` to establish an initial connection.
```javascript
constructor() {
this.contentSettings = document.querySelector("#content-settings");
this.currentIP = this.contentSettings.querySelector("[name='currentIP']");
this.currentPort = this.contentSettings.querySelector("[name='currentPort']");
this.nIPbox = this.contentSettings.querySelector("[name='nIPbox']");
this.nPortBox = this.contentSettings.querySelector("[name='nPortBox']");
this.nPassBox = this.contentSettings.querySelector("[name='nPassBox']");
this.cnctButton = document.querySelector('#cnctbutton');
this.retriedWithNewPort = false;
this.force_close = false;
this.currentTimeout = null;
this.attemptedPort = null;
this.connectSettings = JSON.parse(localStorage.getItem('lsParams')) || { ip: '127.0.0.1', port: 9425, pass: '', };
this.browser = (() => {
const test = (regexp) => regexp.test(window.navigator.userAgent);
switch (true) {
case test(/OBS/i): return 'OBS';
case test(/edg/i): return 'Microsoft Edge';
case test(/trident/i): return 'Microsoft Internet Explorer';
case test(/firefox|fxios/i): return 'Mozilla Firefox';
case test(/opr\//i): return 'Opera';
case test(/ucbrowser/i): return 'UC Browser';
case test(/samsungbrowser/i): return 'Samsung Browser';
case test(/chrome|chromium|crios/i): return 'Google Chrome';
case test(/safari/i): return 'Apple Safari';
default: return 'Other';
}
})();
this.initConnection();
this.connectToSAMMI();
}
```
--------------------------------
### Initialize SAMMI WebSocket and Core Components on Load
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/default.txt
Sets up the SAMMI WebSocket connection and initializes SAMMICore and SAMMIUI when the window loads. It also assigns the WebSocket client to global variables for broader access.
```javascript
window.addEventListener('load', function () {
// Instantiate SAMMICore and SAMMIUI, and setup socket connection...
const sammiclient = new SAMMIWebSocket();
window.sammiclient = sammiclient
window.lioranboardclient = sammiclient
const sammiCore = new SAMMICore();
const sammiUI = new SAMMIUI();
// Initialize SAMMIUI
sammiUI.initModal();
sammiUI.initTabs();
populateExtensionTable();
// Get Bridge Version
getVersionFromHTML();
// Initiate Twitch Test triggers
SAMMITestTriggers();
}, false);
```
--------------------------------
### YouTube Live Event Testing Setup
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/default.txt
Sets up event listeners for testing various YouTube Live events (subscriptions, memberships, super chats, etc.). It creates a `ConstructPullData` class to structure data for each event type and attaches click listeners to corresponding buttons.
```javascript
function YTLiveTestEvent() {
class ConstructPullData {
constructor(id) {
[this.display_name, this.user_id, this.picture_url] = generateName();
this.addvalues = (params) => {
Object.assign(this, params);
};
this.id = id;
}
}
const buttonIds = [
'ytLiveTestSub',
'ytLiveTestMember',
'ytLiveTestMilestone',
'ytLiveTestSuperChat',
'ytLiveTestSuperSticker',
'ytLiveTestChatMessage'
];
buttonIds.forEach(id => {
const button = document.getElementById(id);
const pullData = new ConstructPullData(id);
button.addEventListener('click', () => {
switch (pullData.id) {
case 'ytLiveTestSub': ytLiveTestSub(pullData)
break;
case 'ytLiveTestMember': ytLiveTestMember(pullData)
break;
case 'ytLiveTestMilestone': ytLiveTestMilestone(pullData)
break;
case 'ytLiveTestSuperChat': ytLiveTestSuperChat(pullData)
break;
case 'ytLiveTestSuperSticker': ytLiveTestSuperSticker(pullData)
break;
case 'ytLiveTestChatMessage': ytLiveTestChatMessage(pullData)
break;
}
});
});
}
```
--------------------------------
### Generate Random Name and Get Random Integer
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/bridge.html
Provides functions to generate a random name from a predefined list and to get a random integer within a specified range. These are utility functions likely used for testing or placeholder data generation.
```javascript
function generateName() {
const names = [
"Alice",
"Bob",
"Charlie",
"David",
"Eve"
];
const name = names[Math.floor(Math.random() * names.length)];
// Assuming randomName is defined elsewhere or this is a simplified example
// if (name !== randomName) return randomName;
// return generateName(name);
return [name, Math.floor(Math.random() * 1000)]; // Returning name and a dummy ID
}
function getRandomInt(min, max) {
return Math.floor(Math.random() * ((max + 1) - min) + min);
}
```
--------------------------------
### Simulate Twitch Stream Event for SAMMI
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/default.txt
Simulates Twitch stream events (started or ended) by preparing `pullData` with stream details and sending it to SAMMI via trigger ID 38. The `type` parameter determines whether it's a start or end event.
```javascript
, async SAMMITestTwitchStream(form) {
const typeSelect = form.elements['streamType'];
const type = typeSelect.options[typeSelect.selectedIndex].value
const pullData = {
display_name: window.defaultTwitchUser.display_name,
user_name: window.defaultTwitchUser.login,
user_id: window.defaultTwitchUser.user_id,
started_at: twitchTimestamp(Date.now()),
};
if (type == "started") {
pullData.id = "43355732987";
pullData.started_at = twitchTimestamp(Date.now() - 120000);
}
sendTriggerToSAMMI(
38,
`Stream ${type}: ${pullData.display_name} [test trigger].`,
{
type: type == "started" ? 0 : 1,
},
pullData,
);
}
```
--------------------------------
### Create SAMMI Extension Checkbox
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/bridge.html
Generates a DOM element for an installed extension, including a checkbox and a text label. The checkbox's checked state reflects the saved visibility preference for the extension. This function is used to populate the 'installed extensions' section of the UI.
```javascript
createExtensionBox(e) {
const checkbox = document.createElement('input');
const text = document.createElement('span');
checkbox.type = 'checkbox';
checkbox.id = `checkbox${e.id}`;
checkbox.checked = !(this.tabsVisibility[e.id] === false);
text.innerHTML = `${e.title} `;
text.prepend(checkbox);
this.installedExt.appendChild(text);
}
```
--------------------------------
### Initialize SAMMI Connection Settings
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/bridge.html
Populates the connection input fields (IP address, port, password) with values from `this.connectSettings` or default values. It also attaches a click event listener to the connect button to trigger the `connectButton` method.
```javascript
initConnection() {
this.nIPbox.value = this.connectSettings.ip || '127.0.0.1';
this.nPortBox.value = this.connectSettings.port || 9425;
this.nPassBox.value = this.connectSettings.pass || '';
this.cnctButton.addEventListener('click', () => {
this.connectButton();
});
}
```
--------------------------------
### GET /api/getModifiedButtons
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/default.txt
Retrieves a list of all buttons that have been modified.
```APIDOC
## GET /api/getModifiedButtons
### Description
Retrieves a list of all buttons that have been modified.
### Method
GET
### Endpoint
/api/getModifiedButtons
### Parameters
None
### Response
#### Success Response (200)
- **modifiedButtons** (object) - An object containing all currently modified button objects.
```
--------------------------------
### Get Active Buttons
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/default.txt
Retrieves a list of all currently active buttons.
```APIDOC
## GET /api/getActiveButtons
### Description
Retrieves a list of all currently active buttons.
### Method
GET
### Endpoint
/api/getActiveButtons
### Parameters
None
### Request Example
```json
{
"action": "getOngoingButtons"
}
```
### Response
#### Success Response (200)
- **buttons** (array) - An array of objects, where each object contains the parameters of an active button.
#### Response Example
```json
{
"buttons": [
{
"id": "button-1",
"text": "Press Me",
"color": 16711680,
"image": "icon.png"
},
...
]
}
```
```
--------------------------------
### Get Twitch Account List
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/default.txt
Retrieves the parameters of all linked Twitch accounts.
```APIDOC
## GET /api/getTwitchList
### Description
Retrieves the parameters of all linked Twitch accounts.
### Method
GET
### Endpoint
/api/getTwitchList
### Parameters
None
### Request Example
```json
{
"action": "getTwitchList"
}
```
### Response
#### Success Response (200)
- **twitchAccounts** (array) - An array of objects, each representing a linked Twitch account.
#### Response Example
```json
{
"twitchAccounts": [
{
"username": "streamer1",
"channelId": "channel-id-1"
},
...
]
}
```
```
--------------------------------
### Get File CRC32 Checksum
Source: https://github.com/sammisolutions/sammi-official/blob/main/bridge/default.txt
Retrieves the CRC32 checksum for a given file.
```APIDOC
## GET /api/getSum
### Description
Retrieves the CRC32 checksum for a given file.
### Method
GET
### Endpoint
/api/getSum
### Parameters
#### Query Parameters
- **fileName** (string) - Required - The name of the file (e.g., `config.json`).
### Request Example
```json
{
"action": "getSum",
"data": {
"name": "my_file.txt"
}
}
```
### Response
#### Success Response (200)
- **crc32** (integer) - The CRC32 checksum of the file.
#### Response Example
```json
{
"crc32": 1234567890
}
```
```