{"id":19450171,"url":"https://github.com/webexsamples/websocket-demo-page","last_synced_at":"2025-08-24T19:50:45.207Z","repository":{"id":114829591,"uuid":"203529859","full_name":"WebexSamples/websocket-demo-page","owner":"WebexSamples","description":"Shows how websockets can be an alternative for webhooks","archived":false,"fork":false,"pushed_at":"2025-07-18T20:25:03.000Z","size":889,"stargazers_count":3,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-08-01T03:50:18.175Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://webexsamples.github.io/websocket-demo-page/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WebexSamples.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-08-21T07:23:58.000Z","updated_at":"2025-07-18T20:25:07.000Z","dependencies_parsed_at":"2025-08-01T03:36:08.271Z","dependency_job_id":"34abdecc-f6a5-4513-b687-ba040163cb73","html_url":"https://github.com/WebexSamples/websocket-demo-page","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/WebexSamples/websocket-demo-page","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebexSamples%2Fwebsocket-demo-page","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebexSamples%2Fwebsocket-demo-page/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebexSamples%2Fwebsocket-demo-page/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebexSamples%2Fwebsocket-demo-page/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WebexSamples","download_url":"https://codeload.github.com/WebexSamples/websocket-demo-page/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebexSamples%2Fwebsocket-demo-page/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271937803,"owners_count":24846749,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-24T02:00:11.135Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T16:35:34.774Z","updated_at":"2025-08-24T19:50:45.197Z","avatar_url":"https://github.com/WebexSamples.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🌐 Webex WebSocket Listener Demo\n\nA browser-based demonstration application that showcases real-time message listening using the Webex JavaScript SDK's WebSocket functionality. This interactive web page allows users to authenticate with Webex, listen for incoming messages across all their rooms, and test the functionality with a dedicated test room.\n\n## ✨ Features\n\n- **🔐 Personal Access Token Authentication** - Simple token-based authentication with Webex\n- **📡 Real-time Message Listening** - WebSocket-based message notifications across all user rooms\n- **🏠 Test Room Management** - Create and delete dedicated test rooms for demonstration\n- **💬 Random Message Generation** - Send fun Unicode emoji messages to test the listener\n- **📊 Live Message Display** - Real-time table updates showing incoming message details\n- **🎨 Clean UI Design** - Responsive interface using Spectre.css framework\n- **📋 Room Information** - Display room details and message metadata\n- **🔄 Start/Stop Controls** - Toggle message listening on and off\n\n## 🚀 Quick Start\n\n### Prerequisites\n\n- Modern web browser with WebSocket support\n- Valid Webex personal access token\n- Active Webex account with room access\n\n### Setup and Usage\n\n1. **Access the Application:**\n   - Open `index.html` in a web browser\n   - Or deploy to a web server (GitHub Pages, local server, etc.)\n\n2. **Authenticate:**\n   - Get your personal access token from [Webex Developer Portal](https://developer.webex.com/docs/api/getting-started)\n   - Enter the token in the authentication field\n   - Click \"Authenticate\" to verify your credentials\n\n3. **Start Listening:**\n   - Click \"Start Listening to Messages\" to activate the WebSocket listener\n   - The status will update to show active listening state\n\n4. **Test with Demo Room:**\n   - Click \"Create Test Room\" to create a dedicated testing space\n   - Use \"Send a Message to Your Test Room\" to trigger notifications\n   - Watch the message table update in real-time\n\n5. **Monitor Activity:**\n   - Send messages from any Webex client to your rooms\n   - Observe real-time updates in the \"Last message\" table\n   - View sender, room, timestamp, and content information\n\n## 📖 How It Works\n\n### WebSocket Integration\n\nThe application uses the Webex JavaScript SDK's WebSocket functionality to establish a persistent connection for real-time message notifications:\n\n```javascript\n// Start listening for messages\nwebex.messages.listen().then(() =\u003e {\n    // WebSocket connection established\n    listening = true;\n    \n    // Register event handler for new messages\n    webex.messages.on('created', (event) =\u003e {\n        // Handle incoming message\n        console.log('Message received:', event.data);\n    });\n});\n```\n\n### Authentication Flow\n\n```javascript\n// Initialize Webex SDK with personal access token\nfunction initialize() {\n    webex = Webex.init({\n        credentials: {\n            access_token: document.getElementById('access-token').value\n        }\n    });\n}\n\n// Verify token by calling /people/me endpoint\nwebex.people.get('me').then(person =\u003e {\n    // Authentication successful\n    tokenHolder = person;\n    // Enable additional features\n}).catch(reason =\u003e {\n    // Authentication failed\n    console.error('Authentication failed:', reason);\n});\n```\n\n### Message Event Handling\n\n```javascript\nwebex.messages.on('created', (event) =\u003e {\n    // Extract message details\n    const messageData = event.data;\n    const senderId = event.actorId;\n    \n    // Get sender information\n    webex.people.get(senderId).then(sender =\u003e {\n        // Get room information\n        webex.rooms.get(messageData.roomId).then(room =\u003e {\n            // Update UI with message details\n            updateMessageDisplay(room, messageData, sender);\n        });\n    });\n});\n```\n\n## 🏗️ Project Structure\n\n```\nwebsocket-demo-page/\n├── index.html              # Main HTML interface\n├── app.js                  # Application logic and WebSocket handling\n├── bundle.js               # Bundled Webex JavaScript SDK\n├── _config.yml             # Jekyll configuration for GitHub Pages\n├── LICENSE                 # Cisco Sample Code License\n└── README.md               # This documentation\n```\n\n### Core Components\n\n| Component | Description | Purpose |\n|-----------|-------------|---------|\n| **HTML Interface** | User interface with forms and tables | [`index.html`](index.html) |\n| **WebSocket Logic** | Message listening and event handling | [`app.js`](app.js) |\n| **Webex SDK Bundle** | Pre-bundled Webex JavaScript SDK | [`bundle.js`](bundle.js) |\n| **Jekyll Config** | GitHub Pages deployment configuration | [`_config.yml`](_config.yml) |\n\n## 🔧 Code Implementation\n\n### Global Variables\n\n```javascript\nlet testRoom;        // Test room object for demonstrations\nlet webex;           // Webex SDK instance\nlet tokenHolder;     // Authenticated user information\nlet listening;       // WebSocket listener status\n```\n\n### Core Functions\n\n| Function | Description | Usage |\n|----------|-------------|-------|\n| **initialize()** | Creates Webex SDK instance with token | Called during authentication |\n| **listenToMessages()** | Starts WebSocket listener | Activated by \"Start Listening\" button |\n| **stopListeningToMessages()** | Deactivates WebSocket listener | Activated by \"Stop Listening\" button |\n| **createRoom()** | Creates test room for demonstrations | Activated by \"Create Test Room\" button |\n| **clearRoom()** | Deletes the test room | Activated by \"Delete Test Room\" button |\n\n### UI Event Handlers\n\n```javascript\n// Authentication form submission\ndocument.getElementById('authenticate').addEventListener('submit', ev =\u003e {\n    ev.preventDefault();\n    initialize();\n    // Verify token and enable features\n});\n\n// Start/stop message listening\ndocument.getElementById('listener-btn').addEventListener('click', event =\u003e {\n    event.preventDefault();\n    if (!listening) {\n        listenToMessages();\n    } else {\n        stopListeningToMessages();\n    }\n});\n\n// Test room management\ndocument.getElementById('room-btn').addEventListener('click', event =\u003e {\n    event.preventDefault();\n    if (testRoom) {\n        clearRoom();\n    } else {\n        createRoom();\n    }\n});\n```\n\n### Random Message Generation\n\n```javascript\n// Fun emoji messages for testing\nconst messages = ['ʕ·͡ᴥ·ʔ', '(っ◕‿◕)っ', '(⌐■_■)', '\\\\m/_(\u003e_\u003c)_\\\\m/', 'ᕙ(⇀‸↼)ᕗ', '[¬º-°]¬'];\n\n// Send random message to test room\ndocument.getElementById('messages-btn').addEventListener('click', event =\u003e {\n    event.preventDefault();\n    const message = messages[Math.floor(Math.random() * messages.length)];\n    \n    webex.messages.create({\n        roomId: testRoom.id,\n        markdown: message\n    });\n});\n```\n\n## 🎨 User Interface\n\n### Layout Structure\n\nThe interface is built with a responsive design using Spectre.css:\n\n1. **Header Section:**\n   - Title: \"Websocket Listener\"\n   - Description of functionality\n   - Link to source code\n\n2. **Authentication Section:**\n   - Personal access token input field\n   - Authentication button\n   - Status indicators\n\n3. **Control Section:**\n   - Start/Stop listening button\n   - Create/Delete test room button\n   - Send test message button\n\n4. **Information Tables:**\n   - Test room details table\n   - Last message information table\n\n### Status Indicators\n\n```css\n/* Status label styling */\n.label-success { background-color: #32b643; }\n.label-warning { background-color: #ffb700; }\n.label-error { background-color: #e85600; }\n```\n\n### Table Styling\n\n```css\ntable, th, td {\n    border: 1px solid black;\n    border-collapse: collapse;\n}\n\nth, td {\n    padding: 5px;\n}\n```\n\n## ⚙️ Configuration\n\n### Personal Access Token\n\n1. **Obtain Token:**\n   - Visit [Webex Developer Portal](https://developer.webex.com/docs/api/getting-started)\n   - Log in with your Webex account\n   - Copy your personal access token (12-hour validity)\n\n2. **Token Usage:**\n   ```javascript\n   webex = Webex.init({\n       credentials: {\n           access_token: 'YOUR_PERSONAL_ACCESS_TOKEN'\n       }\n   });\n   ```\n\n### WebSocket Configuration\n\nThe WebSocket connection is automatically configured by the Webex SDK:\n\n```javascript\n// Start listening (establishes WebSocket)\nwebex.messages.listen().then(() =\u003e {\n    console.log('WebSocket connection established');\n});\n\n// Stop listening (closes WebSocket)\nwebex.messages.stopListening();\nwebex.messages.off('created');\n```\n\n## 🧪 Testing the Demo\n\n### Step-by-Step Testing\n\n1. **Authentication Test:**\n   ```bash\n   # Expected: Green success message with your display name\n   1. Enter valid access token\n   2. Click \"Authenticate\"\n   3. Verify \"authenticated as [Your Name]\" appears\n   ```\n\n2. **WebSocket Listener Test:**\n   ```bash\n   # Expected: Blue warning changing to green success\n   1. Click \"Start Listening to Messages\"\n   2. Verify status changes to \"listening to messages\"\n   3. Button text changes to \"Stop Listening to Messages\"\n   ```\n\n3. **Test Room Creation:**\n   ```bash\n   # Expected: Table appears with room details\n   1. Click \"Create Test Room\"\n   2. Verify room details table appears\n   3. \"Send a Message\" button becomes visible\n   ```\n\n4. **Message Testing:**\n   ```bash\n   # Expected: Real-time message table updates\n   1. Click \"Send a Message to Your Test Room\"\n   2. Verify \"Last message\" table updates\n   3. Check timestamp and emoji content\n   ```\n\n5. **External Message Test:**\n   ```bash\n   # Expected: Table updates for any room activity\n   1. Send message from Webex mobile/desktop app\n   2. Verify message appears in demo table\n   3. Check sender and room information\n   ```\n\n### Debug Console\n\nMonitor browser console for additional information:\n\n```javascript\n// Message reception logging\nconsole.log('message received');\n\n// Error handling\nconsole.error('Could not get room details:', reason.message);\nconsole.error('Authentication failed:', reason.message);\n```\n\n## 🌐 Deployment Options\n\n### GitHub Pages\n\nThe repository includes Jekyll configuration for GitHub Pages:\n\n```yaml\n# _config.yml\ntheme: jekyll-theme-minimal\n```\n\n### Local Development\n\n```bash\n# Simple HTTP server\npython -m http.server 8000\n# or\nnpx http-server\n\n# Access at http://localhost:8000\n```\n\n### Static Hosting\n\nDeploy to any static hosting service:\n- Netlify\n- Vercel\n- AWS S3 + CloudFront\n- Azure Static Web Apps\n\n## 🔐 Security Considerations\n\n### Token Management\n\n- **Personal Access Tokens:** 12-hour expiration, suitable for testing\n- **Production Use:** Consider OAuth integration for longer-term access\n- **Client-Side Storage:** Tokens are stored in browser memory only\n\n### WebSocket Security\n\n```javascript\n// WebSocket connections are secured by Webex infrastructure\n// No additional client-side security configuration required\n```\n\n### CORS and CSP\n\nFor production deployment, consider:\n\n```html\n\u003c!-- Content Security Policy --\u003e\n\u003cmeta http-equiv=\"Content-Security-Policy\" \n      content=\"default-src 'self' https://webexapis.com https://unpkg.com;\"\u003e\n```\n\n## 🚨 Troubleshooting\n\n### Common Issues\n\n| Issue | Solution |\n|-------|----------|\n| **Authentication Failed** | Verify token validity and expiration |\n| **WebSocket Not Starting** | Check browser WebSocket support and network connectivity |\n| **Messages Not Appearing** | Ensure rooms are accessible and listener is active |\n| **UI Not Updating** | Check browser console for JavaScript errors |\n\n### Debug Steps\n\n1. **Check Browser Console:**\n   ```javascript\n   // Look for error messages\n   console.error('Authentication failed:', reason);\n   console.error('Could not start listener:', error.message);\n   ```\n\n2. **Verify Network Connectivity:**\n   ```bash\n   # Test API access\n   curl -H \"Authorization: Bearer YOUR_TOKEN\" https://webexapis.com/v1/people/me\n   ```\n\n3. **Test WebSocket Support:**\n   ```javascript\n   // Check WebSocket availability\n   if ('WebSocket' in window) {\n       console.log('WebSocket supported');\n   } else {\n       console.log('WebSocket not supported');\n   }\n   ```\n\n### Browser Compatibility\n\n| Browser | Version | WebSocket Support |\n|---------|---------|-------------------|\n| Chrome | 16+ | ✅ Full Support |\n| Firefox | 11+ | ✅ Full Support |\n| Safari | 7+ | ✅ Full Support |\n| Edge | 12+ | ✅ Full Support |\n\n## 📚 Educational Value\n\n### Learning Objectives\n\nThis demo teaches:\n\n1. **WebSocket Integration:** Real-time communication patterns\n2. **Webex SDK Usage:** Authentication and API interaction\n3. **Event-Driven Programming:** Handling asynchronous events\n4. **DOM Manipulation:** Dynamic UI updates\n5. **Error Handling:** Graceful failure management\n\n### Extension Ideas\n\n```javascript\n// Add more event types\nwebex.rooms.on('created', handleRoomCreated);\nwebex.rooms.on('updated', handleRoomUpdated);\n\n// Message filtering\nwebex.messages.on('created', (event) =\u003e {\n    if (event.data.text.includes('@me')) {\n        handleMention(event);\n    }\n});\n\n// Multiple room monitoring\nconst roomSubscriptions = new Map();\nrooms.forEach(room =\u003e {\n    roomSubscriptions.set(room.id, subscribeToRoom(room));\n});\n```\n\n## 🤝 Contributing\n\nSuggestions for enhancing this demo:\n\n1. **Message Filtering:** Add keyword filtering for messages\n2. **Room Selection:** Choose specific rooms to monitor\n3. **Message History:** Display recent message history\n4. **File Attachments:** Handle and display file messages\n5. **Mentions Detection:** Highlight messages mentioning the user\n\n## 📄 License\n\nThis project is licensed under the Cisco Sample Code License - see the [LICENSE](LICENSE) file for details.\n\n## 🆘 Support\n\nFor technical support and questions:\n\n- **WebSocket Issues**: [Webex JavaScript SDK Documentation](https://webex.github.io/webex-js-sdk/)\n- **API Questions**: [Webex Developer Portal](https://developer.webex.com)\n- **Community**: [Webex Developer Community](https://developer.webex.com/community)\n\n## Thanks!\n\nMade with ❤️ by the Webex Developer Relations Team at Cisco\n\n---\n\n**Note**: This demo uses personal access tokens for simplicity. For production applications, implement proper OAuth flows and consider security best practices for token management.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebexsamples%2Fwebsocket-demo-page","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwebexsamples%2Fwebsocket-demo-page","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebexsamples%2Fwebsocket-demo-page/lists"}