diff --git a/README.md b/README.md index 107d022..471bc69 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,39 @@ -# rocketchat-gitea-hook -Gitea integrate notifications via a incoming webhook in Rocket.Chat + +# About +[Rocket.Chat](https://rocket.chat/) integrate notifications via an [Incoming Webhook](https://docs.rocket.chat/guides/administrator-guides/integrations) in [Gitea](https://gitea.io/) + + +# Instructions +## Rocket.Chat +1. Login Rocket.Chat with Administrator + +2. Go to Adminisration -> Integrations -> Create a new Incoming webhook +3. Set "**Enabled**" option to **True** +4. Select **Channel/User** that you want to post notification +5. Select an **Account** to post message. In Rocket.Chat can set account role be a BOT +6. Copy/Paste [gitea-rocketchat.hooks.js](https://raw.githubusercontent.com/austinsuyoyo/rocketchat-gitea-hook/master/gitea-rocketchat.hooks.js) to Scripts Block in Rocket.Chat. +7. Set "**Script Enabled**" Option to **True** +7. Save the integration first, then you can copy **Webhook URL** for Gitea trigger. + +## Gitea +* System Webhook + 1. Go to **Site Administration** -> **System Webhooks** + 2. Create New Webook -> Select **Gitea** webhook + 3. Past **Webhook URL** to Target URL + 4. Keep **HTTP Method** as POST + 5. Keep **POST Content Type** as application/json + 6. Let **Secret** be empty. + 7. Select what type of notification you want to post (This sciprt will support all message) + 8. Select Active to Enable notification webhook +* Repository Webhook + 1. Go to **any repository** -> **Settings** -> **Webhooks** + 2. Create New Webook -> Select **Gitea** webhook + 3. Past **Webhook URL** to Target URL + 4. Keep **HTTP Method** as POST + 5. Keep **POST Content Type** as application/json + 6. Let **Secret** be empty. + 7. Select what type of notification you want to post (This sciprt will support all message) + 8. Select Active to Enable notification webhook + +# Demo +![rocketchat-gitea-hook](https://raw.githubusercontent.com/Austinsuyoyo/rocketchat-gitea-hook/master/img/push.png) diff --git a/gitea-rocketchat.hooks.js b/gitea-rocketchat.hooks.js new file mode 100644 index 0000000..b5396e3 --- /dev/null +++ b/gitea-rocketchat.hooks.js @@ -0,0 +1,403 @@ +String.prototype.capitalizeFirstLetter = function () { + return this.charAt(0).toUpperCase() + this.slice(1); +} + +const getAssigneesField = (assignees) => { + let assigneesArray = []; + assignees.forEach(function (assignee) { + assigneesArray.push(assignee.login); + }); + assigneesArray = assigneesArray.join(', '); + return { + title: 'Assignees', + value: assigneesArray, + short: assigneesArray.length <= 40 + }; +}; +const getLabelsField = (labels) => { + let labelsArray = []; + labels.forEach(function (label) { + labelsArray.push(label.name); + }); + labelsArray = labelsArray.join(', '); + return { + title: 'Labels', + value: labelsArray, + short: labelsArray.length <= 40 + }; +}; + +const giteaEvents = { + + /* Create branch or tag */ + create(request) { + const user = request.content.sender; + const repo = request.content.repository; + const type = request.content.ref_type; + const ref = request.content.ref; + + if (type == 'branch') { + var text = 'Created branch **[' + ref + '](' + repo.html_url + '/src/branch/' + ref + ')** at [' + repo.full_name + '](' + repo.html_url + ')'; + } else if (type == 'tag') { + var text = 'Created tags **[' + ref + '](' + repo.html_url + '/releases/tag/' + ref + ')** at [' + repo.full_name + '](' + repo.html_url + ')'; + } + + return { + content: { + icon_url: user.avatar_url, + alias: user.login, + text: text + } + }; + }, + /* Delete Branch or tag */ + delete(request) { + const user = request.content.sender; + const repo = request.content.repository; + const type = request.content.ref_type; + const ref = request.content.ref; + if (type == 'branch') { + var text = 'Deleted branch [' + ref + '](' + repo.html_url + '/src/branch/' + ref + ') at [' + repo.full_name + '](' + repo.html_url + ')'; + } else if (type == 'tag') { + var text = 'Deleted tags [' + ref + '](' + repo.html_url + '/releases/tag/' + ref + ') at [' + repo.full_name + '](' + repo.html_url + ')'; + } + + return { + content: { + icon_url: user.avatar_url, + alias: user.login, + text: text + } + }; + }, + + /* Someone forked repository */ + fork(request) { + const user = request.content.sender; + const repo = request.content.repository; + const forkee = request.content.forkee; + const text = "Forked from **[" + forkee.full_name + '](' + forkee.html_url + ')** to **[' + repo.full_name + '](' + repo.html_url + ')**'; + return { + content: { + icon_url: user.avatar_url, + alias: user.login, + text: text + } + }; + }, + + /* Push to repository */ + push(request) { + const commits = request.content.commits; + const user = request.content.sender; + const repo = request.content.repository; + const branch = request.content.ref.split('/').pop(); + + if (commits.length > 1) { + var title = "Show all commits"; + } else { + var title = "" + } + const attachment = { + collapsed: true, + title: title, + fields: [] + }; + + + for (var i = 0; i < commits.length; i++) { + var commit = commits[i]; + var shortID = commit.id.substring(0, 7); + output = '[#' + shortID + '](' + commit.url + '): \n' + commit.message + attachment.fields.push({ + value: output, + }); + } + + var text = 'Pushed to **[' + branch + '](' + repo.html_url + '/src/branch/' + branch + ")** at [" + repo.full_name + "](" + repo.html_url + "):" + + "\n\n"; + + + return { + content: { + icon_url: user.avatar_url, + alias: user.login, + text: text, + attachments: [attachment] + } + }; + }, + /* New/Modified issues */ + issues(request) { + const user = request.content.sender; + const repo = request.content.repository; + const is = request.content.issue; + const action = request.content.action; + + if (action == "opened" || action == "reopened" || action == "edited") { + var body = is.body; + } else if (action == "label_updated" || action == "label_cleared") { + var body = "Current labels: " + getLabelsField(is.labels).value; + } else if (action == "assigned" || action == "unassigned") { + if (is.assignee) { + var body = "Current assignee: " + getAssigneesField(is.assignees).value; + } else { + var body = "There is no assignee"; + } + } else if (action == "closed") { + var body = ""; + } else if (action == "milestoned" || action == "demilestoned") { + var body = "Milestone: [" + is.milestone.title + "](" + repo.html_url + "/milestone/" + is.milestone.id + ")"; + } else { + return { + error: { + success: false, + message: 'Unsupported issue action' + } + }; + } + var text = + action.capitalizeFirstLetter() + ' **[issue ​#' + is.number + + ' - ' + is.title + '](' + + is.html_url + ')** ' + 'at [' + repo.full_name + '](' + repo.html_url + ')\n\n'; + return { + content: { + icon_url: user.avatar_url, + alias: user.login, + text: text, + attachments: [{ + text: body + } + ] + } + }; + }, + + /* Comment on existing issues or pull request*/ + issue_comment(request) { + const user = request.content.comment.user; + const repo = request.content.repository; + const action = request.content.action; + + if (action == "created") { + // Do nothing + } else if (action == "edited") { + // Do nothing + } else if (action == "deleted") { + // Do nothing + } else { + return { + error: { + success: false, + message: 'Unsupported issue_comment action' + } + }; + } + + if (request.content.comment.pull_request_url) { + var type = "pull request"; + } else if (request.content.comment.issue_url) { + + var type = "issue"; + } else { + return { + error: { + success: false, + message: 'Unsupported issue_comment action' + } + }; + } + + const text = + action.capitalizeFirstLetter() + ' comment on **[' + type + ' ​#' + request.content.issue.number + + ' - ' + request.content.issue.title + '](' + + request.content.comment.html_url + ')**' + ' at [' + repo.full_name + '](' + repo.html_url + ')\n\n'; + + + return { + content: { + icon_url: user.avatar_url, + alias: user.login, + text: text, + attachments: [ + { + text: request.content.comment.body + } + ] + } + }; + }, + + /* New/Created pull request*/ + pull_request(request) { + const user = request.content.sender; + const repo = request.content.repository; + const pr = request.content.pull_request + const action = request.content.action; + + if (action == "opened" || action == "reopened" || action == "edited" || action == "synchronize") { + var body = pr.body; + } else if (action == "label_updated" || action == "label_cleared") { + var body = "Current labels: " + getLabelsField(pr.labels).value; + } else if (action == "assigned" || action == "unassigned") { + if (pr.assignee) { + var body = "Current assignee: " + getAssigneesField(pr.assignees).value; + } else { + var body = "There is no assignee"; + } + } else if (action == "closed") { + if (pr.merged) { + var body = "Merged by: " + pr.merged_by.login; + } + } else if (action == "milestoned" || action == "demilestoned") { + var body = "Milestone: [" + pr.milestone.title + "](" + repo.html_url + "/milestone/" + pr.milestone.id + ")"; + } else { + return { + error: { + success: false, + message: 'Unsupported pull request action' + } + }; + } + const text = + action.capitalizeFirstLetter() + ' **[pull request ​#' + pr.number + + ' - ' + pr.title + '](' + + pr.html_url + ')**' + ' at [' + repo.full_name + '](' + repo.html_url + ')\n\n'; + + return { + content: { + icon_url: user.avatar_url, + alias: user.login, + text: text, + attachments: [ + { + text: body + } + ] + } + }; + }, + + /* Someone approved pull request */ + pull_request_approved(request) { + const user = request.content.sender; + const repo = request.content.repository; + const pr = request.content.pull_request + + var text = "Approved" + ' **[pull request ​#' + pr.number + + ' - ' + pr.title + '](' + + pr.html_url + ')**' + ' at [' + repo.full_name + '](' + repo.html_url + ')\n\n'; + + return { + content: { + icon_url: user.avatar_url, + alias: user.login, + text: text, + attachments: [ + { + text: request.content.review.content + } + ] + } + }; + }, + /* Someone rejected pull request */ + pull_request_rejected(request) { + const user = request.content.sender + const repo = request.content.repository;; + const pr = request.content.pull_request + + var text = "Suggested changes for" + ' **[pull request ​#' + pr.number + + ' - ' + pr.title + '](' + + pr.html_url + ')**' + ' at [' + repo.full_name + '](' + repo.html_url + ')\n\n'; + + return { + content: { + icon_url: user.avatar_url, + alias: user.login, + text: text, + attachments: [ + { + text: request.content.review.content + } + ] + } + }; + }, + + /* Deleted/Created Repository */ + repository(request) { + const user = request.content.sender; + const repo = request.content.repository; + const action = request.content.action; + + if (request.content.action == "deleted") { + // Do nothing + } else if (request.content.action == "created") { + // Do nothing + } else { + return { + error: { + success: false, + message: 'Unsupported issue action' + } + }; + } + + const text = action.capitalizeFirstLetter() + ' repository **[' + repo.full_name + '](' + repo.html_url + ')**'; + + return { + content: { + icon_url: user.avatar_url, + alias: user.login, + text: text + } + }; + }, + + /* Published/Updated/Deleted release */ + release(request) { + const user = request.content.sender; + const repo = request.content.repository; + const release = request.content.release; + if (request.content.action == 'published') { + var text = 'Release published "**[' + release.name + '](' + release.html_url + ')** at [' + repo.full_name + '](' + repo.html_url + ')'; + } else if (request.content.action == 'updated') { + var text = 'Release updated "**[' + release.name + '](' + release.html_url + ')** at [' + repo.full_name + '](' + repo.html_url + ')'; + } else if (request.content.action == 'deleted') { + var text = 'Release deleted "**[' + release.name + '](' + release.html_url + ')** at [' + repo.full_name + '](' + repo.html_url + ')'; + } else { + return { + error: { + success: false, + message: 'Unsupported release action' + } + }; + } + + return { + content: { + icon_url: user.avatar_url, + alias: user.login, + text: text + } + }; + }, +}; + +class Script { + process_incoming_request({ request }) { + + const header = request.headers['x-gitea-event']; + if (giteaEvents[header]) { + return giteaEvents[header](request); + } + + return { + error: { + success: false, + message: 'Unsupported method' + } + }; + } +} \ No newline at end of file diff --git a/img/push.png b/img/push.png new file mode 100644 index 0000000..2709c26 Binary files /dev/null and b/img/push.png differ diff --git a/img/repository.png b/img/repository.png new file mode 100644 index 0000000..497a004 Binary files /dev/null and b/img/repository.png differ