Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
SamyPesse committed Jun 3, 2022
0 parents commit 0fc771f
Show file tree
Hide file tree
Showing 82 changed files with 10,462 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitbook.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
root: ./docs
21 changes: 21 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: CI

on:
push:
branches:
- main

jobs:
publish:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm run build --if-present
32 changes: 32 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Test

on:
push:

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm run test
lint:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm run lint
33 changes: 33 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
node_modules
.pnp
.pnp.js

# testing
coverage

# next.js
.next/
out/
build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local

# turbo
.turbo
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# `@gitbook/integrations`

This repository contains:
- [`@gitbook/cli`](./packages/cli/): CLI to build and publish integrations for GitBook
- [`@gitbook/api`](./packages/api/): API client got GitBook
- [`@gitbook/runtime`](./packages/runtime/): Core library to easily write integrations

It also hosts the default integrations provided by the GitBook team:

- [`slack`](./integrations/slack/)
- [`segment`](./integrations/segment/)
- [`webhook`](./integrations/webhook/)
Empty file added docs/README.md
Empty file.
Empty file added docs/SUMMARY.md
Empty file.
9 changes: 9 additions & 0 deletions docs/quickstart.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Quickstart

## Step 1: Install the GitBook CLI

The GitBook Development CLI requires Node v18 or later. It can be installed from NPM using:

```
npm install @gitbook/cli -g
```
4 changes: 4 additions & 0 deletions integrations/segment/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "@gitbook/integration-segment",
"private": true
}
3 changes: 3 additions & 0 deletions integrations/slack/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": ["@gitbook/eslint-config/integration"]
}
26 changes: 26 additions & 0 deletions integrations/slack/integration.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: slack
title: Slack
description: Notify a channel or individual in Slack with real-time events from GitBook.
script: ./script.ts
scopes:
- space:content
summary: |
Configure the Slack integrations to be notified about events occuring on GitBook (content updated, comments, etc).
Using the /gitbook command, you can also search all your content right from your Slack workspace.
configurations:
space:
properties:
oauth_credentials:
type: button
title: Connection
description: Authorization between Slack and GitBook.
button_text: Authorize
callback_url: /oauth
conversation:
type: string
title: Channel
description: Select a channel to post message to.
completion_url: /conversations
required:
- oauth_credentials
- conversation
16 changes: 16 additions & 0 deletions integrations/slack/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "@gitbook/integration-slack",
"private": true,
"dependencies": {
"itty-router": "^2.6.1",
"@gitbook/runtime": "*"
},
"devDependencies": {
"@gitbook/cli": "*",
"@gitbook/eslint-config": "*",
"@gitbook/tsconfig": "*"
},
"scripts": {
"lint": "eslint ./**/*.ts"
}
}
115 changes: 115 additions & 0 deletions integrations/slack/script.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { Router } from 'itty-router';

import { api, createOAuthHandler } from '@gitbook/runtime';

const router = Router({
base: `/hooks/integrations/${environment.integration.name}/installations/${environment.installation.id}`,
});

/*
* Authenticate the user using OAuth.
*/
router.get(
'/oauth',
createOAuthHandler({
clientId: '3085992729.3609034129490',
clientSecret: 'd6d82b7a831d43b046950775b03c31b8',
authorizeURL: 'https://slack.com/oauth/v2/authorize?scope=chat:write%20channels:read',
accessTokenURL: 'https://slack.com/api/oauth.v2.access',
})
);

/*
* List the conversations the user can select in the configuration flow.
*/
router.get('/conversations', async () => {
// TODO: list from all pages
const result = await executeSlackAPIRequest('POST', 'conversations.list');

const completions = result?.channels.map((channel) => ({
label: channel.name,
value: channel.id,
}));

return new Response(JSON.stringify(completions), {
headers: {
'Content-Type': 'application/json',
},
});
});

/*
* Bind these routes.
*/
addEventListener('fetch', (event, eventContext) => {
event.respondWith(router.handle(event.request, eventContext));
});

/*
* Handle content being updated: send a notification on Slack.
*/
addEventListener('space:content:updated', async (event) => {
const conversation = environment.installation.configurations?.space?.conversation;
if (!conversation) {
// Integration not yet configured.
return;
}

const space = await api.spaces.getSpace(event.spaceId);

await executeSlackAPIRequest('POST', 'chat.postMessage', {
channel: conversation,
text: `Content in "${space.data.title}" has been updated`,
});
});

/**
* Execute a Slack API request.
*/
async function executeSlackAPIRequest(
httpMethod: string,
apiMethod: string,
payload: { [key: string]: any } = {}
) {
const accessToken =
environment.installation.configurations?.space?.oauth_credentials?.access_token;
if (!accessToken) {
throw new Error('Connection not ready');
}

const url = new URL(`https://slack.com/api/${apiMethod}`);

let body;

if (httpMethod === 'GET') {
url.searchParams.set('token', accessToken);
} else {
const params = new URLSearchParams();
params.set('token', accessToken);

Object.entries(payload).forEach(([key, value]) => {
params.set(key, value);
});

body = params.toString();
}

const response = await fetch(url.toString(), {
method: httpMethod,
body,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
});

if (!response.ok) {
throw new Error(`${response.status} ${response.statusText}`);
}

const result = await response.json();
if (!result.ok) {
throw new Error(`${httpMethod} ${url.toString()}: ${result.error}`);
}

return result;
}
3 changes: 3 additions & 0 deletions integrations/slack/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "@gitbook/tsconfig/integration.json"
}
4 changes: 4 additions & 0 deletions integrations/webhook/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "@gitbook/integration-webhook",
"private": true
}
Loading

0 comments on commit 0fc771f

Please sign in to comment.