npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@noematicsllc/talk-sdk

v0.2.0

Published

UNOFFICIAL TypeScript SDK for Nextcloud Talk API - Not affiliated with or endorsed by Nextcloud

Downloads

245

Readme

@noematicsllc/talk-sdk

⚠️ UNOFFICIAL SDK: This is an unofficial, community-maintained TypeScript SDK for the Nextcloud Talk API. This package is NOT affiliated with, endorsed by, or connected to Nextcloud GmbH or the Nextcloud project. Use at your own risk.

TypeScript SDK for the Nextcloud Talk API.

Installation

npm install @noematicsllc/talk-sdk
# or
pnpm add @noematicsllc/talk-sdk

Quick Start

import { TalkClient } from '@noematicsllc/talk-sdk';

const client = new TalkClient({
  host: 'https://nextcloud.local',
  username: 'admin',
  password: 'app-password'
});

// List all rooms
const rooms = await client.rooms.list();

// Find a room by token
const targetRoom = rooms.find(r => r.token === 'abcdefgh');

// Send a message
await targetRoom.sendMessage("Automated system check initialized.");

Architecture

The SDK uses a 4-layer architecture:

1. Transport Layer (HttpClient)

Base HTTP client using the native Fetch API. Automatically injects mandatory OCS headers:

  • OCS-APIRequest: true
  • Accept: application/json
  • Authorization: Basic ...

2. Resource Layer

Logical modules mapped to specific API versions:

| Resource | API Version | Base Path | |----------|-------------|-----------| | RoomResource | v4 | /api/v4/room | | ParticipantResource | v4 | /api/v4/room/{token}/participants | | CallResource | v4 | /api/v4/call | | SignalingResource | v3 | /api/v3/signaling | | ChatResource | v1 | /api/v1/chat | | PollResource | v1 | /api/v1/poll | | ReactionResource | v1 | /api/v1/reaction |

3. Normalization Layer

DTO mappers that strip the ocs.meta and ocs.data envelopes, returning clean, flat objects.

4. Domain Layer

High-level entities like Room that encapsulate both the token (string) and id (integer) to handle the API's identifier inconsistencies.

Room Entity

The Room class provides a high-level interface for room operations:

const room = await client.rooms.get('abcdefgh');

// Chat
await room.sendMessage("Hello!");
const messages = await room.getHistory({ limit: 50 });
const result = await room.pollMessages({ lastKnownMessageId: 123 });

// Participants
const participants = await room.getParticipants();
await room.addParticipant('user-id');

// Calls
await room.joinCall({ flags: 7 });
const peers = await room.getCallPeers();
await room.leaveCall();

// Polls
await room.createPoll({
  question: "What's for lunch?",
  options: ["Pizza", "Sushi", "Tacos"]
});

// Reactions
await room.addReaction(messageId, "👍");

Video Calls

⚠️ Experimental/Beta Feature: The video call functionality (WebRTC, signaling, and VideoCall API) is currently in beta/experimental status. While the core implementation is complete, it has not been extensively tested in production environments. We recommend thorough testing before using in production applications. The API may change in future versions based on feedback and real-world usage.

Basic Video Call Setup

import { TalkClient, isWebRTCSupported } from '@noematicsllc/talk-sdk';

// Check browser compatibility first
if (!isWebRTCSupported()) {
  console.error('WebRTC is not supported in this browser');
  return;
}

const client = new TalkClient({
  host: 'https://nextcloud.local',
  username: 'admin',
  password: 'app-password'
});

// Start a video call
const videoCall = client.startVideoCall('abc123');

// Join with media
await videoCall.join({
  video: true,
  audio: true,
  video: { width: 1280, height: 720 } // Optional video constraints
});

// Control media
await videoCall.setVideoEnabled(false);
await videoCall.setAudioEnabled(true);

// Leave call
await videoCall.leave();

Custom UI Composability

The VideoCall API is designed for full UI composability - you control how streams are rendered:

Event-Based Rendering

const videoCall = client.startVideoCall('abc123');

// Render each participant's stream in a separate window
videoCall.on('stream', (stream, peer) => {
  const window = window.open('', `peer-${peer.sessionId}`, 'width=640,height=480');
  if (window) {
    const video = window.document.createElement('video');
    video.srcObject = stream;
    video.autoplay = true;
    video.playsInline = true;
    window.document.body.appendChild(video);
  }
});

// Handle peer join/leave
videoCall.on('peer-joined', (peer) => {
  console.log(`${peer.displayName} joined the call`);
});

videoCall.on('peer-left', (peer) => {
  console.log(`${peer.displayName} left the call`);
});

await videoCall.join({ video: true, audio: true });

Direct Stream Access

