Redirect to last day with message history (#65)
Redirect to last day with message history: `/:roomIdOrAlias` -> `/:roomIdOrAlias/date/:yyyy/:mm/:dd` Fix https://github.com/matrix-org/matrix-public-archive/issues/60
This commit is contained in:
parent
127d416e6a
commit
65a371910a
|
@ -4,6 +4,7 @@ const assert = require('assert');
|
||||||
const urlJoin = require('url-join');
|
const urlJoin = require('url-join');
|
||||||
|
|
||||||
const { fetchEndpointAsJson } = require('../fetch-endpoint');
|
const { fetchEndpointAsJson } = require('../fetch-endpoint');
|
||||||
|
const timestampToEvent = require('./timestamp-to-event');
|
||||||
const { traceFunction } = require('../../tracing/trace-utilities');
|
const { traceFunction } = require('../../tracing/trace-utilities');
|
||||||
|
|
||||||
const config = require('../config');
|
const config = require('../config');
|
||||||
|
@ -27,14 +28,12 @@ async function fetchEventsFromTimestampBackwards(accessToken, roomId, ts, limit)
|
||||||
assert(ts);
|
assert(ts);
|
||||||
assert(limit);
|
assert(limit);
|
||||||
|
|
||||||
const timestampToEventEndpoint = urlJoin(
|
const { eventId: eventIdForTimestamp } = await timestampToEvent({
|
||||||
matrixServerUrl,
|
|
||||||
`_matrix/client/unstable/org.matrix.msc3030/rooms/${roomId}/timestamp_to_event?ts=${ts}&dir=b`
|
|
||||||
);
|
|
||||||
const timestampToEventResData = await fetchEndpointAsJson(timestampToEventEndpoint, {
|
|
||||||
accessToken,
|
accessToken,
|
||||||
|
roomId,
|
||||||
|
ts,
|
||||||
|
direction: 'b',
|
||||||
});
|
});
|
||||||
const eventIdForTimestamp = timestampToEventResData.event_id;
|
|
||||||
assert(eventIdForTimestamp);
|
assert(eventIdForTimestamp);
|
||||||
//console.log('eventIdForTimestamp', eventIdForTimestamp);
|
//console.log('eventIdForTimestamp', eventIdForTimestamp);
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ async function fetchPublicRooms(accessToken, { server, paginationToken, limit }
|
||||||
matrixServerUrl,
|
matrixServerUrl,
|
||||||
`_matrix/client/v3/publicRooms?${qs.toString()}`
|
`_matrix/client/v3/publicRooms?${qs.toString()}`
|
||||||
);
|
);
|
||||||
console.log('publicRoomsEndpoint', publicRoomsEndpoint);
|
|
||||||
|
|
||||||
const publicRoomsRes = await fetchEndpointAsJson(publicRoomsEndpoint, {
|
const publicRoomsRes = await fetchEndpointAsJson(publicRoomsEndpoint, {
|
||||||
accessToken,
|
accessToken,
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const assert = require('assert');
|
||||||
|
const urlJoin = require('url-join');
|
||||||
|
|
||||||
|
const { fetchEndpointAsJson } = require('../fetch-endpoint');
|
||||||
|
const { traceFunction } = require('../../tracing/trace-utilities');
|
||||||
|
|
||||||
|
const config = require('../config');
|
||||||
|
const matrixServerUrl = config.get('matrixServerUrl');
|
||||||
|
assert(matrixServerUrl);
|
||||||
|
|
||||||
|
async function timestampToEvent({ accessToken, roomId, ts, direction }) {
|
||||||
|
assert(accessToken);
|
||||||
|
assert(roomId);
|
||||||
|
assert(ts);
|
||||||
|
assert(direction);
|
||||||
|
|
||||||
|
const timestampToEventEndpoint = urlJoin(
|
||||||
|
matrixServerUrl,
|
||||||
|
`_matrix/client/unstable/org.matrix.msc3030/rooms/${roomId}/timestamp_to_event?ts=${ts}&dir=${direction}`
|
||||||
|
);
|
||||||
|
const timestampToEventResData = await fetchEndpointAsJson(timestampToEventEndpoint, {
|
||||||
|
accessToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
eventId: timestampToEventResData.event_id,
|
||||||
|
originServerTs: timestampToEventResData.origin_server_ts,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = traceFunction(timestampToEvent);
|
|
@ -12,7 +12,9 @@ const timeoutMiddleware = require('./timeout-middleware');
|
||||||
const fetchRoomData = require('../lib/matrix-utils/fetch-room-data');
|
const fetchRoomData = require('../lib/matrix-utils/fetch-room-data');
|
||||||
const fetchEventsInRange = require('../lib/matrix-utils/fetch-events-in-range');
|
const fetchEventsInRange = require('../lib/matrix-utils/fetch-events-in-range');
|
||||||
const ensureRoomJoined = require('../lib/matrix-utils/ensure-room-joined');
|
const ensureRoomJoined = require('../lib/matrix-utils/ensure-room-joined');
|
||||||
|
const timestampToEvent = require('../lib/matrix-utils/timestamp-to-event');
|
||||||
const renderHydrogenVmRenderScriptToPageHtml = require('../hydrogen-render/render-hydrogen-vm-render-script-to-page-html');
|
const renderHydrogenVmRenderScriptToPageHtml = require('../hydrogen-render/render-hydrogen-vm-render-script-to-page-html');
|
||||||
|
const MatrixPublicArchiveURLCreator = require('matrix-public-archive-shared/lib/url-creator');
|
||||||
|
|
||||||
const config = require('../lib/config');
|
const config = require('../lib/config');
|
||||||
const basePath = config.get('basePath');
|
const basePath = config.get('basePath');
|
||||||
|
@ -24,6 +26,8 @@ assert(matrixAccessToken);
|
||||||
const archiveMessageLimit = config.get('archiveMessageLimit');
|
const archiveMessageLimit = config.get('archiveMessageLimit');
|
||||||
assert(archiveMessageLimit);
|
assert(archiveMessageLimit);
|
||||||
|
|
||||||
|
const matrixPublicArchiveURLCreator = new MatrixPublicArchiveURLCreator(basePath);
|
||||||
|
|
||||||
const router = express.Router({
|
const router = express.Router({
|
||||||
caseSensitive: true,
|
caseSensitive: true,
|
||||||
// Preserve the req.params values from the parent router.
|
// Preserve the req.params values from the parent router.
|
||||||
|
@ -73,6 +77,40 @@ function parseArchiveRangeFromReq(req) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
router.get(
|
||||||
|
'/',
|
||||||
|
asyncHandler(async function (req, res) {
|
||||||
|
const roomIdOrAlias = req.params.roomIdOrAlias;
|
||||||
|
assert(roomIdOrAlias.startsWith('!') || roomIdOrAlias.startsWith('#'));
|
||||||
|
|
||||||
|
// In case we're joining a new room for the first time,
|
||||||
|
// let's avoid redirecting to our join event
|
||||||
|
const dateBeforeJoin = Date.now();
|
||||||
|
|
||||||
|
// We have to wait for the room join to happen first before we can fetch
|
||||||
|
// any of the additional room info or messages.
|
||||||
|
await ensureRoomJoined(matrixAccessToken, roomIdOrAlias, req.query.via);
|
||||||
|
|
||||||
|
// Find the closest day to today with messages
|
||||||
|
const { originServerTs } = await timestampToEvent({
|
||||||
|
accessToken: matrixAccessToken,
|
||||||
|
roomId: roomIdOrAlias,
|
||||||
|
ts: dateBeforeJoin,
|
||||||
|
direction: 'b',
|
||||||
|
});
|
||||||
|
if (!originServerTs) {
|
||||||
|
throw new StatusError(404, 'Unable to find day with an history');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redirect to a day with messages
|
||||||
|
res.redirect(
|
||||||
|
matrixPublicArchiveURLCreator.archiveUrlForDate(roomIdOrAlias, new Date(originServerTs), {
|
||||||
|
viaServers: req.query.via,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
'/event/:eventId',
|
'/event/:eventId',
|
||||||
asyncHandler(async function (req, res) {
|
asyncHandler(async function (req, res) {
|
||||||
|
|
|
@ -160,6 +160,38 @@ describe('matrix-public-archive', () => {
|
||||||
return sendEvent(options);
|
return sendEvent(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it('redirects to last day with message history', async () => {
|
||||||
|
const client = await getTestClientForHs(testMatrixServerUrl1);
|
||||||
|
const roomId = await createTestRoom(client);
|
||||||
|
|
||||||
|
// Send an event in the room so we have some day of history to redirect to
|
||||||
|
const eventId = await sendMessageOnArchiveDate({
|
||||||
|
client,
|
||||||
|
roomId,
|
||||||
|
content: {
|
||||||
|
msgtype: 'm.text',
|
||||||
|
body: 'some message in the history',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const expectedEventIdsOnDay = [eventId];
|
||||||
|
|
||||||
|
// Visit `/:roomIdOrAlias` and expect to be redirected to the last day with events
|
||||||
|
archiveUrl = matrixPublicArchiveURLCreator.archiveUrlForRoom(roomId);
|
||||||
|
const archivePageHtml = await fetchEndpointAsText(archiveUrl);
|
||||||
|
|
||||||
|
const dom = parseHTML(archivePageHtml);
|
||||||
|
|
||||||
|
// Make sure the messages from the day we expect to get redirected to are visible
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
expectedEventIdsOnDay.map((eventId) => {
|
||||||
|
return dom.document
|
||||||
|
.querySelector(`[data-event-id="${eventId}"]`)
|
||||||
|
?.getAttribute('data-event-id');
|
||||||
|
}),
|
||||||
|
expectedEventIdsOnDay
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('shows all events in a given day', async () => {
|
it('shows all events in a given day', async () => {
|
||||||
const client = await getTestClientForHs(testMatrixServerUrl1);
|
const client = await getTestClientForHs(testMatrixServerUrl1);
|
||||||
const roomId = await createTestRoom(client);
|
const roomId = await createTestRoom(client);
|
||||||
|
|
Loading…
Reference in New Issue