233 lines
5.1 KiB
JavaScript
233 lines
5.1 KiB
JavaScript
// @flow
|
|
import * as Sentry from "@sentry/node";
|
|
import debug from "debug";
|
|
import services from "./services";
|
|
import { createQueue } from "./utils/queue";
|
|
|
|
const log = debug("services");
|
|
|
|
export type UserEvent =
|
|
| {
|
|
name: | "users.create" // eslint-disable-line
|
|
| "users.signin"
|
|
| "users.update"
|
|
| "users.suspend"
|
|
| "users.activate"
|
|
| "users.delete",
|
|
userId: string,
|
|
teamId: string,
|
|
actorId: string,
|
|
ip: string,
|
|
}
|
|
| {
|
|
name: "users.invite",
|
|
teamId: string,
|
|
actorId: string,
|
|
data: {
|
|
email: string,
|
|
name: string,
|
|
},
|
|
ip: string,
|
|
};
|
|
|
|
export type DocumentEvent =
|
|
| {
|
|
name: | "documents.create" // eslint-disable-line
|
|
| "documents.publish"
|
|
| "documents.delete"
|
|
| "documents.pin"
|
|
| "documents.unpin"
|
|
| "documents.archive"
|
|
| "documents.unarchive"
|
|
| "documents.restore"
|
|
| "documents.star"
|
|
| "documents.unstar",
|
|
documentId: string,
|
|
collectionId: string,
|
|
teamId: string,
|
|
actorId: string,
|
|
ip: string,
|
|
data: {
|
|
title: string,
|
|
source?: "import",
|
|
},
|
|
}
|
|
| {
|
|
name: "documents.move",
|
|
documentId: string,
|
|
collectionId: string,
|
|
teamId: string,
|
|
actorId: string,
|
|
data: {
|
|
collectionIds: string[],
|
|
documentIds: string[],
|
|
},
|
|
ip: string,
|
|
}
|
|
| {
|
|
name: | "documents.update" // eslint-disable-line
|
|
| "documents.update.delayed"
|
|
| "documents.update.debounced",
|
|
documentId: string,
|
|
collectionId: string,
|
|
createdAt: string,
|
|
teamId: string,
|
|
actorId: string,
|
|
data: {
|
|
title: string,
|
|
autosave: boolean,
|
|
done: boolean,
|
|
},
|
|
ip: string,
|
|
}
|
|
| {
|
|
name: "documents.title_change",
|
|
documentId: string,
|
|
collectionId: string,
|
|
createdAt: string,
|
|
teamId: string,
|
|
actorId: string,
|
|
data: {
|
|
title: string,
|
|
previousTitle: string,
|
|
},
|
|
ip: string,
|
|
};
|
|
|
|
export type RevisionEvent = {
|
|
name: "revisions.create",
|
|
documentId: string,
|
|
collectionId: string,
|
|
teamId: string,
|
|
};
|
|
|
|
export type CollectionImportEvent = {
|
|
name: "collections.import",
|
|
modelId: string,
|
|
teamId: string,
|
|
actorId: string,
|
|
data: { type: "outline" },
|
|
ip: string,
|
|
};
|
|
|
|
export type CollectionEvent =
|
|
| {
|
|
name: | "collections.create" // eslint-disable-line
|
|
| "collections.update"
|
|
| "collections.delete",
|
|
collectionId: string,
|
|
teamId: string,
|
|
actorId: string,
|
|
data: { name: string },
|
|
ip: string,
|
|
}
|
|
| {
|
|
name: "collections.add_user" | "collections.remove_user",
|
|
userId: string,
|
|
collectionId: string,
|
|
teamId: string,
|
|
actorId: string,
|
|
ip: string,
|
|
}
|
|
| {
|
|
name: "collections.add_group" | "collections.remove_group",
|
|
collectionId: string,
|
|
teamId: string,
|
|
actorId: string,
|
|
data: { name: string, groupId: string },
|
|
ip: string,
|
|
}
|
|
| {
|
|
name: "collections.move",
|
|
collectionId: string,
|
|
teamId: string,
|
|
actorId: string,
|
|
data: { index: string },
|
|
ip: string,
|
|
};
|
|
|
|
export type GroupEvent =
|
|
| {
|
|
name: "groups.create" | "groups.delete" | "groups.update",
|
|
actorId: string,
|
|
modelId: string,
|
|
teamId: string,
|
|
data: { name: string },
|
|
ip: string,
|
|
}
|
|
| {
|
|
name: "groups.add_user" | "groups.remove_user",
|
|
actorId: string,
|
|
userId: string,
|
|
modelId: string,
|
|
teamId: string,
|
|
data: { name: string },
|
|
ip: string,
|
|
};
|
|
|
|
export type IntegrationEvent = {
|
|
name: "integrations.create" | "integrations.update",
|
|
modelId: string,
|
|
teamId: string,
|
|
actorId: string,
|
|
ip: string,
|
|
};
|
|
|
|
export type TeamEvent = {
|
|
name: "teams.update",
|
|
teamId: string,
|
|
actorId: string,
|
|
data: Object,
|
|
ip: string,
|
|
};
|
|
|
|
export type Event =
|
|
| UserEvent
|
|
| DocumentEvent
|
|
| CollectionEvent
|
|
| CollectionImportEvent
|
|
| IntegrationEvent
|
|
| GroupEvent
|
|
| RevisionEvent
|
|
| TeamEvent;
|
|
|
|
const globalEventsQueue = createQueue("global events");
|
|
const serviceEventsQueue = createQueue("service events");
|
|
|
|
// this queue processes global events and hands them off to service hooks
|
|
globalEventsQueue.process(async (job) => {
|
|
const names = Object.keys(services);
|
|
names.forEach((name) => {
|
|
const service = services[name];
|
|
if (service.on) {
|
|
serviceEventsQueue.add(
|
|
{ ...job.data, service: name },
|
|
{ removeOnComplete: true }
|
|
);
|
|
}
|
|
});
|
|
});
|
|
|
|
// this queue processes an individual event for a specific service
|
|
serviceEventsQueue.process(async (job) => {
|
|
const event = job.data;
|
|
const service = services[event.service];
|
|
|
|
if (service.on) {
|
|
log(`${event.service} processing ${event.name}`);
|
|
|
|
service.on(event).catch((error) => {
|
|
if (process.env.SENTRY_DSN) {
|
|
Sentry.withScope(function (scope) {
|
|
scope.setExtra("event", event);
|
|
Sentry.captureException(error);
|
|
});
|
|
} else {
|
|
throw error;
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
export default globalEventsQueue;
|