Get Started
6 Webhook Subscription

Step 6 - Webhook Subscriptions

So far, we have created some basic demonstrations of the platform. Now, let's build a useful integration between two apps.

Enable the GitHub repository webhook

In src/index.js, uncomment the import of ./githubToSlack.

import "./helloWorld";
import "./helloSlack";
import "./basicWebhook";
import "./githubToSlack";

Take a look at the webhook definition

Look at src/githubToSlack.js. The first thing we do is import the GitHub and Slack connectors.

import { GitHub } from "@runlightyear/github";
import { Slack } from "@runlightyear/slack";
import { getEnvName } from "@runlightyear/lightyear";
 
const envName = getEnvName();
 
const GITHUB_OWNER = "owner"; // The account owner of the repository. The name is not case sensitive.
const GITHUB_REPO = "repo"; // The name of the repository without the .git extension. The name is not case sensitive.
const SLACK_CHANNEL = "#general"; // The Slack channel to post messages in.
 
GitHub.onPush({
  name: "githubToSlack",
  title: "GitHub to Slack",
  owner: GITHUB_OWNER,
  repo: GITHUB_REPO,
  apps: ["slack"],
  run: async ({ data, auths }) => {
    const slack = new Slack({ auth: auths.slack });
 
    await slack.postMessage({
      channel: SLACK_CHANNEL,
      text: `[${envName}] Got push event on repo: ${data.repository.fullName}`,
    });
 
    console.info("Posted message to Slack");
  },
});

Then we create a constant for the envName, which we can obtain using the getEnvName function. This will come in handy whenever we want to make something different happen in development vs. production.

import { GitHub } from "@runlightyear/github";
import { Slack } from "@runlightyear/slack";
import { getEnvName } from "@runlightyear/lightyear";
 
const envName = getEnvName();
 
const GITHUB_OWNER = "owner"; // The account owner of the repository. The name is not case sensitive.
const GITHUB_REPO = "repo"; // The name of the repository without the .git extension. The name is not case sensitive.
const SLACK_CHANNEL = "#general"; // The Slack channel to post messages in.
 
GitHub.onPush({
  name: "githubToSlack",
  title: "GitHub to Slack",
  owner: GITHUB_OWNER,
  repo: GITHUB_REPO,
  apps: ["slack"],
  run: async ({ data, auths }) => {
    const slack = new Slack({ auth: auths.slack });
 
    await slack.postMessage({
      channel: SLACK_CHANNEL,
      text: `[${envName}] Got push event on repo: ${data.repository.fullName}`,
    });
 
    console.info("Posted message to Slack");
  },
});

Next, we define which GitHub owner/repo that we want to use. Update the values to match a GitHub repo that you control and want to use for this tutorial.

Be sure to update the Slack channel as well.

import { GitHub } from "@runlightyear/github";
import { Slack } from "@runlightyear/slack";
import { getEnvName } from "@runlightyear/lightyear";
 
const envName = getEnvName();
 
const GITHUB_OWNER = "owner"; // The account owner of the repository. The name is not case sensitive.
const GITHUB_REPO = "repo"; // The name of the repository without the .git extension. The name is not case sensitive.
const SLACK_CHANNEL = "#general"; // The Slack channel to post messages in.
 
GitHub.onPush({
  name: "githubToSlack",
  title: "GitHub to Slack",
  owner: GITHUB_OWNER,
  repo: GITHUB_REPO,
  apps: ["slack"],
  run: async ({ data, auths }) => {
    const slack = new Slack({ auth: auths.slack });
 
    await slack.postMessage({
      channel: SLACK_CHANNEL,
      text: `[${envName}] Got push event on repo: ${data.repository.fullName}`,
    });
 
    console.info("Posted message to Slack");
  },
});

This webhook will be more sophisticated than the previous one we defined in that it will subscribe to push events in the GitHub repository. We can set this up using the GitHub.onPush handler function.

import { GitHub } from "@runlightyear/github";
import { Slack } from "@runlightyear/slack";
import { getEnvName } from "@runlightyear/lightyear";
 
const envName = getEnvName();
 
const GITHUB_OWNER = "owner"; // The account owner of the repository. The name is not case sensitive.
const GITHUB_REPO = "repo"; // The name of the repository without the .git extension. The name is not case sensitive.
const SLACK_CHANNEL = "#general"; // The Slack channel to post messages in.
 
GitHub.onPush({
  name: "githubToSlack",
  title: "GitHub to Slack",
  owner: GITHUB_OWNER,
  repo: GITHUB_REPO,
  apps: ["slack"],
  run: async ({ data, auths }) => {
    const slack = new Slack({ auth: auths.slack });
 
    await slack.postMessage({
      channel: SLACK_CHANNEL,
      text: `[${envName}] Got push event on repo: ${data.repository.fullName}`,
    });
 
    console.info("Posted message to Slack");
  },
});

Next we pass in the name and title of the webhook, along with the github owner and repo.

import { GitHub } from "@runlightyear/github";
import { Slack } from "@runlightyear/slack";
import { getEnvName } from "@runlightyear/lightyear";
 
const envName = getEnvName();
 
