2017-03-28 65 views
0

我想創建一個使用傳入webhooks的鬆弛應用程序。我希望我的github存儲庫在wiki更新時發佈到閒置狀態。我相信我已經在github上設置了webhook,因爲我可以看到它在每次更新wiki時都會嘗試發送。但是,總是有錯誤,「no_text」。我認爲這個錯誤意味着鬆懈期待一個名爲「文本」的項目,但github的負載不提供任何內容。我通過在命令提示符下嘗試2個捲曲命令驗證了這一點(我在Windows上):鬆弛無法識別github webhook有效負載格式

curl -X POST -H "Content-type: application/json" --data "{\"text\":\"Hello, World!\"}" [MY_WEBHOOK_URL]
curl -X POST -H "Content-type: application/json" --data "{\"foobar\":\"Hello, World!\"}" [MY_WEBHOOK_URL]

這第一個按預期工作;消息「Hello,World!」被張貼到我想要的鬆弛頻道,並且我從curl中收回了「ok」消息。第二個不起作用;該消息未發佈,我從curl中收回消息「no_text」。

我能想到的兩種可能的解決了這個問題:

  1. 變化從GitHub的有效載荷的格式,包括所謂的「文字」等特性懈怠實際識別的項目。
  2. 通過告訴它發佈除「text」之外的其他屬性的內容,可以獲得冗餘來識別有效載荷已經存在的格式。

我不知道如何完成其​​中之一,或者如果他們甚至可能。或者也許還有另一個我沒有想到的解決方案?