// Get all peer streams and render them however you want
const streams = videoCall.getPeerStreams();

streams.forEach((stream, sessionId) => {
  // Render in custom layout, separate windows, canvas, etc.
  renderInCustomLayout(stream, sessionId);
});

// Get local stream for preview
const localStream = videoCall.getLocalStream();
if (localStream) {
  previewElement.srcObject = localStream;
}

Complete Custom UI Example

const videoCall = client.startVideoCall('abc123');

// Custom UI with separate windows for each participant
const participantWindows = new Map<string, Window>();

videoCall.on('stream', (stream, peer) => {
  // Open new window for this participant
  const win = window.open('', `peer-${peer.sessionId}`, 'width=640,height=480');
  if (!win) return;

  win.document.write(`
    <!DOCTYPE html>
    <html>
      <head><title>${peer.displayName}</title></head>
      <body style="margin:0;background:#000;">
        <video autoplay playsinline style="width:100%;height:100%;object-fit:contain;"></video>
      </body>
    </html>
  `);

  win.document.querySelector('video')!.srcObject = stream;
  participantWindows.set(peer.sessionId, win);
});

videoCall.on('peer-left', (peer) => {
  const win = participantWindows.get(peer.sessionId);
  if (win) {
    win.close();
    participantWindows.delete(peer.sessionId);
  }
});

await videoCall.join({ video: true, audio: true });

Low-Level API (Advanced Users)

Note: The low-level WebRTC APIs (WebRTCManager, SignalingConnection) are also experimental and may change.

For advanced use cases, you can use the low-level WebRTC APIs directly:

import { WebRTCManager, SignalingConnection, getUserMedia } from '@noematicsllc/talk-sdk';

// Get signaling settings
const settings = await client.call.getSignalingSettings(token);

// Create signaling connection
const signaling = new SignalingConnection({
  server: settings.server!,
  token,
  helloAuthParams: settings.helloAuthParams,
}, {
  onMessage: (message) => {
    // Handle signaling messages yourself
  }
});

// Get local media
const localStream = await getUserMedia({ video: true, audio: true });

// Create WebRTC manager
const manager = new WebRTCManager({
  signalingSettings: settings,
  roomToken: token,
  sessionId: 'your-session-id',
  handlers: {
    onStream: (stream, peer) => {
      // Handle peer streams
    }
  }
});

manager.setLocalStream(localStream);
await manager.connect();

// Add peers
const peers = await client.call.getPeers(token);
for (const peer of peers) {
  await manager.addPeer(peer);
}

Browser Compatibility

Before using video calls, check browser support:

import { checkBrowserCompatibility, requireWebRTC } from '@noematicsllc/talk-sdk';

// Check compatibility
const compat = checkBrowserCompatibility();
if (!compat.webrtcSupported) {
  console.error('WebRTC not supported:', compat.errors);
}

// Or throw error if not supported
requireWebRTC(); // Throws if not supported

Message Polling

Implement efficient message polling using the spec's pattern:

let lastKnownMessageId = 0;

while (polling) {
  const result = await room.pollMessages({
    lastKnownMessageId,
    timeout: 30, // Long-poll timeout
  });

  for (const message of result.messages) {
    console.log(`${message.actorDisplayName}: ${message.message}`);
  }

  if (result.lastKnownMessageId) {
    lastKnownMessageId = result.lastKnownMessageId;
  }
}

Direct Resource Access

For advanced use cases, access resources directly:

// Direct resource access
const roomData = await client.roomResource.get('token');
const messages = await client.chat.receiveMessages('token', {
  lookIntoFuture: 0,
  limit: 100,
});

// Raw HTTP access
const response = await client.http.get('/custom/endpoint');

Types

All API types are exported for TypeScript users:

import {
  TalkRoom,
  TalkChatMessage,
  TalkParticipant,
  ConversationType,
  ParticipantType,
  Permission,
  InCallFlag,
} from '@noematicsllc/talk-sdk';

Error Handling

The SDK throws HttpClientError for API errors:

import { HttpClientError } from '@noematicsllc/talk-sdk';

try {
  await client.rooms.get('invalid-token');
} catch (error) {
  if (error instanceof HttpClientError) {
    console.error(`HTTP ${error.status}: ${error.message}`);
    console.error(`OCS Status: ${error.ocsStatus}`);
  }
}

Disclaimer

This is an unofficial, community-maintained TypeScript SDK for the Nextcloud Talk API.

  • NOT affiliated with Nextcloud GmbH
  • NOT endorsed by the Nextcloud project
  • NOT officially supported by Nextcloud
  • Maintained independently by the community
  • Use at your own risk

For official Nextcloud resources and support, please visit nextcloud.com or the Nextcloud GitHub organization.

License

MIT