const GITHUB_OWNER = "owner"; // The account owner of the repository. The name is not case sensitive.
const GITHUB_REPO = "repo"; // The name of the repository without the .git extension. The name is not case sensitive.
const SLACK_CHANNEL = "#general"; // The Slack channel to post messages in.
 
GitHub.onPush({
  name: "githubToSlack",
  title: "GitHub to Slack",
  owner: GITHUB_OWNER,
  repo: GITHUB_REPO,
  apps: ["slack"],
  run: async ({ data, auths }) => {
    const slack = new Slack({ auth: auths.slack });
 
    await slack.postMessage({
      channel: SLACK_CHANNEL,
      text: `[${envName}] Got push event on repo: ${data.repository.fullName}`,
    });
 
    console.info("Posted message to Slack");
  },
});

Now look at the run function

The run function is where we define the logic that will run when the webhook is triggered. In this case, we will post a message to Slack.

In order to do that, we first have to identify that we are using the Slack app.

import { GitHub } from "@runlightyear/github";
import { Slack } from "@runlightyear/slack";
import { getEnvName } from "@runlightyear/lightyear";
 
const envName = getEnvName();
 
const GITHUB_OWNER = "owner"; // The account owner of the repository. The name is not case sensitive.
const GITHUB_REPO = "repo"; // The name of the repository without the .git extension. The name is not case sensitive.
const SLACK_CHANNEL = "#general"; // The Slack channel to post messages in.
 
GitHub.onPush({
  name: "githubToSlack",
  title: "GitHub to Slack",
  owner: GITHUB_OWNER,
  repo: GITHUB_REPO,
  apps: ["slack"],
  run: async ({ data, auths }) => {
    const slack = new Slack({ auth: auths.slack });
 
    await slack.postMessage({
      channel: SLACK_CHANNEL,
      text: `[${envName}] Got push event on repo: ${data.repository.fullName}`,
    });
 
    console.info("Posted message to Slack");
  },
});

Then it's a simple matter of creating a new Slack connector...

import { GitHub } from "@runlightyear/github";
import { Slack } from "@runlightyear/slack";
import { getEnvName } from "@runlightyear/lightyear";
 
const envName = getEnvName();
 
const GITHUB_OWNER = "owner"; // The account owner of the repository. The name is not case sensitive.
const GITHUB_REPO = "repo"; // The name of the repository without the .git extension. The name is not case sensitive.
const SLACK_CHANNEL = "#general"; // The Slack channel to post messages in.
 
GitHub.onPush({
  name: "githubToSlack",
  title: "GitHub to Slack",
  owner: GITHUB_OWNER,
  repo: GITHUB_REPO,
  apps: ["slack"],
  run: async ({ data, auths }) => {
    const slack = new Slack({ auth: auths.slack });
 
    await slack.postMessage({
      channel: SLACK_CHANNEL,
      text: `[${envName}] Got push event on repo: ${data.repository.fullName}`,
    });
 
    console.info("Posted message to Slack");
  },
});

...and using it to post a message. If you look closely, you'll note that we begin the Slack message with the envName in brackets.

import { GitHub } from "@runlightyear/github";
import { Slack } from "@runlightyear/slack";
import { getEnvName } from "@runlightyear/lightyear";
 
const envName = getEnvName();
 
const GITHUB_OWNER = "owner"; // The account owner of the repository. The name is not case sensitive.
const GITHUB_REPO = "repo"; // The name of the repository without the .git extension. The name is not case sensitive.
const SLACK_CHANNEL = "#general"; // The Slack channel to post messages in.
 
GitHub.onPush({
  name: "githubToSlack",
  title: "GitHub to Slack",
  owner: GITHUB_OWNER,
  repo: GITHUB_REPO,
  apps: ["slack"],
  run: async ({ data, auths }) => {
    const slack = new Slack({ auth: auths.slack });
 
    await slack.postMessage({
      channel: SLACK_CHANNEL,
      text: `[${envName}] Got push event on repo: ${data.repository.fullName}`,
    });
 
    console.info("Posted message to Slack");
  },
});

Now that we've reviewed all the code, let's take a look at the terminal and see what happened on deploy.

VM: [INFO]: Starting deploy
VM: [INFO]: Deploying helloWorld, basicWebhook, helloSlack, githubWebhook, githubToSlack
VM: [INFO]: Deploy succeeded
CLI: [INFO]: Skipping subscribe for webhooks that need configuration: githubToSlack

Looks like we need to do some additional setup!

Authorize the GitHub app

Go to the Webhooks menu (opens in a new tab) and click on the new GitHub to Slack

0

Notice that the GitHub app needs to be authorized. Click on the GitHub app...

0

...and then click Authorize to begin the OAuth2 flow.

0

When you are back, you should see that GitHub is authorized and that you can share the auth with the production environment. Go ahead and do that.

0

Now go back to the webhook...

0

and then to the Subscription tab...

0

... and click the Subscribe button.

0

If everything is set up properly, you should see a Subscribe succeeded activity.

0

Push to the repo and see the result

And now, the moment of truth. Drumroll please....

Make a change to your repo, commit the change, and push it.

To see if it worked, go to the action

0

Then, let's go to the Runs tab to see what happened.

0

If everything went smoothly, you should see a single successful run like this, along with a run that was skipped because we received a ping event from GitHub to verify the endpoint is valid.

0