Embedding Zenobits in Articulate Storyline 360

A complete guide for Instructional Designers


Overview

This guide will show you how to integrate Zenobits AI-powered roleplay scenarios into your Articulate Storyline 360 projects. You’ll learn how to:

  1. ✅ Embed the Zenobits iFrame in your Storyline project
  2. ✅ Enable microphone permissions for voice interactions
  3. ✅ Capture scenario results (score, pass/fail, feedback)
  4. ✅ Display personalized feedback to learners

Time Required: 30-45 minutes
Difficulty: Intermediate
Prerequisites: Basic knowledge of Articulate Storyline 360


Prerequisites

Before you begin, make sure you have:

  • Created a scenario at app.zenobits.co.uk
  • Configured feedback for your scenario
  • Copied your embed URL (looks like: https://app.zenobits.co.uk/embed/YOUR_SCENARIO_ID)
  • Articulate Storyline 360 installed (Build 3.108 or later recommended)

⚠️ CRITICAL: API Key Security

Never embed API keys directly in Storyline JavaScript. Anyone can inspect a SCORM package and extract credentials. This is a common mistake when building DIY AI integrations.

Zenobits handles this for you — your embed URL connects to our secure backend, keeping all API keys server-side. You never need to manage API credentials in your Storyline project.


Part 1: Embedding Zenobits and Enabling Microphone Access

Understanding the Challenge

When you embed Zenobits using Storyline’s Web Object feature, the iFrame is created without the necessary permissions for microphone access. This prevents learners from speaking to the AI character.

We’ll fix this by adding a JavaScript snippet that modifies the iFrame to include the required permissions.


Step 1.1: Insert the Web Object

  1. Open your Storyline project and navigate to the slide where you want the Zenobits scenario
  2. Go to Insert → Web Object
  3. In the Web Object dialog:
    • Select Web address
    • Paste your Zenobits embed URL (e.g., https://app.zenobits.co.uk/embed/YOUR_SCENARIO_ID)
    • Set the display mode to Display in slide (recommended) or Display in a lightbox
  4. Click Insert
  5. Resize and position the Web Object as needed

Visual Reference:

┌─────────────────────────────────────────────┐
│  Insert Web Object Dialog                   │
├─────────────────────────────────────────────┤
│  ○ Web address                              │
│    https://app.zenobits.co.uk/embed/...     │
│                                             │
│  ○ Display in slide                         │
│  ○ Display in a lightbox                    │
│                                             │
│              [Insert]  [Cancel]             │
└─────────────────────────────────────────────┘

Step 1.2: Enable Microphone Permissions

Now we need to add JavaScript code to enable microphone and camera access for the embedded iFrame.

Create the JavaScript Trigger:

  1. Select your slide (not the Web Object itself)
  2. Open the Triggers Panel
  3. Click Create New Trigger
  4. Configure the trigger:
    • Action: Execute JavaScript
    • When: Timeline starts
    • Object/Slide: [Current slide]
  5. Click OK to open the JavaScript editor

Paste this code:

// Wait for the Web Object iFrame to load
setTimeout(function() {
  // Find the Zenobits iFrame
  var iframe = document.querySelector('iframe[src*="zenobits"]');
  
  if (iframe) {
    // Add permissions for microphone, camera, and audio
    iframe.setAttribute('allow', 'microphone; camera; autoplay');
    console.log('✅ Zenobits permissions enabled');
  } else {
    console.log('⚠️ Zenobits iFrame not found - it may still be loading');
  }
}, 500);
  1. Click OK to save

What this code does:

  • Waits 500ms for the Web Object to load
  • Finds the Zenobits iFrame on the page
  • Adds the necessary allow attribute for microphone, camera, and audio permissions
  • Logs success/failure messages for debugging

Step 1.3: Test the Microphone Access

To verify it’s working:

  1. Preview your slide (F12 or Preview → This Slide)
  2. Press F12 in your browser to open Developer Tools
  3. Check the Console tab - you should see: ✅ Zenobits permissions enabled
  4. Interact with the Zenobits scenario - you should be prompted for microphone access
  5. Grant permission and test speaking to the character

Troubleshooting:

  • If you see “⚠️ Zenobits iFrame not found”, increase the timeout from 500 to 1000 or 2000
  • Make sure you’re testing in a modern browser (Chrome, Firefox, Edge, Safari)
  • Ensure your Storyline project is published to HTML5 (not Flash)
  • Microphone access requires HTTPS - this works automatically in Storyline’s preview

Part 2: Capturing and Displaying Scenario Results

Understanding the Data Flow

When a learner completes a Zenobits scenario, the system sends feedback data that includes:

  • Scenario Name: The name of the completed scenario
  • Pass/Fail Status: Whether the learner passed
  • Score: A numerical score (typically 0-10)
  • Detailed Feedback: AI-generated feedback on their performance

We’ll capture this data and display it in your Storyline course.


Step 2.1: Create Storyline Variables

First, create variables to store the feedback data.

Creating Variables:

  1. Go to Triggers Panel
  2. Click the Variables button (or right-click anywhere and select Manage Project Variables)
  3. Click Create New Variable for each variable below

Required Variables:

Variable NameTypeDefault ValueDescription
ScenarioNameTextemptyName of the completed scenario
ScenarioPassedTrue/FalseFalseWhether learner passed
ScenarioScoreNumber0Numerical score (0-10)
ScenarioFeedbackTextemptyDetailed AI feedback
FeedbackReceivedTrue/FalseFalseFlag indicating feedback was received

Visual Reference:

┌─────────────────────────────────────────────────┐
│  Manage Project Variables                       │
├─────────────────────────────────────────────────┤
│  [Create New Variable]                          │
│                                                 │
│  ☑ ScenarioName         Text        ""          │
│  ☑ ScenarioPassed       True/False  False       │
│  ☑ ScenarioScore        Number      0           │
│  ☑ ScenarioFeedback     Text        ""          │
│  ☑ FeedbackReceived     True/False  False       │
└─────────────────────────────────────────────────┘

Step 2.2: Add the Feedback Listener

Now we’ll add JavaScript code to listen for feedback from Zenobits and store it in your variables.

Update Your Existing JavaScript Trigger:

You can either:

  • Option A: Edit your existing JavaScript trigger from Step 1.2
  • Option B: Create a second JavaScript trigger

For simplicity, we’ll show how to combine both scripts into one.

Replace your previous JavaScript code with this combined version:

// =================================================
// ZENOBITS INTEGRATION FOR STORYLINE
// Part 1: Enable microphone permissions
// Part 2: Capture feedback data
// =================================================

// Get reference to Storyline Player
var player = GetPlayer();

// PART 1: Enable Microphone Permissions
// Wait for the Web Object iFrame to load
setTimeout(function() {
  var iframe = document.querySelector('iframe[src*="zenobits"]');
  
  if (iframe) {
    iframe.setAttribute('allow', 'microphone; camera; autoplay');
    console.log('✅ Zenobits permissions enabled');
  } else {
    console.log('⚠️ Zenobits iFrame not found');
  }
}, 500);

// PART 2: Listen for Feedback Data
// Prevent duplicate listeners on slide revisits
if (!window.zenobitsListenerActive) {
  window.zenobitsListenerActive = true;
  
  window.addEventListener('message', function(event) {
    // Log all messages for debugging
    console.log('📨 Received message:', event.data);
    
    // Check if this is feedback from Zenobits
    if (event.data && event.data.type === 'roleplay_feedback') {
      console.log('✅ Processing Zenobits feedback...');
      
      // Extract the feedback data
      var scenarioName = event.data.scenarioName || 'Unknown Scenario';
      var passed = event.data.passed || false;
      var score = event.data.score || 0;
      var feedback = event.data.feedback || 'No feedback provided';
      
      // Store in Storyline variables
      player.SetVar('ScenarioName', scenarioName);
      player.SetVar('ScenarioPassed', passed);
      player.SetVar('ScenarioScore', score);
      player.SetVar('ScenarioFeedback', feedback);
      player.SetVar('FeedbackReceived', true);
      
      // Log success
      console.log('✅ Feedback stored successfully:');
      console.log('   Scenario: ' + scenarioName);
      console.log('   Passed: ' + passed);
      console.log('   Score: ' + score + '/10');
      console.log('   Feedback: ' + feedback.substring(0, 50) + '...');
    }
  });
  
  console.log('✅ Zenobits feedback listener active');
}

Save the trigger and proceed to the next step.


Step 2.3: Design Your Feedback Display

Now let’s create the visual elements to show the feedback to learners.

Option A: Feedback on the Same Slide

Create a feedback panel on the same slide as the Web Object:

  1. Create a Rectangle (Insert → Shape → Rectangle)

    • Position it below the Web Object
    • Set background color to light gray (#f8f9fa)
    • Add a subtle border (1px, #dee2e6)
    • Add drop shadow (optional, for depth)
  2. Add a Title Text Box:

    • Text: “Your Results”
  3. Add Scenario Name Text Box:

    • Text: Scenario: %ScenarioName%
  4. Add Score Text Box:

    • Text: Score: %ScenarioScore%/10
  5. Add Feedback Text Box:

    • Text: %ScenarioFeedback%
    • Enable scrolling if needed (Format → Scrolling → Vertical)
    • Make this box tall enough for longer feedback
  6. Create a Pass/Fail Badge (optional but recommended):

    • Insert a small rectangle or circle
    • Create two States:
      • Passed State: Green background (#28a745), white text ”✓ PASSED”
      • Failed State: Red background (#dc3545), white text ”✗ FAILED”

Visual Layout:

┌─────────────────────────────────────────────┐
│                                             │
│  ┌───────────────────────────────┐          │
│  │                                │          │
│  │   Zenobits Web Object          │          │
│  │   (iFrame)                     │          │
│  │                                │          │
│  └───────────────────────────────┘          │
│                                             │
│  ┌───────────────────────────────┐          │
│  │ 📊 YOUR RESULTS                │          │
│  │                                │          │
│  │ Scenario: %ScenarioName%       │          │
│  │                                │          │
│  │ ┌──────────┐  Score: 8/10      │          │
│  │ │ ✓ PASSED │                   │          │
│  │ └──────────┘                   │          │
│  │                                │          │
│  │ Feedback:                      │          │
│  │ %ScenarioFeedback%             │          │
│  │                                │          │
│  └───────────────────────────────┘          │
└─────────────────────────────────────────────┘

Option B: Feedback on a Separate Slide

Create a dedicated results/feedback slide:

  1. Create a new slide (Insert → New Slide)
  2. Design your feedback layout using text boxes with variables:
    • Scenario: %ScenarioName%
    • Score: %ScenarioScore%/10
    • %ScenarioFeedback%
  3. Add a Pass/Fail badge with states (as described above)
  4. Add navigation buttons:
    • “Try Again” → Jump to scenario slide
    • “Continue” → Jump to next lesson

Step 2.4: Set Up Triggers to Show Feedback

Now we’ll create triggers to display the feedback when it’s received.

If Using Option A (Same Slide):

Hide the feedback panel initially:

  1. Select your feedback panel (the rectangle)
  2. In States, set the Initial State to Hidden

Create a trigger to show it when feedback arrives:

  1. Trigger 1 - Show Feedback Panel:

    • Action: Change state of [FeedbackPanel]
    • To state: Normal
    • When: Variable changes
    • Variable: FeedbackReceived
    • Condition: FeedbackReceived is equal to True
  2. Trigger 2 - Show “Passed” Badge:

    • Action: Change state of [PassFailBadge]
    • To state: Passed
    • When: Variable changes
    • Variable: ScenarioPassed
    • Condition: ScenarioPassed is equal to True
  3. Trigger 3 - Show “Failed” Badge:

    • Action: Change state of [PassFailBadge]
    • To state: Failed
    • When: Variable changes
    • Variable: ScenarioPassed
    • Condition: ScenarioPassed is equal to False

If Using Option B (Separate Slide):

Create a trigger to jump to the feedback slide:

  • Action: Jump to slide
  • Slide: [Your Feedback Slide]
  • When: Variable changes
  • Variable: FeedbackReceived
  • Condition: FeedbackReceived is equal to True

Testing Your Implementation

Pre-Publish Checklist

Before publishing to learners, verify everything works:

Test in Preview Mode:

  1. Click Preview → This Slide (F12)
  2. Open Developer Console (press F12 in browser)
  3. Check for console messages:
    • ✅ Zenobits permissions enabled
    • ✅ Zenobits feedback listener active
  4. Complete the Zenobits scenario
  5. Verify feedback appears with correct data

Check Variables:

  1. While in preview, open Variables panel
  2. After completing scenario, verify:
    • FeedbackReceived = True
    • ScenarioName = [Your scenario name]
    • ScenarioPassed = True or False
    • ScenarioScore = [Your score]
    • ScenarioFeedback = [Feedback text]

Test Scenarios:

  • ✅ Complete scenario with passing performance
  • ✅ Complete scenario with failing performance
  • ✅ Test with long feedback text (check for overflow)
  • Revisit the slide (ensure no duplicate listeners)
  • ✅ Test on mobile devices (iOS and Android)

Troubleshooting Common Issues

Issue 1: “Microphone permission denied”

Solution:

  • Ensure your code includes iframe.setAttribute('allow', 'microphone; camera; autoplay');
  • Publish to SCORM Cloud or a web server (some browsers block microphone in local files)
  • Check that learner’s browser allows microphone access

Issue 2: “Variables not updating”

Symptoms: Feedback text doesn’t appear, variables stay at default values

Debugging:

  1. Open Developer Console (F12)
  2. Look for messages:
    • 📨 Received message: ...
    • ✅ Processing Zenobits feedback...

If you see no messages:

  • Verify the JavaScript trigger is set to “Timeline starts”
  • Check for JavaScript errors in console (red text)
  • Try increasing the timeout value

If you see messages but variables don’t update:

  • Verify variable names match exactly (case-sensitive!)
  • Check that GetPlayer() is working
  • Try manually setting a variable to test trigger functionality

Issue 3: “Feedback panel doesn’t show”

Symptoms: Variables update but feedback panel stays hidden

Check:

  1. Is FeedbackReceived being set to True? (Check Variables panel)
  2. Is there a trigger watching the FeedbackReceived variable?
  3. Is the trigger action set to Change state or Show layer?
  4. Is the panel’s initial state set to Hidden?

Test manually:

  • In Variables panel, set FeedbackReceived to True
  • Panel should appear immediately

Issue 4: “Text gets cut off”

Symptoms: Long feedback text overflows or gets truncated

Solutions:

  • Expand text box size to be taller
  • Enable vertical scrolling: Select text box → Format → Scrolling → Vertical scroll
  • Use a scrolling panel: Insert → Scrolling Panel
  • Reduce font size to 12pt or smaller

Issue 5: “Works in preview but not when published”

Common causes:

  • LMS restrictions: Some LMSs block JavaScript or iFrames
  • HTTP vs HTTPS: Microphone requires HTTPS
  • Cross-origin restrictions: Ensure Zenobits domain is allowed

Solutions:

  • Test on SCORM Cloud to rule out LMS issues
  • Publish to a web server with HTTPS
  • Check LMS documentation for iFrame restrictions

Advanced Features (Optional)

Feature 1: Multiple Attempts Tracking

Track how many times a learner has attempted the scenario:

Additional Variables:

  • AttemptCount (Number, default: 0)

Enhanced JavaScript (add to your listener):

// Increment attempt counter
var attemptCount = player.GetVar('AttemptCount') || 0;
attemptCount++;
player.SetVar('AttemptCount', attemptCount);
console.log('Attempt #' + attemptCount);

Display in Storyline:

  • Text: Attempt: %AttemptCount%

Feature 2: Score-Based Conditional Feedback

Show different messages based on score ranges:

Create triggers:

  1. If score ≥ 9: Show “Excellent!” message
  2. If score 7-8: Show “Good job!” message
  3. If score 5-6: Show “Keep practicing” message
  4. If score < 5: Show “Let’s try again” message

Example trigger:

  • Action: Show layer “ExcellentLayer”
  • When: Variable changes
  • Variable: ScenarioScore
  • Condition: ScenarioScore is greater than or equal to 9

Feature 3: Auto-Advance on Pass

Automatically move to the next slide if the learner passes:

Create trigger:

  • Action: Jump to slide [Next Slide]
  • When: Variable changes
  • Variable: ScenarioPassed
  • Condition: ScenarioPassed is equal to True
  • Optional: Add a 3-second delay to show feedback first

Feature 4: Retry Button

Add a button to let learners retry the scenario:

Create a button:

  1. Insert → Button
  2. Text: “Try Again”
  3. Add trigger:
    • Action: Reset all variables to default values
    • When: User clicks [Try Again button]
  4. Add second trigger:
    • Action: Revisit slide (or Jump to slide [Current slide])
    • When: User clicks [Try Again button]

This resets all variables and reloads the Zenobits scenario.


Publishing and Deployment

  1. Go to **Publish → Web
  2. Important settings:
    • HTML5 Output: Required (not Flash)
    • Quality: Standard or higher
    • Mobile Player: Recommended for mobile access
  3. Click Publish

Testing After Publishing

SCORM/LMS Testing:

  1. Upload to SCORM Cloud for initial testing
  2. Verify:
    • Zenobits iFrame loads
    • Microphone permissions work
    • Feedback displays correctly
  3. Test in your actual LMS before deployment

Web Hosting:

  • Ensure server uses HTTPS (required for microphone)
  • Test on multiple devices and browsers
  • Check mobile compatibility

Best Practices

Design Recommendations

Keep feedback visible - Don’t hide it in layers learners might miss
Use clear visual hierarchy - Make pass/fail status immediately obvious
Provide context - Show scenario name and score alongside feedback
Allow retry - Give learners a chance to improve
Mobile-friendly - Test on phones and tablets

Instructional Design Tips

Set expectations - Tell learners what “passing” means
Provide guidance - If they fail, offer resources or hints
Celebrate success - Use positive reinforcement for passing
Track progress - Consider logging attempts in LMS
Offer reflection - Add a slide for learners to think about the feedback

Accessibility Considerations

Color contrast - Ensure text is readable (WCAG AA minimum)
Alternative text - Add alt text to visual elements
Keyboard navigation - Test tab order and keyboard controls
Screen reader support - Use proper heading structure


Quick Reference

Essential Code Snippet (Copy & Paste)

// ZENOBITS STORYLINE INTEGRATION
var player = GetPlayer();

// Enable microphone permissions
setTimeout(function() {
  var iframe = document.querySelector('iframe[src*="zenobits"]');
  if (iframe) {
    iframe.setAttribute('allow', 'microphone; camera; autoplay');
    console.log('✅ Permissions enabled');
  }
}, 500);

// Listen for feedback
if (!window.zenobitsListenerActive) {
  window.zenobitsListenerActive = true;
  window.addEventListener('message', function(event) {
    if (event.data && event.data.type === 'roleplay_feedback') {
      player.SetVar('ScenarioName', event.data.scenarioName || '');
      player.SetVar('ScenarioPassed', event.data.passed || false);
      player.SetVar('ScenarioScore', event.data.score || 0);
      player.SetVar('ScenarioFeedback', event.data.feedback || '');
      player.SetVar('FeedbackReceived', true);
      console.log('✅ Feedback received');
    }
  });
}

Required Variables

ScenarioName (Text, "")
ScenarioPassed (True/False, False)
ScenarioScore (Number, 0)
ScenarioFeedback (Text, "")
FeedbackReceived (True/False, False)

Variable References in Text Boxes

Scenario: %ScenarioName%
Score: %ScenarioScore%/10
%ScenarioFeedback%

Summary

You’ve now learned how to:

  1. Embed Zenobits in Storyline using Web Objects
  2. Enable microphone access with JavaScript
  3. Capture feedback data via PostMessage
  4. Display results dynamically in your course
  5. Style and customize the learner experience

Next Steps

  1. Create your Zenobits scenario at app.zenobits.co.uk
  2. Set up your Storyline project following this guide
  3. Test thoroughly before deploying to learners
  4. Gather feedback and iterate on your design

Support

Need help?


Document Version: 1.0
Last Updated: January 2026
Compatible With: Articulate Storyline 360 (Build 3.108+)
Tested Browsers: Chrome 120+, Firefox 121+, Safari 17+, Edge 120+


Happy eLearning! 🚀