2018-01-22 13:48:57 +00:00
// Description:
// Script that listens to new GitHub pull requests
// and greets the user if it is their first PR on the repo
//
// Dependencies:
// github: "^13.1.0"
2018-01-23 18:38:25 +00:00
// probot-config: "^0.1.0"
2018-01-22 13:48:57 +00:00
//
// Author:
// PombeirP
2018-02-08 12:09:59 +00:00
const getConfig = require ( 'probot-config' )
2018-01-22 13:48:57 +00:00
2018-02-14 11:37:49 +00:00
const slackHelper = require ( '../lib/slack' )
2018-02-08 12:09:59 +00:00
const defaultConfig = require ( '../lib/config' )
2018-02-13 14:51:00 +00:00
const botName = 'greet-new-contributor'
2018-01-22 13:48:57 +00:00
2018-01-28 08:24:30 +00:00
module . exports = ( robot ) => {
2018-01-22 13:48:57 +00:00
robot . on ( 'pull_request.opened' , async context => {
// Make sure we don't listen to our own messages
2018-01-23 14:27:25 +00:00
if ( context . isBot ) { return }
2018-01-28 08:24:30 +00:00
2018-01-22 13:48:57 +00:00
// A new PR was opened
2018-01-23 14:27:25 +00:00
await greetNewContributor ( context , robot )
} )
}
2018-01-22 13:48:57 +00:00
2018-02-14 14:06:20 +00:00
function executeTemplate ( templateString , templateVars ) {
let s = templateString
for ( const templateVar in templateVars ) {
if ( templateVars . hasOwnProperty ( templateVar ) ) {
const value = templateVars [ templateVar ]
s = s . replace ( ` { ${ templateVar } } ` , value )
}
}
return s
}
2018-01-28 08:24:30 +00:00
async function greetNewContributor ( context , robot ) {
2018-02-07 16:04:59 +00:00
const { github , payload } = context
2018-02-08 12:09:59 +00:00
const config = await getConfig ( context , 'github-bot.yml' , defaultConfig ( robot , '.github/github-bot.yml' ) )
2018-02-16 20:35:49 +00:00
const repoInfo = { owner : payload . repository . owner . login , repo : payload . repository . name }
const prInfo = { ... repoInfo , number : payload . pull _request . number }
2018-01-28 08:24:30 +00:00
2018-02-08 12:09:59 +00:00
const welcomeBotConfig = config ? config [ 'welcome-bot' ] : null
2018-01-28 08:24:30 +00:00
if ( ! welcomeBotConfig ) {
return
2018-01-23 14:30:24 +00:00
}
2018-01-28 08:24:30 +00:00
2018-02-16 20:35:49 +00:00
robot . log ( ` ${ botName } - Handling Pull Request # ${ prInfo . number } on repo ${ repoInfo . owner } / ${ repoInfo . repo } ` )
2018-01-28 08:24:30 +00:00
2018-01-22 13:48:57 +00:00
try {
2018-02-05 16:12:16 +00:00
const ghissuesPayload = await github . issues . getForRepo ( {
2018-02-16 20:35:49 +00:00
... repoInfo ,
2018-01-22 13:48:57 +00:00
state : 'all' ,
creator : payload . pull _request . user . login
} )
2018-01-28 08:24:30 +00:00
2018-02-05 16:12:16 +00:00
const userPullRequests = ghissuesPayload . data . filter ( issue => issue . pull _request )
2018-01-22 13:48:57 +00:00
if ( userPullRequests . length === 1 ) {
try {
2018-02-16 20:35:49 +00:00
const welcomeMessage = executeTemplate ( welcomeBotConfig [ 'message-template' ] , { user : payload . pull _request . user . login , 'pr-number' : prInfo . number , 'repo-name' : repoInfo . repo } )
2018-02-14 14:06:20 +00:00
2018-01-28 08:24:30 +00:00
if ( process . env . DRY _RUN ) {
2018-02-16 20:35:49 +00:00
robot . log ( ` ${ botName } - Would have created comment in GHI ` , prInfo , welcomeMessage )
2018-01-28 08:24:30 +00:00
} else {
2018-01-23 18:38:25 +00:00
await github . issues . createComment ( {
2018-02-16 20:35:49 +00:00
... prInfo ,
2018-01-23 18:38:25 +00:00
body : welcomeMessage
} )
}
2018-01-28 08:24:30 +00:00
2018-01-22 13:48:57 +00:00
// Send message to Slack
2018-02-16 20:35:49 +00:00
slackHelper . sendMessage ( robot , config . slack . notification . room , ` Greeted ${ payload . pull _request . user . login } on his first PR in the ${ repoInfo . repo } repo \n ${ payload . pull _request . html _url } ` )
2018-04-10 16:50:17 +00:00
const slackRecipients = welcomeBotConfig [ 'slack-recipients' ]
if ( slackRecipients ) {
2018-04-23 16:33:52 +00:00
for ( const slackUsername of slackRecipients ) {
await notifySlackRecipient ( robot , slackUsername , payload , repoInfo )
2018-04-10 16:50:17 +00:00
}
}
2018-01-22 13:48:57 +00:00
} catch ( err ) {
if ( err . code !== 404 ) {
2018-02-16 20:35:49 +00:00
robot . log . error ( ` ${ botName } - Couldn't create comment on PR: ${ err } ` , repoInfo )
2018-01-22 13:48:57 +00:00
}
}
} else {
2018-02-16 20:35:49 +00:00
robot . log . debug ( ` ${ botName } - This is not the user's first PR on the repo, ignoring ` , repoInfo , payload . pull _request . user . login )
2018-01-22 13:48:57 +00:00
}
} catch ( err ) {
2018-02-16 20:35:49 +00:00
robot . log . error ( ` ${ botName } - Couldn't fetch the user's github issues for repo: ${ err } ` , repoInfo )
2018-01-22 13:48:57 +00:00
}
2018-01-28 08:24:30 +00:00
}
2018-04-10 16:50:17 +00:00
2018-04-23 16:33:52 +00:00
async function notifySlackRecipient ( robot , slackUsername , payload , repoInfo ) {
2018-04-10 16:50:17 +00:00
try {
2018-04-23 16:33:52 +00:00
const slackProfileCache = robot [ 'slackProfileCache' ]
const userID = await slackProfileCache . getSlackIdFromSlackUsername ( slackUsername )
2018-04-10 16:50:17 +00:00
const resp = await robot . slackWeb . im . open ( userID )
const dmChannelID = resp . channel . id
const msg = ` Greeted ${ payload . pull _request . user . login } on his first PR in the ${ repoInfo . repo } repo \n ${ payload . pull _request . html _url } `
robot . log . info ( ` ${ botName } - Opened DM Channel ${ dmChannelID } ` )
2018-04-23 16:33:52 +00:00
robot . log . info ( ` Notifying ${ slackUsername } about user's first PM in ${ payload . pull _request . url } ` )
2018-04-10 16:50:17 +00:00
robot . slackWeb . chat . postMessage ( dmChannelID , msg , { unfurl _links : true , as _user : slackHelper . BotUserName } )
} catch ( error ) {
2018-04-23 16:33:52 +00:00
robot . log . warn ( ` Could not open DM channel to ${ slackUsername } for new user's first PM notification ` , error )
2018-04-10 16:50:17 +00:00
}
}