slack 无法识别 github webhook 负载格式

slack doesn't recognize github webhook payload format

我正在尝试创建一个使用传入 webhook 的 slack 应用程序。我希望我的 github 存储库到 post 在 wiki 更新时松弛。我相信我已经在 github 上设置了 webhook 就好了,因为我可以看到每当我更新 wiki 时它都在尝试交付。但是,始终存在错误 "no_text"。我认为这个错误意味着 slack 期待一个名为 "text," 的项目,但来自 github 的有效负载提供了 none。我通过在命令提示符下尝试两个 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]

第一个按预期工作;消息 "Hello, World!" 被 post 发送到我想要的松弛通道,我从 curl 返回了 "ok" 消息。第二个没有用;该消息未 posted,我从 curl.

返回消息 "no_text"

我可以想到两个可能的解决方案:

  1. 更改来自 github 的有效载荷的格式,以包含名为 "text" 的项目和 slack 实际识别的其他属性。
  2. 慢慢地识别有效载荷已经存在的格式,也许通过告诉它 post 属性 的内容而不是 "text."

我不知道如何完成其​​中任何一个,或者它们是否可能。或者还有其他我没有想到的解决方案?

注意:我已经尝试使用 github slack 应用程序,但无法弄清楚如何使用它来 post 更新维基。 (如果您愿意,请参阅我的其他问题:slack github integration doesn't find wiki repository

我现在正想做和你一样的事情。因为 github 和 slack 挂钩根本不同,所以您需要在中间添加一些东西来将 github webhook 处理成 Slack 消息,以便通过传入的 webhook posted。

您将需要做几件不同的事情(排名不分先后):

  1. 设置 Github 为您希望收到通知的特定事件发送挂钩。
  2. 配置中间人(我目前使用的是AWS SNS和Lambda)
  3. 为 webhook 设置 slack。

对于 github webhook,您需要利用更强大的 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'));
});

我记得不久前关注过一篇博客 post 关于如何设置 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/.

为了真正 post 这些事件松弛,我有一个 lambda 脚本,目前看起来像这样(我今天才开始写这个,除了 posting 之外没有实现问题事件,但作为起点应该做得很好)。对于此脚本,您需要 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);

};

它远非完美,但它给出了一个非常好的结果:

对于那个特定的例子,它是一个关闭的问题,但目前该脚本也可以打开。该脚本还进行了有限的降价处理,因此如果问题包含任何源代码块,它将在 slack 中正确呈现。

我希望这对您的方法有所帮助,请随时让我详细说明其他问题。