Skip to content

Commit

Permalink
feat(matrix): add some api
Browse files Browse the repository at this point in the history
  • Loading branch information
Anillc committed Jul 25, 2023
1 parent 88f6f23 commit 0a025fb
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 11 deletions.
26 changes: 26 additions & 0 deletions adapters/matrix/src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,32 @@ export class MatrixBot extends Bot<MatrixBot.Config> {
return await Promise.all(children.map(this.getChannel.bind(this)))
}

async getGuildMemberList(guildId: string): Promise<Universal.GuildMember[]> {
const state = await this.internal.getState(guildId)
const levels = state.find(event => event.type === 'm.room.power_levels').content as Matrix.M_ROOM_POWER_LEVELS
return state
.filter(event => event.type === 'm.room.member')
.map(event => {
const content = event.content as Matrix.M_ROOM_MEMBER
return {
userId: event.state_key,
username: event.state_key,
nickname: content.displayname,
avatar: this.internal.getAssetUrl(content.avatar_url),
isBot: !!this.ctx.bots.find(bot => bot.userId === event.state_key),
roles: [levels.users[event.state_key].toString()],
}
})
}

async getGuildMember(guildId: string, userId: string): Promise<Universal.GuildMember> {
return (await this.getGuildMemberList(guildId)).find(user => user.userId === userId)
}

async createReaction(channelId: string, messageId: string, emoji: string): Promise<void> {
await this.internal.sendReaction(channelId, this.userId, messageId, emoji)
}

async handleFriendRequest(): Promise<void> { }

// as utils.ts commented, messageId is roomId
Expand Down
81 changes: 72 additions & 9 deletions adapters/matrix/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,6 @@ export interface User {
user_id?: string
}

export interface RoomId {
room_id: string
}

export interface Sync {
account_data?: AccountData
// device_lists? // end to end
Expand Down Expand Up @@ -211,6 +207,34 @@ export interface LeftRoom {
timeline?: Timeline
}

export interface Invite3pid {
address: string
id_access_token: string
id_server: string
medium: string
}

export interface StateEvent {
content: EventContent
state_key?: string
type: string
}

export interface RoomCreation {
creation_content?: Partial<M_ROOM_CREATE>
initial_state?: StateEvent[]
invite?: string[]
invite_3pid?: Invite3pid
is_direct?: boolean
name: string
power_level_content_override?: M_ROOM_POWER_LEVELS
preset?: 'private_chat' | 'public_chat' | 'trusted_private_chat'
room_alias_name?: string
room_version?: string
topic?: string
visibility?: 'public' | 'private'
}

export interface EventContent {}

export interface Relation {
Expand Down Expand Up @@ -241,7 +265,7 @@ export interface M_ROOM_JOIN_RULES extends EventContent {

export interface M_ROOM_MEMBER extends EventContent {
avatar_url?: string
displayname?: string[]
displayname?: string
is_direct?: boolean
join_authorised_via_users_server?: string
membership?: 'invite' | 'join' | 'knock' | 'leave' | 'ban'
Expand Down Expand Up @@ -445,6 +469,15 @@ export interface M_SPACE_PARENT extends EventContent {
via?: string[]
}

export interface M_ANNOTATION extends Relation {
rel_type: 'm.annotation'
key: string
}

export interface M_REACTION extends EventContent {
'm.relates_to'?: M_ANNOTATION
}

export class Internal {
private txnId = Math.round(Math.random() * 1000)

Expand Down Expand Up @@ -494,6 +527,19 @@ export class Internal {
return response.event_id
}

async sendReaction(roomId: string, userId: string, messageId: string, key: string): Promise<string> {
const eventContent: M_REACTION = {
'm.relates_to': {
rel_type: 'm.annotation',
event_id: messageId,
key,
},
}
const response = await this.bot.http.put(
`/client/v3/rooms/${roomId}/send/m.reaction/${this.txnId++}?user_id=${userId}`, eventContent)
return response.event_id
}

async getEvent(roomId: string, eventId: string): Promise<ClientEvent> {
return await this.bot.http.get(`/client/v3/rooms/${roomId}/event/${eventId}`)
}
Expand All @@ -516,12 +562,23 @@ export class Internal {
await this.bot.http.put(`/client/v3/profile/${userId}/avatar_url`, { avatar_url: uri })
}

async joinRoom(roomId: string, reason?: string): Promise<RoomId> {
return await this.bot.http.post(`/client/v3/join/${roomId}`, { reason })
async createRoom(creation: RoomCreation): Promise<string> {
const response = await this.bot.http.post('/client/v3/createRoom', creation)
return response.room_id
}

async joinRoom(roomId: string, reason?: string): Promise<string> {
const response = await this.bot.http.post(`/client/v3/join/${roomId}`, { reason })
return response.room_id
}

async leaveRoom(roomId: string, reason?: string): Promise<string> {
const response = await this.bot.http.post(`/client/v3/rooms/${roomId}/leave`, { reason })
return response.room_id
}

async leaveRoom(roomId: string, reason?: string): Promise<RoomId> {
return await this.bot.http.post(`/client/v3/rooms/${roomId}/leave`, { reason })
async invite(roomId: string, userId: string, reason?: string): Promise<void> {
await this.bot.http.post(`/client/v3/rooms/${roomId}/invite`, { user_id: userId, reason })
}

async sync(fullSstate: boolean = false): Promise<Sync> {
Expand All @@ -534,6 +591,12 @@ export class Internal {
return await this.bot.http.get(`/client/v3/rooms/${roomId}/state`)
}

async setState(roomId: string, eventType: string, event: EventContent, state?: string): Promise<string> {
const statePath = state ? `/${state}` : ''
const response = await this.bot.http.put(`/client/v3/rooms/${roomId}/state/${eventType}${statePath}`, event)
return response.event_id
}

async getJoinedRooms(): Promise<string[]> {
return await this.bot.http.get('/client/v3/joined_rooms')
}
Expand Down
14 changes: 12 additions & 2 deletions adapters/matrix/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,20 @@ export async function adaptSession(bot: MatrixBot, event: Matrix.ClientEvent): P
session.timestamp = event.origin_server_ts
session.author = adaptAuthor(bot, event)
switch (event.type) {
case 'm.room.redaction':
session.type = 'message-delete'
case 'm.room.redaction': {
session.type = 'message-deleted'
session.subtype = 'group'
session.messageId = event.redacts
break
}
case 'm.reaction': {
const content = event.content as Matrix.M_REACTION
session.type = 'reaction-added'
session.subtype = 'group'
session.content = content['m.relates_to'].key
session.messageId = content['m.relates_to'].event_id
break
}
case 'm.room.member': {
bot.syncRooms()
const memberEvent = event.content as Matrix.M_ROOM_MEMBER
Expand Down

0 comments on commit 0a025fb

Please sign in to comment.