-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat(discord): initial commit * feat(discord): initial auth setup * added a scope for discord to allow channel selection * added a scope for discord to allow channel selection * added space content updated event to discord integration * added messages api url to discord integration * feat(discord): get channel id via auth webhook * added webhook to extended oauthresponse * feat(discord): use bot token for auth * feat(discord): post message in channel and add embedObject * feat(discord): organise and clean up todos and comments * Update manifest --------- Co-authored-by: chanlevandermerwe <[email protected]> Co-authored-by: megantipps <[email protected]>
- Loading branch information
1 parent
48957c5
commit 71cf45e
Showing
11 changed files
with
908 additions
and
911 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,8 +36,8 @@ yarn-error.log* | |
# turbo | ||
.turbo | ||
|
||
|
||
.env | ||
|
||
.idea | ||
|
||
.gitbook-dev.yaml | ||
.gitbook-dev.yaml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"extends": ["@gitbook/eslint-config/integration"] | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
name: discord | ||
title: Discord | ||
icon: ./assets/icon.png | ||
organization: gitbook | ||
visibility: public | ||
categories: | ||
- collaboration | ||
description: Notify a server channel in Discord with real-time events from GitBook. | ||
summary: | | ||
# Overview | ||
The GitBook Discord integration brings the power of GitBook to your Discord Server. Your members have instant access to your GitBook knowledge base, without leaving the app. | ||
# How it works | ||
Get notified of what's important: | ||
Receive real-time Discord notifications when something important happens to your content on GitBook. For example, when your content is updated or published. | ||
Pick and choose what, where, and how you wish to be notified. | ||
# Configure | ||
You can install the integration on a single space by clicking the integrations button in sub-navigation panel. If you prefer to install the Discord integration on multiple on all spaces you can enable this through organization settings. To configure the integration you will have to authorize the connection between Discord and GitBook. You can also select the default server to post messages to. | ||
previewImages: | ||
- ./assets/discord-preview.png | ||
externalLinks: | ||
- label: Homepage | ||
url: https://www.discord.com | ||
script: src/index.tsx | ||
scopes: | ||
- space:content:read | ||
- space:metadata:read | ||
configurations: | ||
account: | ||
properties: | ||
oauth_credentials: | ||
type: button | ||
title: Connection | ||
description: Authorization between Discord and GitBook. | ||
button_text: Authorize | ||
callback_url: /oauth | ||
required: | ||
- oauth_credentials | ||
secrets: | ||
CLIENT_ID: ${{ env.DISCORD_CLIENT_ID }} | ||
CLIENT_SECRET: ${{ env.DISCORD_CLIENT_SECRET }} | ||
BOT_TOKEN: ${{ env.DISCORD_BOT_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"name": "discord", | ||
"private": true, | ||
"scripts": { | ||
"lint": "eslint ./**/*.ts*", | ||
"typecheck": "tsc --noEmit", | ||
"publish-integrations-staging": "gitbook publish ." | ||
}, | ||
"devDependencies": { | ||
"@gitbook/cli": "^0.8.0", | ||
"@gitbook/runtime": "latest" | ||
}, | ||
"dependencies": { | ||
"itty-router": "^4.0.9" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
export const sendDiscordMessage = async (event, context) => { | ||
const { environment, api } = context; | ||
const { data: space } = await api.spaces.getSpaceById(event.spaceId); | ||
|
||
const channelId = | ||
environment.installation?.configuration.oauth_credentials?.webhook?.channel_id; | ||
|
||
const url = `https://discord.com/api/v10/channels/${channelId}/messages`; | ||
|
||
const botToken = environment.secrets.BOT_TOKEN; | ||
|
||
const accessToken = environment.installation?.configuration.oauth_credentials?.access_token; | ||
|
||
if (!accessToken) { | ||
throw new Error('No authentication token provided'); | ||
} | ||
|
||
const embedObject = { | ||
title: 'View changes here:', | ||
description: `${space.urls.app}`, | ||
thumbnail: { | ||
url: 'https://avatars.githubusercontent.com/u/7111340?s=280&v=4', | ||
}, | ||
}; | ||
|
||
const headers = { | ||
'Content-Type': 'application/json', | ||
Authorization: `Bot ${botToken}`, | ||
}; | ||
const body = JSON.stringify({ | ||
content: `Changes have been made in ${space.title}.`, | ||
embeds: [embedObject], | ||
}); | ||
|
||
await fetch(url, { method: 'POST', headers, body }).catch((err) => { | ||
throw new Error(`Error fetching content from ${url}. ${err}`); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { Router } from 'itty-router'; | ||
|
||
// eslint-disable-next-line import/no-extraneous-dependencies | ||
import { RequestUpdateIntegrationInstallation } from '@gitbook/api'; | ||
import { | ||
createIntegration, | ||
createOAuthHandler, | ||
FetchEventCallback, | ||
EventCallback, | ||
} from '@gitbook/runtime'; | ||
|
||
import { sendDiscordMessage } from './discord'; | ||
import { DiscordRuntimeContext, OAuthResponseWebhook } from './types'; | ||
|
||
/* | ||
* Handle content being updated: send a notification on Slack. | ||
*/ | ||
const handleSpaceContentUpdated: EventCallback< | ||
'space_content_updated', | ||
DiscordRuntimeContext | ||
> = async (event, context) => { | ||
await sendDiscordMessage(event, context); | ||
}; | ||
|
||
const handleFetchEvent: FetchEventCallback<DiscordRuntimeContext> = async (request, context) => { | ||
const { environment } = context; | ||
|
||
const router = Router({ | ||
base: new URL( | ||
environment.spaceInstallation?.urls?.publicEndpoint || | ||
environment.installation?.urls.publicEndpoint || | ||
environment.integration.urls.publicEndpoint | ||
).pathname, | ||
}); | ||
|
||
/* | ||
* Authenticate the user using OAuth. | ||
*/ | ||
router.get( | ||
'/oauth', | ||
// @ts-ignore | ||
createOAuthHandler({ | ||
redirectURL: `${context.environment.integration.urls.publicEndpoint}/oauth`, | ||
clientId: environment.secrets.CLIENT_ID, | ||
clientSecret: environment.secrets.CLIENT_SECRET, | ||
authorizeURL: | ||
'https://discord.com/api/oauth2/authorize?response_type=code&permissions=2147485696', | ||
accessTokenURL: 'https://discord.com/api/oauth2/token', | ||
scopes: ['applications.commands', 'bot', 'webhook.incoming'], | ||
extractCredentials, | ||
}) | ||
); | ||
|
||
const response = await router.handle(request, context); | ||
if (!response) { | ||
return new Response(`No route matching ${request.method} ${request.url}`, { | ||
status: 404, | ||
}); | ||
} | ||
return response; | ||
}; | ||
|
||
const extractCredentials = async ( | ||
response: OAuthResponseWebhook | ||
): Promise<RequestUpdateIntegrationInstallation> => { | ||
const { access_token, webhook } = response; | ||
return { | ||
configuration: { | ||
oauth_credentials: { | ||
access_token, | ||
expires_at: Date.now() + response.expires_in * 1000, | ||
refresh_token: response.refresh_token, | ||
webhook, | ||
}, | ||
}, | ||
}; | ||
}; | ||
|
||
export default createIntegration<DiscordRuntimeContext>({ | ||
fetch: handleFetchEvent, | ||
events: { | ||
space_content_updated: handleSpaceContentUpdated, | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { RuntimeEnvironment, RuntimeContext, OAuthResponse } from '@gitbook/runtime'; | ||
|
||
export interface DiscordInstallationConfiguration { | ||
oauth_credentials?: { | ||
access_token: string; | ||
webhook: { | ||
application_id: string; | ||
name: string; | ||
url: string; | ||
channel_id: string; | ||
token: string; | ||
type: number; | ||
avatar?: string; | ||
guild_id: string; | ||
id: string; | ||
}; | ||
}; | ||
} | ||
|
||
export interface DiscordSpaceInstallationConfiguration { | ||
channel?: string; | ||
notify_content_update?: boolean; | ||
notify_visibility_update?: boolean; | ||
} | ||
|
||
export type DiscordRuntimeEnvironment = RuntimeEnvironment< | ||
DiscordInstallationConfiguration, | ||
DiscordSpaceInstallationConfiguration | ||
>; | ||
export type DiscordRuntimeContext = RuntimeContext<DiscordRuntimeEnvironment>; | ||
|
||
export interface OAuthResponseWebhook extends OAuthResponse { | ||
webhook: { | ||
application_id: string; | ||
name: string; | ||
url: string; | ||
channel_id: string; | ||
token: string; | ||
type: number; | ||
avatar?: string; | ||
guild_id: string; | ||
id: string; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"extends": "@gitbook/tsconfig/integration.json" | ||
} |
Oops, something went wrong.