mirror of
https://github.com/status-im/status-github-bot.git
synced 2025-01-27 13:35:02 +00:00
Simplify Slack-GitHub cache
This commit is contained in:
parent
4513976cb9
commit
a9eb8d117a
@ -18,20 +18,20 @@ const slackHelper = require('../lib/slack')
|
||||
|
||||
const botName = 'bounty-awaiting-approval-slack-ping'
|
||||
|
||||
module.exports = (robot, getSlackMentionFromGitHubId) => {
|
||||
registerForNewBounties(robot, getSlackMentionFromGitHubId)
|
||||
module.exports = (robot) => {
|
||||
registerForNewBounties(robot)
|
||||
}
|
||||
|
||||
function registerForNewBounties (robot, getSlackMentionFromGitHubId) {
|
||||
function registerForNewBounties (robot) {
|
||||
robot.on('issues.labeled', async context => {
|
||||
// Make sure we don't listen to our own messages
|
||||
if (context.isBot) return null
|
||||
|
||||
await notifyCollaborators(context, robot, getSlackMentionFromGitHubId)
|
||||
await notifyCollaborators(context, robot)
|
||||
})
|
||||
}
|
||||
|
||||
async function notifyCollaborators (context, robot, getSlackMentionFromGitHubId) {
|
||||
async function notifyCollaborators (context, robot) {
|
||||
const { github, payload } = context
|
||||
const ownerName = payload.repository.owner.login
|
||||
const repoName = payload.repository.name
|
||||
@ -57,12 +57,12 @@ async function notifyCollaborators (context, robot, getSlackMentionFromGitHubId)
|
||||
|
||||
robot.log(`${botName} - issue #${payload.issue.number} on ${ownerName}/${repoName} was labeled as a bounty awaiting approval. Pinging slack...`)
|
||||
|
||||
const slackCollaborators = await getSlackCollaborators(ownerName, repoName, github, robot, gitHubTeamConfig, getSlackMentionFromGitHubId)
|
||||
const slackCollaborators = await getSlackCollaborators(ownerName, repoName, github, robot, gitHubTeamConfig)
|
||||
|
||||
// Mention the project board owner as well, if configured
|
||||
const bountyProjectBoardOwner = bountyProjectBoardConfig['owner']
|
||||
if (bountyProjectBoardOwner) {
|
||||
const slackUserMention = getSlackMentionFromGitHubId(bountyProjectBoardOwner)
|
||||
const slackUserMention = robot.gitHubIdMapper.getSlackMentionFromGitHubId(bountyProjectBoardOwner)
|
||||
if (slackUserMention) {
|
||||
slackCollaborators.push(slackUserMention)
|
||||
}
|
||||
@ -82,7 +82,7 @@ function randomInt (low, high) {
|
||||
}
|
||||
|
||||
// Get the Slack IDs of the collaborators of this repo.
|
||||
async function getSlackCollaborators (ownerName, repoName, github, robot, gitHubTeamConfig, getSlackMentionFromGitHubId) {
|
||||
async function getSlackCollaborators (ownerName, repoName, github, robot, gitHubTeamConfig) {
|
||||
const teamSlug = gitHubTeamConfig['slug']
|
||||
if (!teamSlug) {
|
||||
robot.log.debug(`${botName} - GitHub team slug not configured in repo ${ownerName}/${repoName}, ignoring`)
|
||||
@ -100,12 +100,21 @@ async function getSlackCollaborators (ownerName, repoName, github, robot, gitHub
|
||||
const teamMembers = await github.paginate(github.orgs.getTeamMembers({id: team.id, per_page: 100}), res => res.data)
|
||||
|
||||
// Create an array of Slack usernames from GitHub usernames
|
||||
const slackUsers = teamMembers.map(u => u.login).map(getSlackMentionFromGitHubId).filter(id => id)
|
||||
const gitHubUsers = teamMembers.map(u => u.login)
|
||||
const slackUsers = new HashSet()
|
||||
for (const gitHubUser of gitHubUsers) {
|
||||
const id = await robot.gitHubIdMapper.getSlackMentionFromGitHubId(gitHubUser)
|
||||
if (id) {
|
||||
slackUsers.add(id)
|
||||
}
|
||||
}
|
||||
|
||||
// Select 2 random Slack team members
|
||||
const randomTeamMemberLimit = 2
|
||||
const selectedSlackUsers = new HashSet()
|
||||
|
||||
while (selectedSlackUsers.length < randomTeamMemberLimit || selectedSlackUsers.length < slackUsers.length) {
|
||||
const slackUser = slackUsers[randomInt(0, slackUsers.length)]
|
||||
while (selectedSlackUsers.size() < randomTeamMemberLimit || selectedSlackUsers.size() < slackUsers.size()) {
|
||||
const slackUser = slackUsers[randomInt(0, slackUsers.size())]
|
||||
selectedSlackUsers.add(slackUser)
|
||||
}
|
||||
|
||||
|
@ -11,24 +11,24 @@ const slackHelper = require('../lib/slack')
|
||||
|
||||
const botName = 'notify-reviewers-via-slack'
|
||||
|
||||
module.exports = (robot, getSlackIdFromGitHubId) => {
|
||||
module.exports = (robot) => {
|
||||
robot.log(`${botName} - Starting...`)
|
||||
registerForNewReviewRequests(robot, getSlackIdFromGitHubId)
|
||||
registerForNewReviewRequests(robot)
|
||||
}
|
||||
|
||||
function registerForNewReviewRequests (robot, getSlackIdFromGitHubId) {
|
||||
function registerForNewReviewRequests (robot) {
|
||||
robot.on('pull_request.review_requested', async context => {
|
||||
// Make sure we don't listen to our own messages
|
||||
if (context.isBot) return null
|
||||
|
||||
await notifyReviewer(context, robot, getSlackIdFromGitHubId)
|
||||
await notifyReviewer(context, robot)
|
||||
})
|
||||
}
|
||||
|
||||
async function notifyReviewer (context, robot, getSlackIdFromGitHubId) {
|
||||
async function notifyReviewer (context, robot) {
|
||||
const { payload } = context
|
||||
const reviewer = payload.requested_reviewer
|
||||
const userID = getSlackIdFromGitHubId(reviewer.login)
|
||||
const userID = await robot.gitHubIdMapper.getSlackIdFromGitHubId(reviewer.login)
|
||||
|
||||
if (!userID) {
|
||||
robot.log.warn('Could not find Slack ID for GitHub user', reviewer.login)
|
||||
|
28
index.js
28
index.js
@ -1,6 +1,3 @@
|
||||
const MemCache = require('mem-cache')
|
||||
const slackGitHubCache = new MemCache({ timeoutDisabled: true })
|
||||
const SlackGitHubCacheBuilder = require('./lib/retrieve-slack-github-users')
|
||||
const Slack = require('./lib/slack')
|
||||
|
||||
module.exports = async (robot) => {
|
||||
@ -8,7 +5,7 @@ module.exports = async (robot) => {
|
||||
|
||||
Slack(robot, slack => {})
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
await new Promise(resolve => {
|
||||
robot.on('slack.connected', event => {
|
||||
robot.log.info(`Connected to Slack`)
|
||||
|
||||
@ -19,20 +16,15 @@ module.exports = async (robot) => {
|
||||
})
|
||||
})
|
||||
|
||||
const slackCachePromise = SlackGitHubCacheBuilder.build(robot, slackGitHubCache)
|
||||
robot['gitHubIdMapper'] = require('./lib/github-id-mapper')(robot)
|
||||
|
||||
require('./bot_scripts/assign-new-pr-to-review')(robot)
|
||||
require('./bot_scripts/assign-approved-pr-to-test')(robot)
|
||||
require('./bot_scripts/assign-to-bounty-awaiting-for-approval')(robot)
|
||||
require('./bot_scripts/greet-new-contributor')(robot)
|
||||
require('./bot_scripts/trigger-automation-test-build')(robot)
|
||||
|
||||
await slackCachePromise
|
||||
robot.log.info('Slack user ID cache populated, loading remainder of scripts')
|
||||
|
||||
// Add scripts which require using the Slack/GitHub cache after this comment
|
||||
require('./bot_scripts/bounty-awaiting-approval-slack-ping')(robot, getSlackMentionFromGitHubId)
|
||||
require('./bot_scripts/notify-reviewers-via-slack')(robot, getSlackIdFromGitHubId)
|
||||
require('./bot_scripts/bounty-awaiting-approval-slack-ping')(robot)
|
||||
require('./bot_scripts/notify-reviewers-via-slack')(robot)
|
||||
|
||||
// For more information on building apps:
|
||||
// https://probot.github.io/docs/
|
||||
@ -40,15 +32,3 @@ module.exports = async (robot) => {
|
||||
// To get your app running against GitHub, see:
|
||||
// https://probot.github.io/docs/development/
|
||||
}
|
||||
|
||||
function getSlackMentionFromGitHubId (gitHubId) {
|
||||
const id = SlackGitHubCacheBuilder.getSlackIdFromGitHubId(gitHubId, slackGitHubCache)
|
||||
if (!id) {
|
||||
return null
|
||||
}
|
||||
return `<@${id}>`
|
||||
}
|
||||
|
||||
function getSlackIdFromGitHubId (gitHubId) {
|
||||
return SlackGitHubCacheBuilder.getSlackIdFromGitHubId(gitHubId, slackGitHubCache)
|
||||
}
|
||||
|
@ -1,33 +1,52 @@
|
||||
// Description:
|
||||
// Configuration-related functionality
|
||||
// GitHub ID mapping to other connected systems (e.g. Slack)
|
||||
//
|
||||
// Dependencies:
|
||||
// "mem-cache": "0.0.5"
|
||||
// mem-cache: "0.0.5"
|
||||
// @slack/client: "^3.16.0"
|
||||
//
|
||||
// Author:
|
||||
// PombeirP
|
||||
|
||||
const MemCache = require('mem-cache')
|
||||
const { WebClient } = require('@slack/client')
|
||||
|
||||
const token = process.env.SLACK_USER_TOKEN || ''
|
||||
|
||||
module.exports.build = async (robot, cache) => {
|
||||
const web = new WebClient(token)
|
||||
await populateCache(robot, web, cache)
|
||||
module.exports = (robot) => new GitHubSlackIdMapper(robot)
|
||||
|
||||
class GitHubSlackIdMapper {
|
||||
constructor (robot) {
|
||||
this.robot = robot
|
||||
this.cache = new MemCache({ timeoutDisabled: true })
|
||||
this.buildPromise = new Promise((resolve, reject) => internalBuild(this.robot, this.cache).then(resolve).catch(reject))
|
||||
}
|
||||
|
||||
module.exports.getGitHubIdFromSlackId = (slackUserId, cache) => {
|
||||
async getGitHubIdFromSlackId (slackUserId, cache) {
|
||||
await this.buildPromise
|
||||
return cache.get(getSlackId2GitHubIdCacheKeyName(slackUserId))
|
||||
}
|
||||
|
||||
module.exports.getSlackIdFromGitHubId = (gitHubId, cache) => {
|
||||
return cache.get(getGitHub2SlackIdCacheKeyName(gitHubId))
|
||||
async getSlackIdFromGitHubId (gitHubId) {
|
||||
await this.buildPromise
|
||||
return this.cache.get(getGitHub2SlackIdCacheKeyName(gitHubId))
|
||||
}
|
||||
|
||||
async function populateCache (robot, web, cache) {
|
||||
async getSlackMentionFromGitHubId (gitHubId) {
|
||||
const id = await this.getSlackIdFromGitHubId(gitHubId)
|
||||
if (!id) {
|
||||
return null
|
||||
}
|
||||
return `<@${id}>`
|
||||
}
|
||||
}
|
||||
|
||||
async function internalBuild (robot, cache) {
|
||||
robot.log.info('Populating Slack user ID cache...')
|
||||
|
||||
try {
|
||||
const usersList = await web.users.list() // TODO: This call should be paginated to avoid hitting limits (memory, API): https://api.slack.com/docs/pagination#cursors
|
||||
const slackWeb = new WebClient(token) // We need to use a different token because users.profile API is not available to bot users
|
||||
const usersList = await slackWeb.users.list() // TODO: This call should be paginated to avoid hitting limits (memory, API): https://api.slack.com/docs/pagination#cursors
|
||||
const activeUsersList = usersList.members.filter(u => !u.deleted && !u.is_bot && u.id !== 'USLACKBOT')
|
||||
|
||||
let gitHubFieldId = null
|
||||
@ -41,7 +60,7 @@ async function populateCache (robot, web, cache) {
|
||||
|
||||
try {
|
||||
++profileFetchBatchCount
|
||||
const { profile } = await web.users.profile.get({ user: user.id, include_labels: !gitHubFieldId })
|
||||
const { profile } = await slackWeb.users.profile.get({ user: user.id, include_labels: !gitHubFieldId })
|
||||
const username = profile.display_name_normalized || profile.real_name_normalized
|
||||
|
||||
if (!gitHubFieldId) {
|
0
lib/slack-github-id-map.js
Normal file
0
lib/slack-github-id-map.js
Normal file
Loading…
x
Reference in New Issue
Block a user