Starting on discord, switching to remote env
This commit is contained in:
parent
1b7715d0c8
commit
e9e5e8f7ec
10 changed files with 130 additions and 34 deletions
10
README.md
10
README.md
|
@ -20,11 +20,19 @@ Very unfinished!! Mostly a programming exercise for me for now to practice fulls
|
|||
(the ones that can use the website to join)
|
||||
|
||||
- [Slack](#Slack)
|
||||
- [Discord](#Discord)
|
||||
|
||||
### Slack
|
||||
|
||||
https://github.com/slackapi/node-slack-sdk
|
||||
- Set up Slack App with old style bot according to matterbridge instructions: https://github.com/42wim/matterbridge/wiki/Slack-bot-setup
|
||||
- Configure slack app to use the callback API url: `<yourdomain.etc.>/api/slack/oauth_redirect`
|
||||
- Set your `.env` variables!
|
||||
|
||||
### Discord
|
||||
|
||||
- Set up Discord App according to matterbridge instructions: https://github.com/42wim/matterbridge/wiki/Discord-bot-setup
|
||||
- Additionally enable "[Requires OAUTH2 Code Grant](https://discord.com/developers/docs/topics/oauth2#advanced-bot-authorization)" in your bot's authorization flow settings
|
||||
- Set the redirect URL to `<yourdomain.etc>/api/discord/oauth_redirect`
|
||||
|
||||
## Deployment
|
||||
|
||||
|
|
0
client/src/components/platforms/discordLogin.tsx
Normal file
0
client/src/components/platforms/discordLogin.tsx
Normal file
21
example.env
21
example.env
|
@ -9,11 +9,6 @@ POSTGRES_USER=
|
|||
POSTGRES_PASSWORD=
|
||||
POSTGRES_DB=
|
||||
|
||||
SLACK_CLIENT_ID=
|
||||
SLACK_CLIENT_SECRET=
|
||||
SLACK_SIGNING_SECRET=
|
||||
SLACK_STATE_SECRET=
|
||||
|
||||
# Used to log in to create and manage groups
|
||||
ADMIN_TOKEN=
|
||||
|
||||
|
@ -24,3 +19,19 @@ COOKIE_KEY_2=
|
|||
# Location of the matterbridge binary!
|
||||
MATTERBRIDGE_BINARY=
|
||||
MATTERBRIDGE_CONFIG_DIR=
|
||||
|
||||
# ---------------
|
||||
## Platforms
|
||||
# ---------------
|
||||
|
||||
# Slack -----------------
|
||||
SLACK_CLIENT_ID=
|
||||
SLACK_CLIENT_SECRET=
|
||||
SLACK_SIGNING_SECRET=
|
||||
SLACK_STATE_SECRET=
|
||||
|
||||
# Discord ----------------
|
||||
DISCORD_TOKEN=
|
||||
DISCORD_CLIENT_ID=
|
||||
|
||||
|
||||
|
|
|
@ -13,6 +13,10 @@ export default {
|
|||
signing_secret: 'SLACK_SIGNING_SECRET',
|
||||
state_secret: 'SLACK_STATE_SECRET'
|
||||
},
|
||||
discordConfig: {
|
||||
token: 'DISCORD_TOKEN',
|
||||
client_id: "DISCORD_CLIENT_ID"
|
||||
},
|
||||
admin_token: 'ADMIN_TOKEN',
|
||||
cookies:{
|
||||
key1: 'COOKIE_KEY_1',
|
||||
|
|
|
@ -13,6 +13,7 @@ import slackRoutes from "./routes/slack.routes";
|
|||
import authRoutes from "./routes/auth.routes";
|
||||
import bridgeRoutes from './routes/bridge.routes';
|
||||
import channelRoutes from './routes/channel.routes';
|
||||
import discordRoutes from "./routes/discord.routes";
|
||||
|
||||
import logger from "./logging";
|
||||
|
||||
|
@ -39,6 +40,7 @@ AppDataSource.initialize()
|
|||
app.use('/slack', slackRoutes);
|
||||
app.use('/bridge', bridgeRoutes);
|
||||
app.use('/channel', channelRoutes);
|
||||
app.use('/discord', discordRoutes);
|
||||
|
||||
app.all('*', (req: Request, res: Response, next: NextFunction) => {
|
||||
next(new AppError(404, `Route ${req.originalUrl} not found`));
|
||||
|
|
32
server/src/controllers/discord.controller.ts
Normal file
32
server/src/controllers/discord.controller.ts
Normal file
|
@ -0,0 +1,32 @@
|
|||
|
||||
import {Request, Response} from "express";
|
||||
import {randomUUID} from "crypto";
|
||||
import config from "config";
|
||||
import {discordConfigType} from "../types/config";
|
||||
import {DiscordBridge} from "../entities/bridge.entity";
|
||||
import {AppDataSource} from "../db/data-source";
|
||||
|
||||
|
||||
|
||||
const discordBridgeRepository = AppDataSource.getRepository(DiscordBridge)
|
||||
const discordConfig = config.get<discordConfigType>('discordConfig');
|
||||
|
||||
export const DiscordInstallLinkHandler = async(
|
||||
req: Request,
|
||||
res: Response
|
||||
) => {
|
||||
let state_token = randomUUID()
|
||||
req.session.state_token = state_token;
|
||||
|
||||
const url = `https://discordapp.com/oauth2/authorize?&client_id=${discordConfig.client_id}&scope=bot&permissions=536870912&state=${state_token}`
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
export const DiscordOAuthHandler = async(
|
||||
req: Request,
|
||||
res: Response
|
||||
) => {
|
||||
console.log('discord oauth', req.body, req.query)
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import config from 'config';
|
||||
import {Request, Response} from 'express';
|
||||
import {AppDataSource} from "../db/data-source";
|
||||
import {Bridge} from "../entities/bridge.entity";
|
||||
import {Bridge, SlackBridge} from "../entities/bridge.entity";
|
||||
import {Group} from "../entities/group.entity";
|
||||
import {JoinSlackChannelInput} from "../schemas/slack.schema";
|
||||
import {randomUUID} from "crypto";
|
||||
|
@ -12,7 +12,7 @@ import { slackConfigType } from "../types/config";
|
|||
const { InstallProvider, LogLevel, FileInstallationStore } = require('@slack/oauth');
|
||||
|
||||
const scopes = ['bot', 'channels:write', 'channels:write.invites', 'chat:write:bot', 'chat:write:user', 'users.profile:read'];
|
||||
const bridgeRepository = AppDataSource.getRepository(Bridge)
|
||||
const slackBridgeRepository = AppDataSource.getRepository(SlackBridge)
|
||||
const groupRepository = AppDataSource.getRepository(Group)
|
||||
|
||||
const SLACK_COOKIE_NAME = "slack-oauth-state";
|
||||
|
@ -77,10 +77,10 @@ export const SlackCallbackHandler = async(
|
|||
}
|
||||
|
||||
// check if we have an entity
|
||||
let bridge = await bridgeRepository.findOneBy({Token: installation.bot.token})
|
||||
let bridge = await slackBridgeRepository.findOneBy({Token: installation.bot.token})
|
||||
if (!bridge){
|
||||
bridge = await bridgeRepository.create(bridge_data);
|
||||
await bridgeRepository.save(bridge);
|
||||
bridge = await slackBridgeRepository.create(bridge_data);
|
||||
await slackBridgeRepository.save(bridge);
|
||||
logger.debug('created bridge')
|
||||
} else {
|
||||
|
||||
|
@ -88,7 +88,7 @@ export const SlackCallbackHandler = async(
|
|||
// Don't overwrite existing label
|
||||
bridge_data.Label = bridge.Label
|
||||
bridge_data = {...bridge, ...bridge_data}
|
||||
let newbridge = await bridgeRepository.save(bridge_data)
|
||||
let newbridge = await slackBridgeRepository.save(bridge_data)
|
||||
}
|
||||
res.send('<html><body><h1>Success! Return to the chatbridge login window.</h1><h3>This tab will close in 3 seconds...</h3><script>window.setTimeout(window.close, 3000)</script></body>')
|
||||
|
||||
|
@ -107,7 +107,7 @@ export const getChannelsHandler = async(
|
|||
req: Request,
|
||||
res: Response
|
||||
) => {
|
||||
let bridge = await bridgeRepository.findOneBy({state_token: req.session.state_token})
|
||||
let bridge = await slackBridgeRepository.findOneBy({state_token: req.session.state_token})
|
||||
|
||||
try {
|
||||
fetch('https://slack.com/api/conversations.list', {
|
||||
|
@ -150,7 +150,7 @@ export const joinChannelsHandler = async(
|
|||
res: Response
|
||||
) => {
|
||||
|
||||
let bridge = await bridgeRepository.findOneBy({state_token: req.session.state_token})
|
||||
let bridge = await slackBridgeRepository.findOneBy({state_token: req.session.state_token})
|
||||
|
||||
fetch('https://slack.com/api/conversations.invite', {
|
||||
method: "POST",
|
||||
|
@ -184,7 +184,7 @@ export const getBotInfo = async(
|
|||
req: Request,
|
||||
res: Response
|
||||
) => {
|
||||
let bridge = await bridgeRepository.findOneBy({state_token: req.session.state_token})
|
||||
let bridge = await slackBridgeRepository.findOneBy({state_token: req.session.state_token})
|
||||
|
||||
try {
|
||||
fetch('https://slack.com/api/auth.test', {
|
||||
|
|
|
@ -20,13 +20,6 @@ export class Bridge extends Model {
|
|||
@Column()
|
||||
Label: string;
|
||||
|
||||
// The ID of the team
|
||||
@Column({nullable:true})
|
||||
team_id: string;
|
||||
|
||||
@Column({nullable:true})
|
||||
team_name: string;
|
||||
|
||||
// Used to fetch the bridge data from the client while installing
|
||||
@Column()
|
||||
state_token: string;
|
||||
|
@ -37,16 +30,6 @@ export class Bridge extends Model {
|
|||
})
|
||||
Token: string;
|
||||
|
||||
@Column({
|
||||
nullable: true
|
||||
})
|
||||
user_token: string;
|
||||
|
||||
@Column({
|
||||
nullable:true
|
||||
})
|
||||
bot_id: string;
|
||||
|
||||
@Column({
|
||||
default: true
|
||||
})
|
||||
|
@ -58,8 +41,7 @@ export class Bridge extends Model {
|
|||
})
|
||||
RemoteNickFormat: string;
|
||||
|
||||
|
||||
|
||||
// Bridged channels (not the channels in the slack/discord/etc.)
|
||||
@OneToMany(() => Channel, (channel) => channel.bridge,
|
||||
{
|
||||
cascade: ["remove"]
|
||||
|
@ -68,6 +50,38 @@ export class Bridge extends Model {
|
|||
|
||||
}
|
||||
|
||||
@ChildEntity()
|
||||
export class SlackBridge extends Bridge {
|
||||
// The ID of the team
|
||||
@Column({nullable:true})
|
||||
team_id: string;
|
||||
|
||||
@Column({nullable:true})
|
||||
team_name: string;
|
||||
|
||||
@Column({
|
||||
nullable: true
|
||||
})
|
||||
user_token: string;
|
||||
|
||||
@Column({
|
||||
nullable:true
|
||||
})
|
||||
bot_id: string;
|
||||
|
||||
}
|
||||
|
||||
@ChildEntity()
|
||||
export class DiscordBridge extends Bridge {
|
||||
// Server name - needed to use multiple 'servers' with a single discord app
|
||||
@Column()
|
||||
Server: string;
|
||||
|
||||
// Analogous to team_id in slack bridge
|
||||
@Column()
|
||||
guild_id: string;
|
||||
}
|
||||
|
||||
@ChildEntity()
|
||||
export class MatrixBridge extends Bridge {
|
||||
// Matrix-specific
|
||||
|
|
20
server/src/routes/discord.routes.ts
Normal file
20
server/src/routes/discord.routes.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
import express from 'express';
|
||||
|
||||
import {
|
||||
DiscordInstallLinkHandler,
|
||||
DiscordOAuthHandler
|
||||
} from "../controllers/discord.controller";
|
||||
|
||||
import {
|
||||
requireStateToken
|
||||
} from "../middleware/cookies";
|
||||
|
||||
const router = express.Router();
|
||||
router.route('/install')
|
||||
.get(DiscordInstallLinkHandler)
|
||||
|
||||
router.route('/oauth_redirect')
|
||||
.get(DiscordOAuthHandler)
|
||||
|
||||
|
||||
export default router
|
|
@ -4,3 +4,8 @@ export interface slackConfigType {
|
|||
signing_secret: string,
|
||||
state_secret: string
|
||||
}
|
||||
|
||||
export interface discordConfigType {
|
||||
token: string;
|
||||
client_id: string;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue