package livekit import ( "context" "time" "github.com/flowy-live/llink/internal/utils" "github.com/livekit/protocol/auth" "github.com/livekit/protocol/livekit" lksdk "github.com/livekit/server-sdk-go/v2" ) type Client interface { // GetJoinToken mints a participant JWT; name surfaces as the display name. GetJoinToken(roomId string, humanId string, name string) (string, error) ServerUrl() string ListParticipants(ctx context.Context, roomName string) ([]*livekit.ParticipantInfo, error) // KeyProvider is used by handlers to verify webhook signatures. KeyProvider() auth.KeyProvider } type clientImpl struct { apiSecret string apiKey string hostUrl string roomService *lksdk.RoomServiceClient keyProvider auth.KeyProvider } func NewClient() Client { apiKey := utils.MustGetEnv("LIVEKIT_API_KEY") apiSecret := utils.MustGetEnv("LIVEKIT_API_SECRET") hostUrl := utils.MustGetEnv("LIVEKIT_URL") roomService := lksdk.NewRoomServiceClient(hostUrl, apiKey, apiSecret) return &clientImpl{ apiSecret: apiSecret, apiKey: apiKey, hostUrl: hostUrl, roomService: roomService, keyProvider: auth.NewSimpleKeyProvider(apiKey, apiSecret), } } func (c *clientImpl) ServerUrl() string { return c.hostUrl } func (c *clientImpl) GetJoinToken(room, humanId, name string) (string, error) { at := auth.NewAccessToken(c.apiKey, c.apiSecret) grant := &auth.VideoGrant{ RoomJoin: true, Room: room, } at.SetVideoGrant(grant). SetIdentity(humanId). SetName(name). SetValidFor(time.Hour) return at.ToJWT() } func (c *clientImpl) ListParticipants(ctx context.Context, roomName string) ([]*livekit.ParticipantInfo, error) { resp, err := c.roomService.ListParticipants(ctx, &livekit.ListParticipantsRequest{ Room: roomName, }) if err != nil { return nil, err } return resp.Participants, nil } func (c *clientImpl) KeyProvider() auth.KeyProvider { return c.keyProvider }