注:我已經嘗試使用github slack應用程序,但無法弄清楚如何讓它發佈更新到wiki。 (看到我的另一個問題,如果你願意:slack github integration doesn't find wiki repository

回答

0

我其實正在尋找和你一樣的東西。因爲github和slack鉤子根本不同,所以你需要在中間有一些東西來處理github webhooks到一個Slack消息中,通過一個傳入的webhook發佈。

你會需要做一些不同的東西(排名不分先後):

  1. 設置Github上發出掛鉤您希望被通知的具體事件。
  2. 配置一箇中間人(我目前正在使用AWS SNS和Lambda)
  3. 設置webhook的鬆弛。

對於github webhooks,您需要利用功能更強大的github API來創建鉤子。你可以用curl來做到這一點,但是這很痛苦,所以我使用JS腳本來處理它。您需要npm install github bluebird在同一目錄下運行這樣前:

var GitHubApi = require("github"); 

var github = new GitHubApi({ 
    // optional 
    debug: true, 
    protocol: "https", 
    host: "api.github.com", // should be api.github.com for GitHub 
    pathPrefix: "", // for some GHEs; none for GitHub 
    headers: { 
     "user-agent": "ocelotsloth-conf" // GitHub is happy with a unique user agent 
    }, 
    Promise: require('bluebird'), 
    followRedirects: false, // default: true; there's currently an issue with non-get redirects, so allow ability to disable follow-redirects 
    timeout: 5000 
}); 

// user token 
github.authenticate({ 
    type: "token", 
    token: "GITHUB_TOKEN_HERE", 
}); 

// https://mikedeboer.github.io/node-github/#api-repos-createHook 
github.repos.createHook({ 
    owner: "ocelotsloth", 
    repo: "lib-ical", 
    name: "amazonsns", 
    events: [ 
    //"commit_comment", 
    //"create", 
    //"delete", 
    //"gollum", 
    //"issue_comment", 
    "issues" 
    //"label", 
    //"milestone", 
    //"pull_request", 
    //"pull_request_review", 
    //"pull_request_review_comment", 
    //"push", 
    //"release" 
    ], 
    config: { 
    aws_key: "AWS_KEY", 
    aws_secret: "AWS_SECRET", 
    sns_region: "us-east-1", 
    sns_topic: "SNS_TOPIC_ARN" 
    }, 

}, function(err, res) { 
    console.log(JSON.stringify(res, null, '\t')); 
}); 

記得關注博客發表前一段時間有關設置SNS話題正常工作,但我不記得確切的地方已經是了。一些谷歌應該幫助。另外,如果您想避免複雜性,您應該能夠爲github建立自己的服務器,以將它們發送到並避免必須設置AWS。有關該方法的具體說明,請參見https://mikedeboer.github.io/node-github/#api-repos-createHook。創建掛鉤後,您需要使用editHook,因此無論是第一次使用它還是使用編輯它。您只需將方法調用更改爲editHook,並將id添加到調用中。

重要的是要看到,你可以定義你希望github發送給你的所有不同Events。對於所有這些以及它們的格式,請看https://developer.github.com/v3/activity/events/types/。如果要將這些事件實際發佈爲冗餘,我有一個目前看起來像這樣的lambda腳本(我現在剛剛從今天開始寫這篇文章,並沒有實現更多的發佈事件事件,但它應該做得很好初始點)。對於這個腳本,你需要npm install identify-github-event slack-webhook,並設置你的webhook。

var identifyGithubEvent = require('identify-github-event'); 
var SlackWebhook = require('slack-webhook') 

// slack's link syntax 
function link(url, txt) { 
return "<" + url + "|" + txt + ">"; 
} 

exports.handler = function(event, context) { 
// 1. extract GitHub event from SNS message 
var ghEvent = JSON.parse(event.Records[0].Sns.Message); 
var eventType, eventName, numb; 
console.log(ghEvent); 

var ghEventType = identifyGithubEvent(ghEvent); 

if (!ghEventType) { 
    return; 
} 

var text = "Event! " + ghEventType; 

if (ghEventType === 'IssueCommentEvent') { 
    var who = link(ghEvent.comment.user.html_url, ghEvent.comment.user.login); 
    var what = link(ghEvent.issue.html_url, "Issue " + ghEvent.issue.number + ": \"" + ghEvent.issue.title + "\""); 
    text = who + " commented on " + what; 
} 
else if (ghEventType === 'IssuesEvent') { 
    var who = link(ghEvent.sender.html_url, ghEvent.sender.login); 
    var action = ghEvent.action; 
    var issueNumber = ghEvent.issue.number; 
    var issueName = link(ghEvent.issue.html_url, ghEvent.issue.title + "\""); 

    if (action === "opened" | action === "closed") { 
     text = { 
      attachments: [{ 
       "fallback": who + " opened Issue" + issueNumber + ": " + issueName, 
       "color": "#36a64f", 
       "pretext": "New issue " + action + ":", 
       "author_name": ghEvent.sender.login, 
       "author_link": ghEvent.sender.html_url, 
       "thumb_url": ghEvent.sender.avatar_url, 
       "title": "#" + issueNumber + ": " + ghEvent.issue.title, 
       "title_link": ghEvent.issue.html_url, 
       "text": ghEvent.issue.body, 
       "fields": [ 
       { 
        "title": "Status", 
        "value": ghEvent.issue.state, 
        "short": true 
       }, 
       { 
        "title": "Labels", 
        "value": ghEvent.issue.labels.map(label => label.name).join("\n"), 
        "short": true 
       } 
       ], 
       "footer": "lib-ical", 
       "footer_icon": "https://platform.slack-edge.com/img/default_application_icon.png", 
       "mrkdwn_in": ["text"] 
      }] 
     }; 
    } else return; 
} 

    // 'commit_comment': 
    // 'create': 
    // 'delete': 
    // 'issues': 
    // 'label': 
    // 'member': 
    // 'milestone': 
    // 'pull_request': 
    // 'pull_request_review': 
    // 'pull_request_review_comment': 
    // 'push': 
    // 'release': 

var slack = new SlackWebhook('https://hooks.slack.com/services/SLACK-WEBHOOK-URL', { 
    defaults: { 
    username: 'GitHub -- user/project', 
    channel: '#CHANNEL-NAME', 
    icon_emoji: ':github:' 
    } 
}) 

slack.send(text); 

}; 

它遠非完美,但它提供了一個非常好的結果:

Example hook

因爲這是一個問題近,具體的例子,但目前該腳本也將開放工作。該腳本還會執行有限的降價處理,所以如果問題包含任何源塊,它將在鬆弛內正確呈現。

我希望這可以幫助你的方法,隨時要求我詳細說明其他任何事情。