Add support for bot login.

Add flags + bot information for users.
This commit is contained in:
Paul
2021-08-12 12:00:07 +01:00
parent f96059c3ff
commit 343d6e3992
11 changed files with 169 additions and 79 deletions
+2 -1
View File
@@ -1,3 +1,4 @@
API_URL=https://api.revolt.chat
EMAIL=1@example.com
PASSWORD=password
PASSWORD=password
BOT_TOKEN=abc
+5 -1
View File
@@ -21,7 +21,11 @@ client.on('message', async message => {
}
});
// Either create a new session:
// To login as a bot:
client.loginBot('..');
// To login as a user,
// either create a new session:
client.login({ email: '..', password: '..' });
// Or use an existing session:
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "revolt.js",
"version": "5.0.0-alpha.21",
"version": "5.0.1-alpha.0",
"main": "dist/index.js",
"repository": "https://gitlab.insrt.uk/revolt/revolt.js",
"author": "Paul Makles <insrt.uk>",
@@ -30,7 +30,7 @@
"in-publish": "^2.0.1",
"jsdoc-babel": "^0.5.0",
"node-fetch": "^2.6.1",
"revolt-api": "0.5.1-alpha.22",
"revolt-api": "^0.5.2-alpha.0",
"rimraf": "^3.0.2",
"typedoc": "^0.21.4",
"typescript": "^4.2.3"
+27 -11
View File
@@ -63,7 +63,7 @@ export type FileArgs = [ options?: SizeOptions, allowAnimation?: boolean, fallba
export class Client extends EventEmitter {
heartbeat: number;
session?: Session;
session?: Session | string;
user?: User;
websocket: WebSocketClient;
@@ -217,10 +217,16 @@ export class Client extends EventEmitter {
await this.connect();
}
private $generateHeaders(session: Session | undefined = this.session) {
return {
'x-user-id': session?.user_id,
'x-session-token': session?.session_token
private $generateHeaders(session: Session | string | undefined = this.session) {
if (typeof session === 'string') {
return {
'x-bot-token': session
}
} else {
return {
'x-user-id': session?.user_id,
'x-session-token': session?.session_token
}
}
}
@@ -230,24 +236,35 @@ export class Client extends EventEmitter {
* @returns An onboarding function if onboarding is required, undefined otherwise
*/
async login(details: Route<'POST', '/auth/login'>["data"]) {
this.fetchConfiguration();
await this.fetchConfiguration();
this.session = await this.req('POST', '/auth/login', details);
return await this.$connect();
}
/**
* Use an existing session to log into REVOLT.
* Use an existing session to log into Revolt.
* @param session Session data object
* @returns An onboarding function if onboarding is required, undefined otherwise
*/
async useExistingSession(session: Session) {
this.fetchConfiguration();
await this.fetchConfiguration();
await this.request('GET', '/auth/check', { headers: this.$generateHeaders(session) });
this.session = session;
return await this.$connect();
}
/**
* Log in as a bot.
* @param token Bot token
*/
async loginBot(token: string) {
await this.fetchConfiguration();
this.session = token;
this.Axios.defaults.headers = this.$generateHeaders();
return await this.websocket.connect();
}
// Check onboarding status and connect to notifications service.
private async $connect() {
this.Axios.defaults.headers = this.$generateHeaders();
@@ -380,9 +397,8 @@ export class Client extends EventEmitter {
* @returns Modified plain text
*/
markdownToText(source: string) {
console.warn('revolt.js: Client.markdownToText() is deprecated, please stop using it.');
return source
/*.replace(
.replace(
RE_MENTIONS,
(sub: string, ...args: any[]) => {
const id = args[0],
@@ -394,7 +410,7 @@ export class Client extends EventEmitter {
return sub;
}
)*/
)
.replace(
RE_SPOILER,
'<spoiler>'
+67 -1
View File
@@ -1,3 +1,4 @@
import type { Bot, PublicBot } from 'revolt-api/types/Bots';
import type { RevoltConfiguration } from 'revolt-api/types/Core';
import type { UserSettings, ChannelUnread } from 'revolt-api/types/Sync';
import type { RetrievedInvite, ServerInvite } from 'revolt-api/types/Invites'
@@ -144,7 +145,8 @@ type Routes =
route: `/onboard/hello`,
data: undefined,
response: {
onboarding: boolean
onboarding: boolean,
id?: string
}
}
| {
@@ -600,6 +602,8 @@ type Routes =
data: {
name?: string,
colour?: string,
hoist?: boolean,
rank?: number,
remove?: RemoveRoleField
},
response: undefined
@@ -623,6 +627,68 @@ type Routes =
},
response: undefined
}
/**
* Bots
*/
| {
// Create Bot
method: 'POST',
route: `/bots/create`,
data: {
name: string
},
response: Bot
}
| {
// Fetch Owned Bots
method: 'GET',
route: `/bots/@me`,
data: undefined,
response: Bot[]
}
| {
// Fetch Bot
method: 'GET',
route: `/bots/${Id}`,
data: undefined,
response: Bot
}
| {
// Edit Bot
method: 'PATCH',
route: `/bots/${Id}`,
data: {
name?: string,
public?: boolean,
interactionsURL?: string,
remove?: 'InteractionsURL'
},
response: undefined
}
| {
// Delete Bot
method: 'DELETE',
route: `/bots/${Id}`,
data: undefined,
response: undefined
}
| {
// Fetch Public Bot
method: 'GET',
route: `/bots/${Id}/invite`,
data: undefined,
response: PublicBot
}
| {
// Invite Public Bot
method: 'POST',
route: `/bots/${Id}/invite`,
data: (
{ server: string } |
{ group: string }
),
response: undefined
}
/**
* Invites
*/
+1 -1
View File
@@ -1,7 +1,7 @@
export * from './Client';
export { UserPermission, ChannelPermission, ServerPermission } from './api/permissions';
export const LIBRARY_VERSION = '5.0.0-alpha.21';
export const LIBRARY_VERSION = '5.0.1-alpha.0';
export const defaultConfig = {
apiURL: 'https://api.revolt.chat',
+8 -1
View File
@@ -1,4 +1,4 @@
import type { Status, User as UserI } from 'revolt-api/types/Users';
import type { BotInformation, Status, User as UserI } from 'revolt-api/types/Users';
import type { RemoveUserField, Route } from '../api/routes';
import type { Attachment } from 'revolt-api/types/Autumn';
@@ -9,6 +9,7 @@ import { U32_MAX, UserPermission } from '../api/permissions';
import { toNullable, Nullable } from '../util/null';
import Collection from './Collection';
import { Client, FileArgs, SYSTEM_USER_ID } from '..';
import _ from 'lodash';
enum RelationshipStatus {
None = "None",
@@ -31,6 +32,8 @@ export class User {
status: Nullable<Status>;
relationship: Nullable<RelationshipStatus>;
online: Nullable<boolean>;
flags: Nullable<number>;
bot: Nullable<BotInformation>;
constructor(client: Client, data: UserI) {
this.client = client;
@@ -43,6 +46,8 @@ export class User {
this.status = toNullable(data.status);
this.relationship = toNullable(data.relationship);
this.online = toNullable(data.online);
this.flags = toNullable(data.flags);
this.bot = toNullable(data.bot);
makeAutoObservable(this, {
_id: false,
@@ -81,6 +86,8 @@ export class User {
apply("status");
apply("relationship");
apply("online");
apply("flags");
apply("bot");
}
/**
+43 -54
View File
@@ -5,63 +5,52 @@ config();
// To run this example, you need to have a local Revolt server running and an existing account.
// Copy and paste `.env.example` to `.env` and edit accordingly.
let client = new Client({
apiURL: process.env.API_URL
});
client.on('ready', async () => {
console.info(`Logged in as ${client.user!.username}!`);
[...client.users.values()].forEach(x => console.info(`perm against ${x.username} is ${x.permission}`));
[...client.servers.values()].forEach(x => console.info(`perm against ${x.name} is ${x.permission}`));
[...client.channels.values()].forEach(x => console.info(`perm against ${x.name} is ${x.permission}`));
setTimeout(() => {
client.users.edit({
remove: 'Avatar'
});
}, 10_000);
});
client.on('message', async message => {
if (message.content === 'sus') {
message.channel!.sendMessage('sus!');
}
});
import { autorun } from 'mobx';
autorun(() => {
console.log(`
BATCH UPDATE
----
srv ids: ${[...client.servers.values()].map(x => x._id).length}
chn ids: ${[...client.channels.values()].map(x => x._id).length}
usr ids: ${[...client.users.values()].map(x => x._id).length}
msg ids: ${[...client.messages.values()].map(x => x._id).length}
mbr ids: ${[...client.members.values()].map(x => x._id).length}
----`);
});
client.once('ready', () => {
autorun(() => {
console.log(`Changed username to ${client.user!.username}!`);
function user() {
let client = new Client({
apiURL: process.env.API_URL
});
autorun(() => {
console.log(`Avatar URL: ${client.user!.generateAvatarURL()}!`);
client.on('ready', async () => {
console.info(`Logged in as ${client.user!.username}!`);
});
let server_id = [...client.servers.keys()][0];
autorun(() => {
console.log(`
Server
------
Name: ${client.servers.get(server_id)!.name}
`);
client.on('message', async message => {
if (message.content === 'sus') {
message.channel!.sendMessage('sus!');
} else if (message.content === 'bot') {
let bot = await client.req('POST', '/bots/create', { name: 'basedbot3' });
message.channel!.sendMessage(JSON.stringify(bot));
} else if (message.content === 'my bots') {
message.channel!.sendMessage(JSON.stringify(
await client.req('GET', '/bots/@me')
));
} else if (message.content === 'join bot') {
await client.req('POST', `/bots/01FCV7DCMRD9MT3JBYT5VEKVRD/invite` as '/bots/id/invite',
{ group: message.channel_id });
// { server: '01FATEGMHEE2M1QGPA65NS6V8K' });
}
});
});
client.login({ email: process.env.EMAIL as string, password: process.env.PASSWORD as string })
// client.useExistingSession({ user_id: process.env.USER_ID as string, session_token: process.env.SESSION_TOKEN as string });
client.login({ email: process.env.EMAIL as string, password: process.env.PASSWORD as string })
}
function bot() {
let client = new Client({
apiURL: process.env.API_URL
});
client.on('ready', async () => {
console.info(`Logged in as ${client.user!.username}! [${client.user!._id}]`);
});
client.on('message', async message => {
if (message.content === 'sus') {
message.channel!.sendMessage('sus!');
}
});
client.loginBot(process.env.BOT_TOKEN as string)
}
// user();
bot();
+9 -3
View File
@@ -3,9 +3,9 @@ import { backOff } from 'exponential-backoff';
import { Client, SYSTEM_USER_ID } from '..';
import { ServerboundNotification, ClientboundNotification } from './notifications';
import { Session } from 'revolt-api/types/Auth';
import { runInAction } from 'mobx';
import { Role } from 'revolt-api/types/Servers';
export class WebSocketClient {
@@ -78,7 +78,11 @@ export class WebSocketClient {
this.ws = ws;
ws.onopen = () => {
this.send({ type: 'Authenticate', ...this.client.session as Session });
if (typeof this.client.session === 'string') {
this.send({ type: 'Authenticate', token: this.client.session! });
} else {
this.send({ type: 'Authenticate', ...this.client.session! });
}
};
let timeouts: Record<string, any> = {};
@@ -123,7 +127,9 @@ export class WebSocketClient {
}
});
this.client.user = this.client.users.get(this.client.session!.user_id)!;
this.client.user = this.client.users.get(
packet.users.find(x => x.relationship === 'User')!._id
)!;
this.client.emit('ready');
this.ready = true;
+1
View File
@@ -14,6 +14,7 @@ export type ServerboundNotification = (
{ type: 'Ping', time: number } |
{ type: 'Pong', time: number } |
({ type: 'Authenticate' } & Session) |
({ type: 'Authenticate', token: string }) |
({ type: 'BeginTyping', channel: string }) |
({ type: 'EndTyping', channel: string })
);
+4 -4
View File
@@ -2014,10 +2014,10 @@ ret@~0.1.10:
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==
revolt-api@0.5.1-alpha.22:
version "0.5.1-alpha.22"
resolved "https://registry.yarnpkg.com/revolt-api/-/revolt-api-0.5.1-alpha.22.tgz#ba60bad959e90a1ba75864d359b7d91b438c79ce"
integrity sha512-U97JcetsdzjZDfn/RBxLWuFtEevwdaAvT7hu6EYGxXr/8uYzNs7/MuiPDsom3KRaft443AL6Upswgsc7idntBQ==
revolt-api@^0.5.2-alpha.0:
version "0.5.2-alpha.0"
resolved "https://registry.yarnpkg.com/revolt-api/-/revolt-api-0.5.2-alpha.0.tgz#a41f44ee38622636c9b5b5843f9e2798a79f00d3"
integrity sha512-VI/o4nQTPXrDCVdFpZFfZfj7Q4nunj62gftdmYJtuSmXx+6eN2Nve7QQZjNt6UIH6Dc/IDgiFDcBdafBF9YXug==
rimraf@^3.0.2:
version "3.0.2"