Skip to content

Commit

Permalink
Add chat API support (#278)
Browse files Browse the repository at this point in the history
* Add chat API support

* Add receive support

* Add edit message support

* Fix editing

* reuse

* fix types

* Create funny-lamps-carry.md
  • Loading branch information
lukasIO authored Oct 14, 2024
1 parent b03ed37 commit b0ff41a
Show file tree
Hide file tree
Showing 9 changed files with 465 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/funny-lamps-carry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@livekit/rtc-node": patch
---

Add chat API support
1 change: 1 addition & 0 deletions packages/livekit-rtc/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ export { StreamState, TrackKind, TrackSource } from './proto/track_pb.js';
export { VideoBufferType, VideoRotation, VideoCodec } from './proto/video_frame_pb.js';
export { ParticipantKind } from './proto/participant_pb.js';
export { dispose } from './ffi_client.js';
export type { ChatMessage } from './types.js';
13 changes: 8 additions & 5 deletions packages/livekit-rtc/src/napi/native.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@

/* auto-generated by NAPI-RS */

export function livekitInitialize(callback: (data: Uint8Array) => void, captureLogs: boolean): void;
export function livekitFfiRequest(data: Uint8Array): Uint8Array;
export function livekitRetrievePtr(handle: Uint8Array): bigint;
export function livekitCopyBuffer(ptr: bigint, len: number): Uint8Array;
export function livekitDispose(): Promise<void>;
export declare function livekitInitialize(
callback: (data: Uint8Array) => void,
captureLogs: boolean,
): void;
export declare function livekitFfiRequest(data: Uint8Array): Uint8Array;
export declare function livekitRetrievePtr(handle: Uint8Array): bigint;
export declare function livekitCopyBuffer(ptr: bigint, len: number): Uint8Array;
export declare function livekitDispose(): Promise<void>;
export declare class FfiHandle {
constructor(handle: bigint);
dispose(): void;
Expand Down
79 changes: 78 additions & 1 deletion packages/livekit-rtc/src/participant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
// SPDX-License-Identifier: Apache-2.0
import { FfiClient, FfiHandle } from './ffi_client.js';
import type { OwnedParticipant, ParticipantInfo, ParticipantKind } from './proto/participant_pb.js';
import type {
import {
ChatMessage as ChatMessageModel,
PublishDataCallback,
PublishDataResponse,
PublishSipDtmfCallback,
Expand All @@ -12,6 +13,8 @@ import type {
PublishTrackResponse,
PublishTranscriptionCallback,
PublishTranscriptionResponse,
SendChatMessageCallback,
SendChatMessageResponse,
SetLocalAttributesCallback,
SetLocalAttributesResponse,
SetLocalMetadataCallback,
Expand All @@ -23,11 +26,13 @@ import type {
UnpublishTrackResponse,
} from './proto/room_pb.js';
import {
EditChatMessageRequest,
TranscriptionSegment as ProtoTranscriptionSegment,
PublishDataRequest,
PublishSipDtmfRequest,
PublishTrackRequest,
PublishTranscriptionRequest,
SendChatMessageRequest,
SetLocalAttributesRequest,
SetLocalMetadataRequest,
SetLocalNameRequest,
Expand All @@ -37,6 +42,7 @@ import type { LocalTrack } from './track.js';
import type { RemoteTrackPublication, TrackPublication } from './track_publication.js';
import { LocalTrackPublication } from './track_publication.js';
import type { Transcription } from './transcription.js';
import { ChatMessage } from './types.js';

export abstract class Participant {
/** @internal */
Expand Down Expand Up @@ -185,6 +191,77 @@ export class LocalParticipant extends Participant {
});
}

/**
*
*/
async sendChatMessage(
text: string,
destinationIdentities?: Array<string>,
senderIdentity?: string,
): Promise<ChatMessage> {
const req = new SendChatMessageRequest({
localParticipantHandle: this.ffi_handle.handle,
message: text,
destinationIdentities,
senderIdentity,
});

const res = FfiClient.instance.request<SendChatMessageResponse>({
message: { case: 'sendChatMessage', value: req },
});

const cb = await FfiClient.instance.waitFor<SendChatMessageCallback>((ev) => {
return ev.message.case == 'chatMessage' && ev.message.value.asyncId == res.asyncId;
});

if (cb.error) {
throw new Error(cb.error);
}
const { id, timestamp, editTimestamp, message } = cb.chatMessage;
return { id, timestamp: Number(timestamp), editTimestamp: Number(editTimestamp), message };
}

/**
* Sends a chat message to participants in the room
*
* @param text - The text content of the chat message.
* @param destinationIdentities - An optional array of recipient identities to whom the message will be sent. If omitted, the message is broadcast to all participants.
* @param senderIdentity - An optional identity of the sender. If omitted, the default sender identity is used.
*
*/
async editChatMessage(
editText: string,
originalMessage: ChatMessage,
destinationIdentities?: Array<string>,
senderIdentity?: string,
): Promise<ChatMessage> {
const req = new EditChatMessageRequest({
localParticipantHandle: this.ffi_handle.handle,
editText,
originalMessage: new ChatMessageModel({
...originalMessage,
timestamp: BigInt(originalMessage.timestamp),
editTimestamp: BigInt(originalMessage.editTimestamp),
}),
destinationIdentities,
senderIdentity,
});

const res = FfiClient.instance.request<SendChatMessageResponse>({
message: { case: 'editChatMessage', value: req },
});

const cb = await FfiClient.instance.waitFor<SendChatMessageCallback>((ev) => {
return ev.message.case == 'chatMessage' && ev.message.value.asyncId == res.asyncId;
});

if (cb.error) {
throw new Error(cb.error);
}
const { id, timestamp, editTimestamp, message } = cb.chatMessage;
return { id, timestamp: Number(timestamp), editTimestamp: Number(editTimestamp), message };
}

async updateName(name: string) {
const req = new SetLocalNameRequest({
localParticipantHandle: this.ffi_handle.handle,
Expand Down
30 changes: 29 additions & 1 deletion packages/livekit-rtc/src/proto/ffi_pb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
import { Message, proto3, protoInt64 } from "@bufbuild/protobuf";
import { ConnectCallback, ConnectRequest, ConnectResponse, DisconnectCallback, DisconnectRequest, DisconnectResponse, GetSessionStatsCallback, GetSessionStatsRequest, GetSessionStatsResponse, PublishDataCallback, PublishDataRequest, PublishDataResponse, PublishSipDtmfCallback, PublishSipDtmfRequest, PublishSipDtmfResponse, PublishTrackCallback, PublishTrackRequest, PublishTrackResponse, PublishTranscriptionCallback, PublishTranscriptionRequest, PublishTranscriptionResponse, RoomEvent, SetLocalAttributesCallback, SetLocalAttributesRequest, SetLocalAttributesResponse, SetLocalMetadataCallback, SetLocalMetadataRequest, SetLocalMetadataResponse, SetLocalNameCallback, SetLocalNameRequest, SetLocalNameResponse, SetSubscribedRequest, SetSubscribedResponse, UnpublishTrackCallback, UnpublishTrackRequest, UnpublishTrackResponse } from "./room_pb.js";
import { ConnectCallback, ConnectRequest, ConnectResponse, DisconnectCallback, DisconnectRequest, DisconnectResponse, EditChatMessageRequest, GetSessionStatsCallback, GetSessionStatsRequest, GetSessionStatsResponse, PublishDataCallback, PublishDataRequest, PublishDataResponse, PublishSipDtmfCallback, PublishSipDtmfRequest, PublishSipDtmfResponse, PublishTrackCallback, PublishTrackRequest, PublishTrackResponse, PublishTranscriptionCallback, PublishTranscriptionRequest, PublishTranscriptionResponse, RoomEvent, SendChatMessageCallback, SendChatMessageRequest, SendChatMessageResponse, SetLocalAttributesCallback, SetLocalAttributesRequest, SetLocalAttributesResponse, SetLocalMetadataCallback, SetLocalMetadataRequest, SetLocalMetadataResponse, SetLocalNameCallback, SetLocalNameRequest, SetLocalNameResponse, SetSubscribedRequest, SetSubscribedResponse, UnpublishTrackCallback, UnpublishTrackRequest, UnpublishTrackResponse } from "./room_pb.js";
import { CreateAudioTrackRequest, CreateAudioTrackResponse, CreateVideoTrackRequest, CreateVideoTrackResponse, EnableRemoteTrackRequest, EnableRemoteTrackResponse, GetStatsCallback, GetStatsRequest, GetStatsResponse, LocalTrackMuteRequest, LocalTrackMuteResponse, TrackEvent } from "./track_pb.js";
import { CaptureVideoFrameRequest, CaptureVideoFrameResponse, NewVideoSourceRequest, NewVideoSourceResponse, NewVideoStreamRequest, NewVideoStreamResponse, VideoConvertRequest, VideoConvertResponse, VideoStreamEvent, VideoStreamFromParticipantRequest, VideoStreamFromParticipantResponse } from "./video_frame_pb.js";
import { AudioStreamEvent, AudioStreamFromParticipantRequest, AudioStreamFromParticipantResponse, CaptureAudioFrameCallback, CaptureAudioFrameRequest, CaptureAudioFrameResponse, ClearAudioBufferRequest, ClearAudioBufferResponse, FlushSoxResamplerRequest, FlushSoxResamplerResponse, NewAudioResamplerRequest, NewAudioResamplerResponse, NewAudioSourceRequest, NewAudioSourceResponse, NewAudioStreamRequest, NewAudioStreamResponse, NewSoxResamplerRequest, NewSoxResamplerResponse, PushSoxResamplerRequest, PushSoxResamplerResponse, RemixAndResampleRequest, RemixAndResampleResponse } from "./audio_frame_pb.js";
Expand Down Expand Up @@ -285,6 +285,18 @@ export class FfiRequest extends Message<FfiRequest> {
*/
value: FlushSoxResamplerRequest;
case: "flushSoxResampler";
} | {
/**
* @generated from field: livekit.proto.SendChatMessageRequest send_chat_message = 36;
*/
value: SendChatMessageRequest;
case: "sendChatMessage";
} | {
/**
* @generated from field: livekit.proto.EditChatMessageRequest edit_chat_message = 37;
*/
value: EditChatMessageRequest;
case: "editChatMessage";
} | { case: undefined; value?: undefined } = { case: undefined };

constructor(data?: PartialMessage<FfiRequest>) {
Expand Down Expand Up @@ -329,6 +341,8 @@ export class FfiRequest extends Message<FfiRequest> {
{ no: 33, name: "new_sox_resampler", kind: "message", T: NewSoxResamplerRequest, oneof: "message" },
{ no: 34, name: "push_sox_resampler", kind: "message", T: PushSoxResamplerRequest, oneof: "message" },
{ no: 35, name: "flush_sox_resampler", kind: "message", T: FlushSoxResamplerRequest, oneof: "message" },
{ no: 36, name: "send_chat_message", kind: "message", T: SendChatMessageRequest, oneof: "message" },
{ no: 37, name: "edit_chat_message", kind: "message", T: EditChatMessageRequest, oneof: "message" },
]);

static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): FfiRequest {
Expand Down Expand Up @@ -569,6 +583,12 @@ export class FfiResponse extends Message<FfiResponse> {
*/
value: FlushSoxResamplerResponse;
case: "flushSoxResampler";
} | {
/**
* @generated from field: livekit.proto.SendChatMessageResponse send_chat_message = 36;
*/
value: SendChatMessageResponse;
case: "sendChatMessage";
} | { case: undefined; value?: undefined } = { case: undefined };

constructor(data?: PartialMessage<FfiResponse>) {
Expand Down Expand Up @@ -613,6 +633,7 @@ export class FfiResponse extends Message<FfiResponse> {
{ no: 33, name: "new_sox_resampler", kind: "message", T: NewSoxResamplerResponse, oneof: "message" },
{ no: 34, name: "push_sox_resampler", kind: "message", T: PushSoxResamplerResponse, oneof: "message" },
{ no: 35, name: "flush_sox_resampler", kind: "message", T: FlushSoxResamplerResponse, oneof: "message" },
{ no: 36, name: "send_chat_message", kind: "message", T: SendChatMessageResponse, oneof: "message" },
]);

static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): FfiResponse {
Expand Down Expand Up @@ -763,6 +784,12 @@ export class FfiEvent extends Message<FfiEvent> {
*/
value: PublishSipDtmfCallback;
case: "publishSipDtmf";
} | {
/**
* @generated from field: livekit.proto.SendChatMessageCallback chat_message = 22;
*/
value: SendChatMessageCallback;
case: "chatMessage";
} | { case: undefined; value?: undefined } = { case: undefined };

constructor(data?: PartialMessage<FfiEvent>) {
Expand Down Expand Up @@ -793,6 +820,7 @@ export class FfiEvent extends Message<FfiEvent> {
{ no: 19, name: "get_session_stats", kind: "message", T: GetSessionStatsCallback, oneof: "message" },
{ no: 20, name: "panic", kind: "message", T: Panic, oneof: "message" },
{ no: 21, name: "publish_sip_dtmf", kind: "message", T: PublishSipDtmfCallback, oneof: "message" },
{ no: 22, name: "chat_message", kind: "message", T: SendChatMessageCallback, oneof: "message" },
]);

static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): FfiEvent {
Expand Down
Loading

0 comments on commit b0ff41a

Please sign in to comment.