Skip to content
This repository has been archived by the owner on Dec 1, 2023. It is now read-only.

Commit

Permalink
add onboarding
Browse files Browse the repository at this point in the history
  • Loading branch information
katsumi143 committed Nov 15, 2023
1 parent 06f9e21 commit 89940ac
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 50 deletions.
11 changes: 7 additions & 4 deletions src/commands/general/whois.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@ export default command(({ t, token, guild_id }, { target }) => defer(token, asyn
value: roles.join(' • ')
});

const robloxLinks = await supabase.from('user_connections')
.select('sub')
const robloxLinks = await supabase.from('mellow_user_server_connections')
.select<string, {
connection: { sub: string }
}>('connection:user_connections ( sub )')
.eq('user_id', user.id)
.eq('type', 2);
.eq('server_id', guild_id)
.eq('user_connections.type', 2);
if (robloxLinks.data) {
const users = await ROBLOX_API.users.getProfiles(robloxLinks.data.map(i => i.sub), ['names.username', 'names.combinedName']);
const users = await ROBLOX_API.users.getProfiles(robloxLinks.data.map(i => i.connection.sub), ['names.username', 'names.combinedName']);
fields.push({
name: t('whois.roblox'),
value: users.map(user => t('whois.roblox.user', [user])).join(' • ')
Expand Down
2 changes: 1 addition & 1 deletion src/commands/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { DiscordInteraction, CommandExecutePayload, DiscordApplicationComma

import { setup } from './other/mod.ts';
import { ping, roll, whois, pokemon } from './general/mod.ts';
import { sync, forcesync, forcesyncall } from './roblox/mod.ts';
import { sync, forcesync, forcesyncall } from './syncing/mod.ts';
export const commands: Record<string, Command<any>> = {
ping,
roll,
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { defer, content } from '../response.ts';
import { DISCORD_APP_ID } from '../../util/constants.ts';
import { sendSyncedWebhookEvent } from '../../syncing.ts';
import type { Log, RobloxProfile, WebhookSyncedEventItem } from '../../types.ts';
import { DiscordMessageFlag, MellowServerLogType, WebhookSyncedEventItemState } from '../../enums.ts';
import { supabase, getServer, getUsersByDiscordId, getServerProfileSyncingActions } from '../../database.ts';
import { getDiscordServer, getServerMembers, getMemberPosition, editOriginalResponse } from '../../discord.ts';
import { DiscordMessageFlag, UserConnectionType, MellowServerLogType, WebhookSyncedEventItemState } from '../../enums.ts';
export default command(({ t, token, member, guild_id }) => defer(token, async () => {
const server = await getServer(guild_id);
if (!server)
Expand All @@ -32,13 +32,21 @@ export default command(({ t, token, member, guild_id }) => defer(token, async ()

const users = await getUsersByDiscordId(members.map(member => member.user.id));
const links = await supabase.from('users')
.select('user_connections ( sub, type, user_id )')
.select<string, {
connections: {
connection: {
sub: string
type: UserConnectionType
user_id: string
}
}[]
}>('connections:mellow_user_server_connections ( connection:user_connections ( sub, type, user_id ) )')
.in('id', users.map(user => user.id))
.eq('user_connections.type', 2)
.eq('mellow_user_server_connections.user_connections.type', 2)
.then(response => {
if (response.error)
console.error(response.error);
return response.data?.map(item => item.user_connections[0]).filter(i => i) ?? [];
return response.data?.map(item => item.connections[0]?.connection).filter(i => i) ?? [];
});

const robloxUsers: RobloxProfile[] = await ROBLOX_API.users.getProfiles(links.map(link => link.sub as string), ['names.username', 'names.combinedName']);
Expand Down
File renamed without changes.
56 changes: 21 additions & 35 deletions src/commands/roblox/sync.ts → src/commands/syncing/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { sendLogs } from '../../logging.ts';
import { syncMember } from '../../roblox.ts';
import { defer, content } from '../response.ts';
import { sendSyncedWebhookEvent } from '../../syncing.ts';
import { MELLOW_SYNC_REQUIREMENT_CONNECTIONS } from '../../constants.ts';
import { getDiscordServer, getMemberPosition, editOriginalResponse } from '../../discord.ts';
import type { User, TranslateFn, MellowServer, DiscordMember, RobloxProfile } from '../../types.ts';
import { supabase, getServer, getUserByDiscordId, getServerProfileSyncingActions } from '../../database.ts';
Expand All @@ -29,47 +30,33 @@ export default command(({ t, token, locale, member, guild_id }) => defer(token,
});
return editOriginalResponse(token, {
flags: DiscordMessageFlag.Ephemeral,
content: t('sync.signup'),
components: [{
type: 1,
components: [{
url: 'https://discord.com/api/oauth2/authorize?client_id=1068554282481229885&redirect_uri=https%3A%2F%2Fapi.hakumi.cafe%2Fv1%2Fauth%2Fcallback%2F0&response_type=code&scope=identify&state=roblox',
type: 2,
style: 5,
label: t('common:action.continue')
}]
}]
content: t('sync.signup', ['TODO', guild_id])
});
}, DiscordMessageFlag.Ephemeral));

export async function verify(t: TranslateFn, executor: DiscordMember | null, server: MellowServer, token: string, serverId: string, user: User | undefined, member: DiscordMember, syncAs?: number) {
const userBind = user ? await supabase.from('users')
.select('user_connections ( sub )')
export async function verify(t: TranslateFn, executor: DiscordMember | null, server: MellowServer, token: string, serverId: string, user: User | undefined, member: DiscordMember) {
const userConnections = user ? await supabase.from('users')
.select<string, {
connections: {
connection: {
sub: string
type: UserConnectionType
}
}[]
}>('connections:mellow_user_server_connections ( connection:user_connections ( sub, type ) )')
.eq('id', user.id)
.eq('user_connections.type', 2)
.limit(1)
.maybeSingle()
.then(response => {
if (response.error)
console.error(response.error);
return response.data?.user_connections[0];
if (!response.data)
return [];
return response.data?.connections.map(item => item.connection);
})
: null;
if (!userBind)
return editOriginalResponse(token, {
content: t('sync.signup'),
components: [{
type: 1,
components: [{
url: 'https://discord.com/api/oauth2/authorize?client_id=1068554282481229885&redirect_uri=https%3A%2F%2Fapi.hakumi.cafe%2Fv1%2Fauth%2Fcallback%2F0&response_type=code&scope=identify&state=roblox',
type: 2,
style: 5,
label: t('common:action.continue')
}]
}]
});
: [];

const robloxId = syncAs ?? userBind?.sub as string;
const robloxId = userConnections?.find(item => item.type === UserConnectionType.Roblox)?.sub;
const [ruser]: RobloxProfile[] = robloxId ? await ROBLOX_API.users.getProfiles([robloxId], ['names.username', 'names.combinedName']) : [undefined];
const serverLinks = await getServerProfileSyncingActions(serverId);
const discordServer = (await getDiscordServer(serverId))!;
Expand Down Expand Up @@ -99,16 +86,15 @@ export async function verify(t: TranslateFn, executor: DiscordMember | null, ser
role_changes: roleChanges,
discord_member_id: member.user.id,
discord_server_id: serverId,
relevant_user_connections: [{
sub: robloxId.toString(),
type: UserConnectionType.Roblox
}]
relevant_user_connections: userConnections
}]);
}

const removed = banned || kicked;
const addedRoles = roleChanges.filter(item => item.type === RoleChangeType.Added);
const removedRoles = roleChanges.filter(item => item.type === RoleChangeType.Removed);

const actionConnections = [...new Set(serverLinks.map(item => item.requirements.map(item => MELLOW_SYNC_REQUIREMENT_CONNECTIONS[item.type]!).filter(i => i)).flat())];
return editOriginalResponse(token, {
embeds: profileChanged ? [{
fields: [
Expand All @@ -124,7 +110,7 @@ export async function verify(t: TranslateFn, executor: DiscordMember | null, ser
}] : []
]
}] : [],
content: removed ? t('sync.complete.removed') + t(`sync.complete.removed.${banned ? 0 : 1}`) : t(`sync.complete.${profileChanged}`) + (roleChanges.length ? nicknameChanged ? t('sync.complete.true.2') : t('sync.complete.true.0') : nicknameChanged ? t('sync.complete.true.1') : ''),
content: removed ? t('sync.complete.removed') + t(`sync.complete.removed.${banned ? 0 : 1}`) : t(`sync.complete.${profileChanged}`) + (roleChanges.length ? nicknameChanged ? t('sync.complete.true.2') : t('sync.complete.true.0') : nicknameChanged ? t('sync.complete.true.1') : '') + (userConnections.length >= actionConnections.length ? '' : t('sync.complete.missing_connections', [serverId])),
components: []
});
}
15 changes: 15 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { UserConnectionType, MellowProfileSyncActionRequirementType } from './enums.ts';
export const MELLOW_SYNC_REQUIREMENT_CONNECTIONS: Record<MellowProfileSyncActionRequirementType, UserConnectionType | null> = {
[MellowProfileSyncActionRequirementType.RobloxHaveConnection]: UserConnectionType.Roblox,
[MellowProfileSyncActionRequirementType.RobloxHaveGroupRole]: UserConnectionType.Roblox,
[MellowProfileSyncActionRequirementType.RobloxHaveGroupRankInRange]: UserConnectionType.Roblox,
[MellowProfileSyncActionRequirementType.RobloxInGroup]: UserConnectionType.Roblox,
[MellowProfileSyncActionRequirementType.RobloxBeFriendsWith]: UserConnectionType.Roblox,
[MellowProfileSyncActionRequirementType.MeetOtherAction]: null,
[MellowProfileSyncActionRequirementType.HAKUMIInTeam]: null,
[MellowProfileSyncActionRequirementType.SteamInGroup]: null,
[MellowProfileSyncActionRequirementType.RobloxHaveAsset]: UserConnectionType.Roblox,
[MellowProfileSyncActionRequirementType.RobloxHaveBadge]: UserConnectionType.Roblox,
[MellowProfileSyncActionRequirementType.RobloxHavePass]: UserConnectionType.Roblox,
[MellowProfileSyncActionRequirementType.GitHubInOrganisation]: UserConnectionType.GitHub
};
7 changes: 4 additions & 3 deletions src/localisation/locales/en-US/command.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
"pokemon.embed.summary": "it is a {{0.types.0.type.name}} type with {{0.abilities.length}} abilities",

"sync": "sync",
"sync.summary": "Sync your Server Profile with your Roblox Account.",
"sync.signup": "## Connect Roblox Account\nYou must be new to mellow, click Continue to connect your Roblox Account.\n~~This message will update with your server profile status after you link a Roblox Account.~~\nThe functionality above is currently under maintenance, please execute this command again upon completion.",
"sync.summary": "Sync your server profile.",
"sync.signup": "## Hello, welcome to the server!\nYou appear to be new to mellow, this server uses mellow to sync member profiles with external services, such as Roblox.\nIf you would like to continue, please continue [here](https://discord.com/api/oauth2/authorize?client_id=1068554282481229885&redirect_uri=https%3A%2F%2Fapi.hakumi.cafe%2Fv1%2Fauth%2Fcallback%2F0&response_type=code&scope=identify&state=mlw{{1}}mlw), don't worry, it shouldn't take long!",
"sync.complete.true": "## Server Profile Updated\n",
"sync.complete.true.0": "Your roles have been updated.",
"sync.complete.true.1": "Your nickname has been updated.",
Expand All @@ -26,6 +26,7 @@
"sync.complete.removed2": "has been removed from this server",
"sync.complete.removed.0": "This member has been banned for meeting the requirements of a ban action.",
"sync.complete.removed.1": "This member has been kicked for meeting the requirements of a kick action.",
"sync.complete.missing_connections": "\n\n### You're missing connections\nYou haven't given this server access to all connections yet, change that [here](https://hakumi.cafe/mellow/server/{{0}}/onboarding)!",
"sync.no_server": "## Cannot Sync Profile\nThis server has not been set-up with mellow yet, ",

"forcesync": "forcesync",
Expand All @@ -42,7 +43,7 @@
"setup.summary": "Connect this Discord Server to mellow.",
"setup.signup": "## Account required\nBefore you can continue, you need to [sign-up](https://hakumi.cafe/sign-up) for a HAKUMI Account.\nAfter that, if you did not sign-up with Discord, please connect your account [here](https://hakumi.cafe/settings/account/connections).\nExecute this command again after completing these instructions.",
"setup.exists": "## Server already connected\nThis server is already connected to mellow, view it [here](https://hakumi.cafe/mellow/server/{{0}}/settings).",
"setup.done": "## Server connected\nThis server is now connected to mellow!\nConfigure it online [here](https://hakumi.cafe/mellow/server/{{0}}/settings).",
"setup.done": "## Server connected\nThis server is now connected to mellow!\nConfigure it online [here](https://hakumi.cafe/mellow/server/{{0}}/settings).\n\nIf you haven't already, and you plan for me to manage members' roles, you may need to position one of my roles at very top of your server.",

"whois": "profile",
"whois.summary": "Request someone's HAKUMI Profile.",
Expand Down
7 changes: 4 additions & 3 deletions src/routes/signup-finish.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getFixedT } from 'i18next';

import { verify } from '../commands/roblox/sync.ts';
import { verify } from '../commands/syncing/sync.ts';
import { MELLOW_KEY } from '../util/constants.ts';
import { getServerMember } from '../discord.ts';
import { getUser, supabase, getServer } from '../database.ts';
Expand All @@ -25,9 +25,10 @@ export default async (request: Request) => {

const t = getFixedT(data.locale, 'command');
const server = await getServer(data.server_id);
await verify(t, null, server!, data.interaction_token, data.server_id, user, member);
await verify(t, null, server!, data.interaction_token, data.server_id, user, member)
.catch(console.error);

await supabase.from('mellow_signups').delete().eq('user_id', discordId);

return new Response('great!', { status: 200 });
return new Response();
}

0 comments on commit 89940ac

Please sign in to comment.