diff --git a/src/MatrixClient.ts b/src/MatrixClient.ts index 14c55956..a7df31d1 100644 --- a/src/MatrixClient.ts +++ b/src/MatrixClient.ts @@ -44,6 +44,7 @@ import { DMs } from "./DMs"; import { ServerVersions } from "./models/ServerVersions"; import { RoomCreateOptions } from "./models/CreateRoom"; import { PresenceState } from './models/events/PresenceEvent'; +import { GetRoomMessagesResponse } from "./models/Messages"; const SYNC_BACKOFF_MIN_MS = 5000; const SYNC_BACKOFF_MAX_MS = 15000; @@ -1977,6 +1978,20 @@ export class MatrixClient extends EventEmitter { return this.doRequest("GET", url); } + /** + * Get relations for a given event. + * @param {string} roomId The room ID to for the given event. + * @param {string} eventId The event ID to list relations for. + * @param {string?} relationType The type of relations (e.g. `m.room.member`) to filter for. Optional. + * @param {string?} eventType The type of event to look for (e.g. `m.room.member`). Optional. + * @returns {Promise<{chunk: any[]}>} Resolves to an object containing the chunk of relations + */ + @timedMatrixClientFunctionCall() + public async getMessages(roomId: string, dir: "b"|"f", opts: Partial<{filter: string, from: string, limit: number, to: string}>): Promise { + const url = `/_matrix/client/v3/rooms/${encodeURIComponent(roomId)}/messages`; + return this.doRequest("GET", url, { dir, ...opts }); + } + /** * Performs a web request to the homeserver, applying appropriate authorization headers for * this client. diff --git a/src/models/Messages.ts b/src/models/Messages.ts new file mode 100644 index 00000000..738d3961 --- /dev/null +++ b/src/models/Messages.ts @@ -0,0 +1,29 @@ +import { RoomEventContent } from "./events/RoomEvent"; + +export interface GetRoomMessagesResponse { + /** + * A list of room events. The order depends on the dir parameter passed to the function. + * For dir=b events will be in reverse-chronological order, + * For dir=f in chronological order. (The exact definition of chronological is dependent on the server implementation.) + * + * Note that an empty array does not necessarily imply that no more events are available. You can continue + * to paginate until `end` is empty. + */ + chunk: RoomEventContent[]; + /** + * A token corresponding to the end of `chunk`. This token can be passed back to getMessages to request further events. + * If no further events are available (either because we have reached the start of the timeline, or because you do + * not have permission to see any more events), this property will not be provided. + */ + end?: string; + /** + * A token corresponding to the start of chunk. + */ + start: string; + /** + * A list of state events relevant to showing the `chunk`. + * For example, if `lazy_load_members` is enabled in the provided filter then this + * may contain the membership events for the senders of events in the `chunk`. + */ + state: RoomEventContent[]; +} \ No newline at end of file diff --git a/test/MatrixClientTest.ts b/test/MatrixClientTest.ts index f7980df9..c0d95b4c 100644 --- a/test/MatrixClientTest.ts +++ b/test/MatrixClientTest.ts @@ -6998,6 +6998,45 @@ describe('MatrixClient', () => { }); }); + describe('getMessages', () => { + it('should call the right endpoint', async () => { + const roomId = "!room_id:room.org"; + const { client, http } = createTestClient(); + + const dir = "b"; + const opts = { + filter: "my-filter", + from: "from-token", + limit: 50, + to: "to-token", + }; + const expectedResponse = { + chunk: [{ + my: "event", + }], + start: "start-token", + end: "end-token", + state: [{ + state: "event", + }], + }; + + // noinspection TypeScriptValidateJSTypes + http.when("GET", `/_matrix/client/v3/rooms/${encodeURIComponent(roomId)}/messages`).respond(200, (_path, _content, req) => { + expect(req.queryParams["dir"]).toEqual("b"); + expect(req.queryParams["filter"]).toEqual("my-filter"); + expect(req.queryParams["from"]).toEqual("from-token"); + expect(req.queryParams["limit"]).toEqual(50); + expect(req.queryParams["to"]).toEqual("to-token"); + return expectedResponse; + }); + + + const [messageResponse] = await Promise.all([client.getMessages(roomId, dir, opts), http.flushAllExpected()]); + expect(messageResponse).toEqual(expectedResponse); + }); + }); + describe('redactObjectForLogging', () => { it('should redact multilevel objects', () => { const input = {