import { IJoinRoomStrategy } from "./JoinRoomStrategy";
import { Appservice } from "../appservice/Appservice";
/**
* A join strategy for application services that proxies joins to an underlying join
* strategy while also trying to use the appservice's bot user to invite the underlying
* user if needed.
* @category Join strategies
*/
export class AppserviceJoinRoomStrategy implements IJoinRoomStrategy {
constructor(private underlyingStrategy: IJoinRoomStrategy, private appservice: Appservice) {
}
public async joinRoom(roomIdOrAlias: string, userId: string, apiCall: (targetRoomIdOrAlias: string) => Promise<string>): Promise<string> {
try {
// First just try joining via the apiCall
return await apiCall(roomIdOrAlias);
} catch (err) {
// If the user being joined is *not* the bridge bot, try and get the bridge bot to
// join them to the room.
if (userId !== this.appservice.botUserId) {
const client = this.appservice.botIntent.underlyingClient;
const roomId = await client.resolveRoom(roomIdOrAlias);
try {
// First start with having the bridge bot invite the user to the room
await client.inviteUser(userId, roomId);
} catch (inviteErr) {
// The invite failed - use the underlying join strategy to join the room, just in case.
// If there's no join strategy, we want to fall through to an error.
if (this.underlyingStrategy) return this.underlyingStrategy.joinRoom(roomId, userId, apiCall);
throw inviteErr;
}
// The invite succeeded - use the underlying join strategy to join the room or just call use
// the apiCall if no strategy exists. We are expecting success.
if (this.underlyingStrategy) return this.underlyingStrategy.joinRoom(roomId, userId, apiCall);
else return apiCall(roomId);
} else if (this.underlyingStrategy) {
// If the user being joined *is* the bridge bot, try and use the join strategy to join.
return this.underlyingStrategy.joinRoom(roomIdOrAlias, userId, apiCall);
}
// Finally, if all else fails, throw.
throw err;
}
}
}
Source