### 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 = ` `; } 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 = ` `; } 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 } ``` ```