From d2e4f0d1432ccde276e967cfa03a329884e21295 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Thu, 20 Oct 2022 22:50:08 +0200 Subject: [PATCH] feat(github): add new watcher trigger --- .../github/triggers/new-watchers/index.ts | 47 ++++++++++++ .../triggers/new-watchers/new-watchers.ts | 75 +++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 packages/backend/src/apps/github/triggers/new-watchers/index.ts create mode 100644 packages/backend/src/apps/github/triggers/new-watchers/new-watchers.ts diff --git a/packages/backend/src/apps/github/triggers/new-watchers/index.ts b/packages/backend/src/apps/github/triggers/new-watchers/index.ts new file mode 100644 index 00000000..cffd8f2f --- /dev/null +++ b/packages/backend/src/apps/github/triggers/new-watchers/index.ts @@ -0,0 +1,47 @@ +import defineTrigger from '../../../../helpers/define-trigger'; +import newWatchers from './new-watchers'; + +export default defineTrigger({ + name: 'New watchers', + key: 'newWatchers', + pollInterval: 15, + dedupeStrategy: 'unique', + description: 'Triggers when a user watches a repository', + substeps: [ + { + key: 'chooseConnection', + name: 'Choose connection' + }, + { + key: 'chooseTrigger', + name: 'Set up a trigger', + arguments: [ + { + label: 'Repo', + key: 'repo', + type: 'dropdown', + required: true, + variables: false, + source: { + type: 'query', + name: 'getData', + arguments: [ + { + name: 'key', + value: 'listRepos' + } + ] + } + }, + ] + }, + { + key: 'testStep', + name: 'Test trigger' + } + ], + + async run($) { + return await newWatchers($); + }, +}); diff --git a/packages/backend/src/apps/github/triggers/new-watchers/new-watchers.ts b/packages/backend/src/apps/github/triggers/new-watchers/new-watchers.ts new file mode 100644 index 00000000..255ab493 --- /dev/null +++ b/packages/backend/src/apps/github/triggers/new-watchers/new-watchers.ts @@ -0,0 +1,75 @@ +import { + IGlobalVariable, + ITriggerOutput, +} from '@automatisch/types'; +import getRepoOwnerAndRepo from '../../common/get-repo-owner-and-repo'; +import parseLinkHeader from '../../../../helpers/parse-header-link'; + +const fetchWatchers = async ($: IGlobalVariable) => { + const repoParameter = $.step.parameters.repo as string; + + if (!repoParameter) throw new Error('A repo must be set!'); + + const { repoOwner, repo } = getRepoOwnerAndRepo(repoParameter); + + const firstPagePathname = `/repos/${repoOwner}/${repo}/subscribers`; + const requestConfig = { + params: { + per_page: 100 + }, + } + + const firstPageResponse = await $.http.get(firstPagePathname, requestConfig); + const firstPageLinks = parseLinkHeader(firstPageResponse.headers.link); + + // in case there is only single page to fetch + let pathname = firstPageLinks.last?.uri || firstPagePathname; + + const watchers: ITriggerOutput = { + data: [], + }; + + do { + const response = await $.http.get(pathname, requestConfig); + const links = parseLinkHeader(response.headers.link); + pathname = links.prev?.uri; + + if (response.integrationError) { + watchers.error = response.integrationError; + return watchers; + } + + if (response.data.length) { + // to iterate reverse-chronologically + response.data.reverse(); + + for (const watcher of response.data) { + const watcherId = watcher.id.toString(); + + if ($.flow.isAlreadyProcessed(watcherId) && !$.execution.testRun) return watchers; + + const dataItem = { + raw: watcher, + meta: { + internalId: watcherId, + }, + }; + + watchers.data.push(dataItem); + } + } + } while (pathname && !$.execution.testRun === false); + + return watchers; +} + +const newWatchers = async ($: IGlobalVariable) => { + const watchers = await fetchWatchers($); + + // to process chronologically + watchers.data.reverse(); + + return watchers; +}; + +export default newWatchers;