Skip to content

Instantly share code, notes, and snippets.

@uiur
Created April 18, 2019 00:24
Show Gist options
  • Save uiur/50ba5729cf8e5920e5fbb385392a6543 to your computer and use it in GitHub Desktop.
Save uiur/50ba5729cf8e5920e5fbb385392a6543 to your computer and use it in GitHub Desktop.
slack emoji -> github issue
const axios = require('axios')
const decode = require('decode-html')
const CHANNEL = '#dev'
const ISSUE_REPO = 'foo/bar'
exports.otochan = (req, res) => {
console.log('Received request:', req.body)
// slack challenge
if (req.body.challenge) {
res.send(req.body.challenge)
return
}
// slack event
if (req.body.event) {
handleSlack(req, res)
return
}
}
function handleSlack(req, res) {
const event = req.body.event
if (event.type === 'reaction_added') {
if (event.reaction === 'イシュー') {
handleReaction(event)
.then(() => {
res.send('ok')
})
.catch(err => {
console.error(err)
res.status(500).send(err.message)
})
return
}
}
res.send('ok: no matched handler')
}
async function handleReaction(event) {
const { channel, ts } = event.item
const { messages } = await getMessages(channel, ts, 10)
const message = messages[0]
const permalink = await getPermalink(channel, message.ts)
const repo = ISSUE_REPO
const title = decode(message.text)
const historyText = messages.reverse()
.filter(m => m.type === 'message')
.map(m => decode(m.text))
.join("\n")
const body = `${permalink}\n` + '```\n' + historyText + '\n```'
const issues = await getLatestIssues(repo)
const foundIssue = issues.find((issue) => {
return issue.title === title
})
if (foundIssue) {
return
}
const issue = await createIssue(repo, { title: title, body: body })
const slackMessage = `<@${event.user}> ${issue.html_url}`
await postMessage(channel, slackMessage)
}
function apiHeaders(token) {
return {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
}
async function getMessages (channel, ts, count = 1) {
const token = process.env.SLACK_USER_TOKEN
const res = await axios.get('https://slack.com/api/channels.history', {
params: {
channel: channel,
latest: ts,
count: count,
inclusive: true,
token: token
}
})
return res.data
}
async function postMessage (channel, text) {
const token = process.env.SLACK_TOKEN
await axios.post('https://slack.com/api/chat.postMessage', {
channel: channel,
text: text,
icon_emoji: ':chicken:'
}, {
headers: apiHeaders(token)
})
}
async function getPermalink (channel, ts) {
const res = await axios.get('https://slack.com/api/chat.getPermalink', {
params: {
channel: channel,
message_ts: ts,
token: process.env.SLACK_TOKEN
}
})
return res.data.permalink
}
function githubApiHeaders() {
return {
...apiHeaders(process.env.GITHUB_TOKEN),
'Accept': 'application/vnd.github.v3+json'
}
}
async function createIssue(repo, params) {
const res = await axios.post(`https://api.github.com/repos/${repo}/issues`, params, {
headers: githubApiHeaders()
})
if (res.status > 300) {
console.error(res.data)
throw new Error(res.data.message)
}
return res.data
}
async function getLatestIssues(repo) {
const res = await axios.get(`https://api.github.com/repos/${repo}/issues`, {
params: {
state: 'all'
},
headers: githubApiHeaders()
})
if (res.status > 300) {
console.error(res.data)
throw new Error(res.data.message)
}
return res.data
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment