Skip to content

Commit

Permalink
feat(github): support experimental event filter
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Sep 4, 2020
1 parent 3cc5662 commit 2610cd8
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 2 deletions.
86 changes: 86 additions & 0 deletions packages/plugin-github/src/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,92 @@
import { EventNames } from '@octokit/webhooks'
import { GetWebhookPayloadTypeFromEvent } from '@octokit/webhooks/dist-types/generated/get-webhook-payload-type-from-event'

export interface EventConfig {
commitComment?: boolean
fork?: boolean
issueComment?: boolean | {
created?: boolean
deleted?: boolean
edited?: boolean
}
issues?: boolean | {
assigned?: boolean
closed?: boolean
deleted?: boolean
demilestoned?: boolean
edited?: boolean
labeled?: boolean
locked?: boolean
milestoned?: boolean
opened?: boolean
pinned?: boolean
reopened?: boolean
transferred?: boolean
unassigned?: boolean
unlabeled?: boolean
unlocked?: boolean
unpinned?: boolean
}
pullRequest?: boolean | {
assigned?: boolean
closed?: boolean
edited?: boolean
labeled?: boolean
locked?: boolean
merged?: boolean
opened?: boolean
readyForReview?: boolean
reopened?: boolean
reviewRequestRemoved?: boolean
reviewRequested?: boolean
synchronize?: boolean
unassigned?: boolean
unlabeled?: boolean
unlocked?: boolean
}
pullRequestReview?: boolean | {
dismissed?: boolean
edited?: boolean
submitted?: boolean
}
pullRequestReviewComment?: boolean | {
created?: boolean
deleted?: boolean
edited?: boolean
}
push?: boolean
star?: boolean | {
created?: boolean
deleted?: boolean
}
}

export const defaultEvents: EventConfig = {
commitComment: true,
fork: true,
issueComment: {
created: true,
},
issues: {
closed: true,
opened: true,
},
pullRequest: {
closed: true,
opened: true,
},
pullRequestReview: {
submitted: true,
},
pullRequestReviewComment: {
created: true,
},
push: true,
star: {
created: true,
},
}

export interface ReplyPayloads {
link?: string
react?: string
Expand Down
22 changes: 20 additions & 2 deletions packages/plugin-github/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
/* eslint-disable quote-props */

import { Context, Session, User } from 'koishi-core'
import { CQCode, defineProperty, Logger, Time } from 'koishi-utils'
import { camelize, CQCode, defineProperty, Logger, Time } from 'koishi-utils'
import { Webhooks } from '@octokit/webhooks'
import { Agent } from 'https'
import { encode } from 'querystring'
import axios, { AxiosError } from 'axios'
import { addListeners, ReplyPayloads } from './events'
import { addListeners, defaultEvents, EventConfig, ReplyPayloads } from './events'

declare module 'koishi-core/dist/app' {
interface App {
Expand Down Expand Up @@ -53,6 +53,7 @@ export interface Config {
replyTimeout?: number
requestTimeout?: number
repos?: Record<string, number[]>
events?: EventConfig
}

const defaultOptions: Config = {
Expand All @@ -62,6 +63,7 @@ const defaultOptions: Config = {
authorize: '/github/authorize',
replyTimeout: Time.hour,
repos: {},
events: {},
}

const logger = new Logger('github')
Expand Down Expand Up @@ -220,18 +222,34 @@ export function apply(ctx: Context, config: Config = {}) {
})

addListeners((event, handler) => {
const base = camelize(event.split('.', 1)[0]) as keyof EventConfig
webhooks.on(event, async (callback) => {
const { repository } = callback.payload

// step 1: filter repository
const groupIds = config.repos[repository.full_name]
if (!groupIds) return

// step 2: filter event
const baseConfig = config.events[base] || {}
if (baseConfig === false) return
const action = camelize(callback.payload.action)
if (action && baseConfig !== true) {
const actionConfig = baseConfig[action]
if (actionConfig === false) return
if (actionConfig !== true && defaultEvents[base] !== true && !(defaultEvents[base] || {})[action]) return
}

// step 3: handle event
const result = handler(callback.payload)
if (!result) return

// step 4: broadcast message
const [message, replies] = result
const messageIds = await ctx.broadcast(groupIds, message)
if (!replies) return

// step 5: save message ids for interactions
for (const id of messageIds) {
interactions[id] = replies
}
Expand Down

0 comments on commit 2610cd8

Please sign in to comment.