slack doesn't recognize github webhook payload format

∥☆過路亽.° 提交于 2019-12-12 03:33:34

问题


I'm trying to create a slack app that uses incoming webhooks. I want my github repository to post to slack whenever the wiki is updated. I believe I've set up the webhook on github just fine, because I can see that it is attempting a delivery whenever I update the wiki. However, there's always the error, "no_text". I think this error means slack is expecting an item named "text," but the payload from github provides none. I verified this by trying two curl commands from the command prompt (I'm on 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]

This first one works as expected; the message "Hello, World!" gets posted to the slack channel I wanted, and I got back the "ok" message from curl. The second one did not work; the message was not posted, and I got back the message "no_text" from curl.

I can think of two possible solutions to this problem:

  1. Change the format of the payload coming from github to include an item called "text" and other properties slack actually recognizes.
  2. Get slack to recognize the format the payload is already in, perhaps by telling it to post the contents of a property other than "text."

I don't know how to accomplish either of these, or if they're even possible. Or perhaps there's another solution I haven't thought of?

Note: I already tried to use the github slack app, but couldn't figure out how to get it to post updates to the wiki. (See my other question if you'd like: slack github integration doesn't find wiki repository)


回答1:


I'm actually looking to do the same thing as you right now. Because the github and slack hooks are fundamentally different, you will need to have something in the middle to process the github webhooks into a Slack message to be posted via an incoming webhook.

You're going to need to do a couple different things (in no particular order):

  1. Set up Github to send out hooks for the specific events you wish to be notified of.
  2. Configure a middle man (I am currently using AWS SNS and Lambda)
  3. Set up slack for the webhook.

For the github webhooks, you will need to leverage the more powerful github API to create the hook. You could do this with curl, but that's kind of a pain so I am using a JS script to take care of it. You will need to npm install github bluebird in the same directory before running something like this:

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'));
});

I remember following a blog post a while ago about setting up the SNS topic to work properly, but I don't remember exactly where it is anymore. Some googling should help. Also, you should be able to set up your own server for github to send these to and avoid having to set up AWS at all if you want to avoid the complexity. See https://mikedeboer.github.io/node-github/#api-repos-createHook for specific instructions on that method. You will need to use editHook after you create the hook, so either get it right the first time or use edit it. You just need to change the method call to editHook and add the id to the call as well.

Something important to see, you can define all of the different Events that you want github to send to you. For all of these, along with their formats, look at https://developer.github.com/v3/activity/events/types/.

To actually post these events to slack, I have a lambda script that currently looks like this (I literally just started writing this today, and haven't implemented more than just posting issue events, but it should do well as a starting point). For this script, you will need to npm install identify-github-event slack-webhook and have your incoming webhook set up as well.

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);

};

It's far from perfect, but it gives a really nice result:

For that specific example it's an issue close, but currently that script will also work on open. The script also does limited markdown processing, so if the issue contains any source blocks, it will be rendered properly inside of slack.

I hope this helps you with your approach, feel free to ask me to elaborate on anything else.



来源:https://stackoverflow.com/questions/43080513/slack-doesnt-recognize-github-webhook-payload-format

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!