mirror of
https://github.com/matrix-org/mjolnir.git
synced 2024-10-01 01:36:06 -04:00
switch to setTimeout, handle exceptions
This commit is contained in:
parent
3994999306
commit
3320fee9a0
@ -68,7 +68,7 @@ const ENABLED_PROTECTIONS_EVENT_TYPE = "org.matrix.mjolnir.enabled_protections";
|
||||
const PROTECTED_ROOMS_EVENT_TYPE = "org.matrix.mjolnir.protected_rooms";
|
||||
const WARN_UNPROTECTED_ROOM_EVENT_PREFIX = "org.matrix.mjolnir.unprotected_room_warning.for.";
|
||||
const CONSEQUENCE_EVENT_DATA = "org.matrix.mjolnir.consequence";
|
||||
const REPORT_POLL_EVENT_TYPE = "org.matrix.mjolnir.report_poll";
|
||||
export const REPORT_POLL_EVENT_TYPE = "org.matrix.mjolnir.report_poll";
|
||||
|
||||
export class Mjolnir {
|
||||
private displayName: string;
|
||||
@ -260,6 +260,7 @@ export class Mjolnir {
|
||||
const reportManager = new ReportManager(this);
|
||||
reportManager.on("report.new", this.handleReport);
|
||||
this.webapis = new WebAPIs(reportManager, this.ruleServer);
|
||||
this.reportPoll = new ReportPoll(this, reportManager);
|
||||
// Setup join/leave listener
|
||||
this.roomJoins = new RoomMemberManager(this.client);
|
||||
this.taskQueue = new ThrottlingQueue(this, config.backgroundDelayMS);
|
||||
|
@ -14,14 +14,15 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { MatrixClient } from "matrix-bot-sdk";
|
||||
import { Mjolnir, REPORT_POLL_EVENT_TYPE } from "../Mjolnir";
|
||||
import { ReportManager } from './ReportManager';
|
||||
import { LogLevel } from "matrix-bot-sdk";
|
||||
|
||||
class InvalidStateError extends Error {}
|
||||
|
||||
export class ReportPoll {
|
||||
private from = 0;
|
||||
private interval: ReturnType<typeof setInterval> | null = null;
|
||||
private timeout: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
/*
|
||||
* A class to poll synapse's report endpoint, so we can act on new reports
|
||||
@ -31,50 +32,71 @@ export class ReportPoll {
|
||||
* @param save An abstract function to persist where we got to in report reading
|
||||
*/
|
||||
constructor(
|
||||
private client: MatrixClient,
|
||||
private mjolnir: Mjolnir,
|
||||
private manager: ReportManager,
|
||||
private save: (a: number) => Promise<any>
|
||||
) { }
|
||||
|
||||
private schedulePoll() {
|
||||
const self = this;
|
||||
this.timeout = setTimeout(
|
||||
function() { self.getAbuseReports() },
|
||||
60_000 // a minute in milliseconds
|
||||
);
|
||||
}
|
||||
|
||||
private async getAbuseReports(): Promise<any> {
|
||||
const response = await this.client.doRequest(
|
||||
let response_: {
|
||||
event_reports: { room_id: string, event_id: string, sender: string, reason: string }[],
|
||||
next_token: number | undefined
|
||||
} | undefined = undefined;
|
||||
try {
|
||||
response_ = await this.mjolnir.client.doRequest(
|
||||
"GET",
|
||||
"/_synapse/admin/v1/event_reports",
|
||||
{ from: this.from.toString() }
|
||||
);
|
||||
} catch (ex) {
|
||||
await this.mjolnir.logMessage(LogLevel.ERROR, "getAbuseReports", `failed to poll events: ${ex}`);
|
||||
this.schedulePoll();
|
||||
}
|
||||
|
||||
const response = response_!;
|
||||
for (let report of response.event_reports) {
|
||||
const event = await this.client.getEvent(report.room_id, report.event_id);
|
||||
let event: any; // `any` because `getEvent` and `handleServerAbuseReport` also use `any`
|
||||
try {
|
||||
event = await this.mjolnir.client.getEvent(report.room_id, report.event_id);
|
||||
} catch (ex) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await this.manager.handleServerAbuseReport({
|
||||
roomId: report.room_id,
|
||||
reporterId: report.sender,
|
||||
event: event,
|
||||
reason: report.event,
|
||||
reason: report.reason,
|
||||
});
|
||||
}
|
||||
|
||||
if (response.next_token !== undefined) {
|
||||
this.from = response.next_token;
|
||||
await this.save(response.next_token);
|
||||
await this.mjolnir.client.setAccountData(REPORT_POLL_EVENT_TYPE, { from: response.next_token });
|
||||
}
|
||||
|
||||
this.schedulePoll();
|
||||
}
|
||||
|
||||
public start(startFrom: number) {
|
||||
if (this.interval === null) {
|
||||
if (this.timeout === null) {
|
||||
this.from = startFrom;
|
||||
const self = this;
|
||||
this.interval = setInterval(
|
||||
function() { self.getAbuseReports() },
|
||||
60_000 // a minute in milliseconds
|
||||
);
|
||||
this.schedulePoll();
|
||||
} else {
|
||||
throw new InvalidStateError("cannot start an already started poll");
|
||||
}
|
||||
}
|
||||
public stop() {
|
||||
if (this.interval !== null) {
|
||||
clearInterval(this.interval);
|
||||
this.interval = null;
|
||||
if (this.timeout !== null) {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = null;
|
||||
} else {
|
||||
throw new InvalidStateError("cannot stop a poll that hasn't started");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user