trello/sources/card-due-date-reminder/card-due-date-reminder.mjs
import ms from "ms"; import taskScheduler from "../../../pipedream/sources/new-scheduled-tasks/new-scheduled-tasks.mjs"; import constants from "../../common/constants.mjs"; import trello from "../../trello.app.mjs"; import sampleEmit from "./test-event.mjs"; export default { key: "trello-card-due-date-reminder", name: "Card Due Date Reminder", description: "Emit new event at a specified time before a card is due.", version: "0.1.3", type: "source", dedupe: "unique", props: { pipedream: taskScheduler.props.pipedream, trello, db: "$.service.db", http: "$.interface.http", board: { propDefinition: [ trello, "board", ], }, timeBefore: { type: "string", label: "Time Before", description: "How far before the due time the event should trigger. For example, `5 minutes`, `10 minutes`, `1 hour`.", default: "5 minutes", options: constants.NOTIFICATION_TIMES, reloadProps: true, }, }, async additionalProps() { const props = {}; if (this.timeBefore) { props.timer = { type: "$.interface.timer", description: "Poll the API to schedule alerts for any newly created events", default: { intervalSeconds: ms(this.timeBefore) / 1000, }, }; } return props; }, hooks: { async deactivate() { const ids = this._getScheduledEventIds(); if (!ids?.length) { return; } for (const id of ids) { if (await this.deleteEvent({ body: { id, }, })) { console.log("Cancelled scheduled event"); } } this._setScheduledEventIds(); }, }, methods: { ...taskScheduler.methods, generateMeta({ id, name: summary, }, now) { return { id, summary, ts: now, }; }, _getScheduledEventIds() { return this.db.get("scheduledEventIds"); }, _setScheduledEventIds(ids) { this.db.set("scheduledEventIds", ids); }, _getScheduledCardIds() { return this.db.get("scheduledCardIds"); }, _setScheduledCardIds(ids) { this.db.set("scheduledCardIds", ids); }, _hasDeployed() { const result = this.db.get("hasDeployed"); this.db.set("hasDeployed", true); return result; }, emitEvent(card, now) { const meta = this.generateMeta(card, now); this.$emit(card, meta); }, }, async run(event) { const now = event.timestamp * 1000; if (!this._hasDeployed()) { await this.selfSubscribe(); } let scheduledEventIds = this._getScheduledEventIds() || []; if (event.$channel === this.selfChannel()) { const remainingScheduledEventIds = scheduledEventIds.filter((id) => id !== event["$id"]); this._setScheduledEventIds(remainingScheduledEventIds); this.emitEvent(event, now); return; } const scheduledCardIds = this._getScheduledCardIds() || {}; const cards = await this.trello.getCards({ boardId: this.board, }); for (const card of cards) { const dueDate = card.due ? new Date(card.due) : null; if (!dueDate || dueDate.getTime() < Date.now()) { delete scheduledCardIds[card.id]; continue; } const later = new Date(dueDate.getTime() - ms(this.timeBefore)); if (scheduledCardIds[card.id]) { if (card.due !== scheduledCardIds[card.id].dueDate) { await this.deleteEvent({ body: { id: scheduledCardIds[card.id].eventId, }, }); scheduledEventIds = scheduledEventIds .filter((id) => id !== scheduledCardIds[card.id].eventId); } else { continue; } } const scheduledEventId = this.emitScheduleEvent(card, later); scheduledEventIds.push(scheduledEventId); scheduledCardIds[card.id] = { eventId: scheduledEventId, dueDate: card.due, }; } this._setScheduledEventIds(scheduledEventIds); this._setScheduledCardIds(scheduledCardIds); }, sampleEmit, };