slack没有识别github webhook有效载荷格式

时间:2017-03-28 21:44:44

标签: github webhooks slack-api slack payload

我试图创建一个使用传入webhook的松弛应用程序。我希望每当维基更新时,我的github存储库都会发布。我相信我已经在github上设置了webhook就好了,因为每当我更新wiki时我都能看到它正在尝试交付。但是,始终存在错误," no_text"。我认为这个错误意味着松弛期待一个名为" text,"但是来自github的有效负载没有提供。我通过在命令提示符下尝试两个curl命令来验证这一点(我在Windows上):

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]

第一个按预期工作;消息"你好,世界!"被发布到我想要的松弛频道,我回到了" ok"卷曲的消息。第二个没有用;消息没有发布,我收到了消息" no_text"来自卷曲。

我可以想到两个可能解决这个问题的方法:

  1. 更改来自github的有效负载的格式,以包含一个名为" text"的项目。和slack实际上认可的其他属性。
  2. 通过告诉它发布除"文本以外的其他属性的内容,可以轻松识别有效负载已经存在的格式。"
  3. 我不知道如何完成其​​中任何一项,或者如果他们甚至可能。或者也许还有我想不到的另一种解决方案?

    注意:我已经尝试使用github slack app,但无法弄清楚如何让它发布更新到wiki。 (如果您愿意,请参阅我的另一个问题:slack github integration doesn't find wiki repository

1 个答案:

答案 0 :(得分:2)

我实际上想要和你一样做同样的事情。因为github和slack钩子根本不同,所以你需要在中间有一些东西将github webhooks处理成Slack消息,以便通过传入的webhook发布。

你需要做几件不同的事情(没有特别的顺序):

  1. 设置Github以发送您希望收到通知的特定事件的挂钩。
  2. 配置中间人(我目前正在使用AWS SNS和Lambda)
  3. 为webhook设置松弛。
  4. 对于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

    对于该特定示例,问题很接近,但目前该脚本也将在打开时运行。该脚本还执行有限的降价处理,因此如果问题包含任何源块,它将在松弛内部正确呈现。

    我希望这可以帮助你处理你的方法,随时让我详细说明其他事情。