Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
node_modules
.parcel-cache

.env
.env.local
.env.*.local

# yarn
.pnp.*
Expand Down
55 changes: 54 additions & 1 deletion packages/api/src/EmbeddedChatApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,16 @@ export default class EmbeddedChatApi {

async channelInfo() {
try {
const { userId, authToken } = (await this.auth.getCurrentUser()) || {};
const currentUser = await this.auth.getCurrentUser();
if (!currentUser || !currentUser.authToken || !currentUser.userId) {
return {
success: false,
error: "User not authenticated",
errorType: "unauthorized",
};
}

const { userId, authToken } = currentUser;
const response = await fetch(
`${this.host}/api/v1/rooms.info?roomId=${this.rid}`,
{
Expand All @@ -482,6 +491,50 @@ export default class EmbeddedChatApi {
return await response.json();
} catch (err) {
console.error(err);
return {
success: false,
error: err instanceof Error ? err.message : "Unknown error",
};
}
}

async getRoomIdByName(channelName: string): Promise<string | null> {
try {
const currentUser = await this.auth.getCurrentUser();
if (!currentUser || !currentUser.authToken || !currentUser.userId) {
return null;
}

const { userId, authToken } = currentUser;
const response = await fetch(
`${this.host}/api/v1/rooms.info?roomName=${encodeURIComponent(
channelName
)}`,
{
headers: {
"Content-Type": "application/json",
"X-Auth-Token": authToken,
"X-User-Id": userId,
},
method: "GET",
}
);

if (!response.ok) {
if (response.status === 401) {
return null;
}
return null;
}

const data = await response.json();
if (data?.success === true && data?.room?._id) {
return data.room._id;
}
return null;
} catch (err) {
console.error(err);
return null;
}
}

Expand Down
93 changes: 93 additions & 0 deletions packages/react/src/hooks/useRoomId.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { useState, useEffect } from 'react';
import { EmbeddedChatApi } from '@embeddedchat/api';

/**
* Custom hook to resolve roomId from either explicit roomId or channelName.
* Returns an object with:
* - roomId: The resolved room ID, or null if resolution is pending/failed
* - error: Error message if resolution failed, or null if successful/pending
*
* @param {string|null|undefined} roomId - Explicit room ID
* @param {string|null|undefined} channelName - Channel name to resolve
* @param {string} host - Rocket.Chat host URL
* @param {Function} getToken - Token getter function
* @param {Function} deleteToken - Token deleter function
* @param {Function} saveToken - Token saver function
* @param {boolean} isUserAuthenticated - Whether user is authenticated
* @returns {{roomId: string|null, error: string|null}} - Resolved room ID and error state
*/
export const useRoomId = (
roomId,
channelName,
host,
getToken,
deleteToken,
saveToken,
isUserAuthenticated
) => {
const [resolvedRoomId, setResolvedRoomId] = useState(() => {
if (roomId) {
return { roomId, error: null };
}
return channelName
? { roomId: 'GENERAL', error: null }
: { roomId: 'GENERAL', error: null };
});

useEffect(() => {
const resolveRoomId = async () => {
if (roomId) {
setResolvedRoomId({ roomId, error: null });
return;
}

if (channelName) {
if (!isUserAuthenticated) {
setResolvedRoomId({ roomId: 'GENERAL', error: null });
return;
}

try {
const tempRCInstance = new EmbeddedChatApi(host, 'GENERAL', {
getToken,
deleteToken,
saveToken,
});
const roomIdFromName = await tempRCInstance.getRoomIdByName(
channelName
);
await tempRCInstance.close().catch(console.error);
if (roomIdFromName) {
setResolvedRoomId({ roomId: roomIdFromName, error: null });
} else {
setResolvedRoomId({
roomId: null,
error: `Channel "${channelName}" not found or you don't have access to it.`,
});
}
} catch (error) {
setResolvedRoomId({
roomId: null,
error: `Failed to resolve channel "${channelName}": ${
error.message || 'Unknown error'
}`,
});
}
} else {
setResolvedRoomId({ roomId: 'GENERAL', error: null });
}
};

resolveRoomId();
}, [
roomId,
channelName,
host,
getToken,
deleteToken,
saveToken,
isUserAuthenticated,
]);

return resolvedRoomId;
};
Loading