Skip to content

Commit fd9d8fa

Browse files
committed
Add "list-new-joiners" command
1 parent e66068c commit fd9d8fa

File tree

4 files changed

+85
-1
lines changed

4 files changed

+85
-1
lines changed

src/admin-api/index.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,22 @@ class AdminApi {
125125
return users
126126
}
127127

128+
async getNewUserAccounts(limit: number): Promise<UserAccountShort[]> {
129+
let users: UserAccountShort[] = []
130+
let nextToken: string | null = null
131+
let total: number | null = null
132+
do {
133+
const result = (await this.makeRequest(
134+
"GET",
135+
`/v2/users?limit=${limit}${nextToken ? `&from=${nextToken}` : ``}&guests=false&order_by=creation_ts&dir=desc`,
136+
)) as UserAccountsResponse
137+
users = users.concat(result.users)
138+
nextToken = result.next_token || null
139+
total = result.total
140+
} while (nextToken !== null || users.length < total)
141+
return users
142+
}
143+
128144
async getRooms(): Promise<RoomInfoShort[]> {
129145
const limit = 50
130146
let rooms: RoomInfoShort[] = []

src/bot.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { LogService, MatrixClient, MatrixProfileInfo, MessageEvent, UserID } from "matrix-bot-sdk"
22

3+
import { LIST_NEW_JOINERS_COMMAND, runListNewJoinersCommand } from "src/commands/list-new-joiners"
34
import { LIST_ROOMS_COMMAND, runListRoomsCommand } from "src/commands/list-rooms"
45
import { LIST_SPACES_COMMAND, runListSpacesCommand } from "src/commands/list-spaces"
56
import config from "src/config/env"
@@ -108,6 +109,8 @@ export default class Bot {
108109
return await runListRoomsCommand(roomId, event, this.client, args[1])
109110
case LIST_SPACES_COMMAND:
110111
return await runListSpacesCommand(roomId, event, this.client)
112+
case LIST_NEW_JOINERS_COMMAND:
113+
return await runListNewJoinersCommand(roomId, event, this.client, args)
111114
case PROMOTE_COMMAND:
112115
return await runPromoteCommand(roomId, event, args, this.client, this.userId)
113116
case DELETE_ROOM_COMMAND:

src/commands/help.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,21 @@ import htmlEscape from "escape-html"
22
import { MatrixClient, MessageEvent, MessageEventContent, RichReply } from "matrix-bot-sdk"
33

44
import { ACCOUNT_COMMAND, Command as AccountSubcommand } from "src/commands/account"
5-
import { WELCOME_MESSAGE_COMMAND, Command as WelcomeMessageSubcommand } from "src/commands/welcome-message"
65
import { BULK_INVITE_COMMAND } from "src/commands/bulk-invite"
76
import { DEACTIVATE_USER_COMMAND } from "src/commands/deactivate-user"
87
import { DELETE_ROOM_COMMAND } from "src/commands/delete-room"
98
import { defaultGroups, INVITE_COMMAND } from "src/commands/invite"
9+
import {
10+
LIST_NEW_JOINERS_COMMAND,
11+
LIST_NEW_JOINERS_DEFAULT_LIMIT,
12+
LIST_NEW_JOINERS_MAX_LIMIT,
13+
LIST_NEW_JOINERS_MIN_LIMIT,
14+
} from "src/commands/list-new-joiners"
1015
import { LIST_ROOMS_COMMAND } from "src/commands/list-rooms"
1116
import { LIST_SPACES_COMMAND } from "src/commands/list-spaces"
1217
import { PROMOTE_COMMAND } from "src/commands/promote"
1318
import { SPACE_COMMAND } from "src/commands/space"
19+
import { Command as WelcomeMessageSubcommand, WELCOME_MESSAGE_COMMAND } from "src/commands/welcome-message"
1420
import config from "src/config/env"
1521
import { groupedRooms } from "src/config/rooms"
1622
import { commandPrefix } from "src/constants"
@@ -37,6 +43,12 @@ ${commandPrefix} ${LIST_SPACES_COMMAND}
3743
3844
--------------------------------------------------
3945
46+
${commandPrefix} ${LIST_NEW_JOINERS_COMMAND} [<number>]
47+
Show the last registered users on the server.
48+
[<number>] - (Optional) how many users to list. Default: ${LIST_NEW_JOINERS_DEFAULT_LIMIT}, Min: ${LIST_NEW_JOINERS_MIN_LIMIT}, Max: ${LIST_NEW_JOINERS_MAX_LIMIT}
49+
50+
--------------------------------------------------
51+
4052
${commandPrefix} ${SPACE_COMMAND} <spaceId> [list | add | remove] [<roomId>]
4153
A command for managing spacess. See examples below.
4254
<spaceId> - Matrix room id or alias for the space

src/commands/list-new-joiners.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { MatrixClient, MessageEvent, MessageEventContent } from "matrix-bot-sdk"
2+
3+
import { adminApi } from "src/admin-api"
4+
import { canExecuteCommand, CommandError, sendMessage } from "src/utils"
5+
6+
export const LIST_NEW_JOINERS_COMMAND = "list-new-joiners"
7+
export const LIST_NEW_JOINERS_DEFAULT_LIMIT = 10
8+
export const LIST_NEW_JOINERS_MIN_LIMIT = 1
9+
export const LIST_NEW_JOINERS_MAX_LIMIT = 100
10+
11+
export async function runListNewJoinersCommand(
12+
roomId: string,
13+
event: MessageEvent<MessageEventContent>,
14+
client: MatrixClient,
15+
args: string[],
16+
): Promise<string> {
17+
// Ensure the user can execute the command
18+
const canExecute = await canExecuteCommand(event.sender, roomId)
19+
if (!canExecute) {
20+
throw new CommandError(`Access denied`)
21+
}
22+
23+
// Parse optional limit argument
24+
const limitArg = args?.[1]
25+
let limit = LIST_NEW_JOINERS_DEFAULT_LIMIT
26+
if (limitArg !== undefined) {
27+
const parsed = Number(limitArg)
28+
if (!Number.isFinite(parsed)) {
29+
throw new CommandError(
30+
`Invalid limit. Provide a number between ${LIST_NEW_JOINERS_MIN_LIMIT} and ${LIST_NEW_JOINERS_MAX_LIMIT}.`,
31+
)
32+
}
33+
const floored = Math.floor(parsed)
34+
limit = Math.min(LIST_NEW_JOINERS_MAX_LIMIT, Math.max(LIST_NEW_JOINERS_MIN_LIMIT, floored))
35+
}
36+
37+
const users = await adminApi.getNewUserAccounts(limit)
38+
console.log("new joiners", JSON.stringify(users))
39+
const filtered = users.filter((u) => !u.is_guest && !u.deactivated)
40+
41+
if (!filtered.length) {
42+
return await sendMessage(client, roomId, "No users found")
43+
}
44+
45+
const lines = filtered
46+
.map((u) => {
47+
const createdAt = new Date(u.creation_ts).toISOString()
48+
return `${u.name}, ${u.displayname ?? ""}, ${createdAt}`
49+
})
50+
.join("\n")
51+
52+
return await client.sendHtmlText(roomId, `New joiners (Name, Displayname, CreatedAt):<br/><br/><pre>${lines}</pre>`)
53+
}

0 commit comments

Comments
 (0)