@mastra/discord 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +63 -0
- package/src/Discord.test.ts +55 -0
- package/src/assets/discord.png +0 -0
- package/src/index.ts +201 -0
- package/src/openapi-components.ts +31769 -0
- package/src/openapi-paths.ts +15861 -0
- package/src/openapi.ts +23784 -0
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mastra/discord",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/mylib.esm.js",
|
|
7
|
+
"typings": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"src"
|
|
11
|
+
],
|
|
12
|
+
"husky": {
|
|
13
|
+
"hooks": {
|
|
14
|
+
"pre-commit": "dts lint"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=20 <22"
|
|
19
|
+
},
|
|
20
|
+
"size-limit": [
|
|
21
|
+
{
|
|
22
|
+
"path": "dist/mylib.cjs.production.min.js",
|
|
23
|
+
"limit": "10 KB"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"path": "dist/mylib.esm.js",
|
|
27
|
+
"limit": "10 KB"
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@jest/globals": "^29.7.0",
|
|
32
|
+
"@rollup/plugin-image": "^3.0.3",
|
|
33
|
+
"@size-limit/preset-small-lib": "^11.1.4",
|
|
34
|
+
"@tsconfig/recommended": "^1.0.7",
|
|
35
|
+
"@types/jest": "^29.5.12",
|
|
36
|
+
"@types/lodash": "^4.17.7",
|
|
37
|
+
"@types/node": "^22.1.0",
|
|
38
|
+
"dts-cli": "^2.0.5",
|
|
39
|
+
"husky": "^9.1.4",
|
|
40
|
+
"jest": "^29.7.0",
|
|
41
|
+
"size-limit": "^11.1.4",
|
|
42
|
+
"ts-jest": "^29.2.4",
|
|
43
|
+
"tslib": "^2.6.3",
|
|
44
|
+
"typescript": "^5.5.4"
|
|
45
|
+
},
|
|
46
|
+
"keywords": [],
|
|
47
|
+
"author": "",
|
|
48
|
+
"license": "ISC",
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"fets": "*",
|
|
51
|
+
"zod": "^3.23.8",
|
|
52
|
+
"@mastra/core": "0.1.0"
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"analyze": "size-limit --why",
|
|
56
|
+
"build": "dts build",
|
|
57
|
+
"build:dev": "dts watch",
|
|
58
|
+
"lint": "dts lint",
|
|
59
|
+
"size": "size-limit",
|
|
60
|
+
"start": "dts watch",
|
|
61
|
+
"test": "jest"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {
|
|
2
|
+
describe,
|
|
3
|
+
it,
|
|
4
|
+
beforeAll,
|
|
5
|
+
afterAll, //expect
|
|
6
|
+
} from '@jest/globals';
|
|
7
|
+
import { Framework } from '@mastra/core';
|
|
8
|
+
|
|
9
|
+
import { DiscordIntegration } from '.';
|
|
10
|
+
|
|
11
|
+
// We need to OAuth from admin
|
|
12
|
+
|
|
13
|
+
const CLIENT_ID = process.env.CLIENT_ID!;
|
|
14
|
+
const CLIENT_SECRET = process.env.CLIENT_SECRET!;
|
|
15
|
+
|
|
16
|
+
const dbUri = process.env.DB_URL!;
|
|
17
|
+
const connectionId = process.env.CONNECTION_ID!;
|
|
18
|
+
|
|
19
|
+
const integrationName = 'DISCORD';
|
|
20
|
+
|
|
21
|
+
const integrationFramework = Framework.init({
|
|
22
|
+
name: 'TestFramework',
|
|
23
|
+
integrations: [
|
|
24
|
+
new DiscordIntegration({
|
|
25
|
+
config: {
|
|
26
|
+
CLIENT_ID,
|
|
27
|
+
CLIENT_SECRET,
|
|
28
|
+
undefined,
|
|
29
|
+
},
|
|
30
|
+
}),
|
|
31
|
+
],
|
|
32
|
+
systemApis: [],
|
|
33
|
+
systemEvents: {},
|
|
34
|
+
db: {
|
|
35
|
+
provider: 'postgres',
|
|
36
|
+
uri: dbUri,
|
|
37
|
+
},
|
|
38
|
+
systemHostURL: 'http://localhost:3000',
|
|
39
|
+
routeRegistrationPath: '/api/mastra',
|
|
40
|
+
blueprintDirPath: '',
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
//const integration = integrationFramework.getIntegration(integrationName) as DiscordIntegration
|
|
44
|
+
|
|
45
|
+
describe('discord', () => {
|
|
46
|
+
beforeAll(async () => {});
|
|
47
|
+
|
|
48
|
+
it('should 200 on some apis', async () => {
|
|
49
|
+
//const client = await integration.getApiClient({ connectionId });
|
|
50
|
+
//const response = await client['/2010-04-01/Accounts.json'].get();
|
|
51
|
+
//expect(response.status).toBe(200);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
afterAll(async () => {});
|
|
55
|
+
});
|
|
Binary file
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { Integration, OpenAPI, IntegrationCredentialType, IntegrationAuth } from '@mastra/core';
|
|
2
|
+
import { createClient, type OASClient, type NormalizeOAS } from 'fets';
|
|
3
|
+
|
|
4
|
+
// @ts-ignore
|
|
5
|
+
import DiscordLogo from './assets/discord.png';
|
|
6
|
+
import { openapi } from './openapi';
|
|
7
|
+
import { components } from './openapi-components';
|
|
8
|
+
import { paths } from './openapi-paths';
|
|
9
|
+
|
|
10
|
+
type DiscordConfig = {
|
|
11
|
+
CLIENT_ID: string;
|
|
12
|
+
CLIENT_SECRET: string;
|
|
13
|
+
|
|
14
|
+
[key: string]: any;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export class DiscordIntegration extends Integration {
|
|
18
|
+
availableScopes = [
|
|
19
|
+
{
|
|
20
|
+
key: `activities.read`,
|
|
21
|
+
description: `allows your app to fetch data from a user's "Now Playing/Recently Played" list - requires Discord approval`,
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
key: `activities.write`,
|
|
25
|
+
description: `allows your app to update a user's activity - requires Discord approval (NOT REQUIRED FOR GAMESDK ACTIVITY MANAGER)`,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
key: `applications.builds.read`,
|
|
29
|
+
description: `allows your app to read build data for a user's applications`,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
key: `applications.builds.upload`,
|
|
33
|
+
description: `allows your app to upload/update builds for a user's applications - requires Discord approval`,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
key: `applications.commands`,
|
|
37
|
+
description: `allows your app to use commands in a guild`,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
key: `applications.commands.permissions.update`,
|
|
41
|
+
description: `allows your app to update permissions for its commands in a guild a user has permissions to`,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
key: `applications.entitlements`,
|
|
45
|
+
description: `allows your app to read entitlements for a user's applications`,
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
key: `applications.store.update`,
|
|
49
|
+
description: `allows your app to read and update store data (SKUs, store listings, achievements, etc.) for a user's applications`,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
key: `bot`,
|
|
53
|
+
description: `for oauth2 bots, this puts the bot in the user's selected guild by default`,
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
key: `connections`,
|
|
57
|
+
description: `allows /users/@me/connections to return linked third-party accounts`,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
key: `dm_channels.read`,
|
|
61
|
+
description: `allows your app to see information about the user's DMs and group DMs - requires Discord approval`,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
key: `email`,
|
|
65
|
+
description: `enables /users/@me to return an email`,
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
key: `gdm.join`,
|
|
69
|
+
description: `allows your app to join users to a group dm`,
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
key: `guilds`,
|
|
73
|
+
description: `allows /users/@me/guilds to return basic information about all of a user's guilds`,
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
key: `guilds.join`,
|
|
77
|
+
description: `allows /guilds/{guild.id}/members/{user.id} to be used for joining users to a guild`,
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
key: `guilds.members.read`,
|
|
81
|
+
description: `allows /users/@me/guilds/{guild.id}/member to return a user's member information in a guild`,
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
key: `identify`,
|
|
85
|
+
description: `allows /users/@me without email`,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
key: `messages.read`,
|
|
89
|
+
description: `for local rpc server api access, this allows you to read messages from all client channels (otherwise restricted to channels/guilds your app creates)`,
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
key: `relationships.read`,
|
|
93
|
+
description: `allows your app to know a user's friends and implicit relationships - requires Discord approval`,
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
key: `rpc`,
|
|
97
|
+
description: `for local rpc server access, this allows you to control a user's local Discord client - requires Discord approval`,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
key: `rpc.activities.write`,
|
|
101
|
+
description: `for local rpc server access, this allows you to update a user's activity - requires Discord approval`,
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
key: `rpc.notifications.read`,
|
|
105
|
+
description: `for local rpc server access, this allows you to receive notifications pushed out to the user - requires Discord approval`,
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
key: `rpc.screenshare.read`,
|
|
109
|
+
description: `for local rpc server access, this allows you to read a user's screenshare status- requires Discord approval`,
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
key: `rpc.screenshare.write`,
|
|
113
|
+
description: `for local rpc server access, this allows you to update a user's screenshare settings- requires Discord approval`,
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
key: `rpc.video.read`,
|
|
117
|
+
description: `for local rpc server access, this allows you to read a user's video status - requires Discord approval`,
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
key: `rpc.video.write`,
|
|
121
|
+
description: `for local rpc server access, this allows you to update a user's video settings - requires Discord approval`,
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
key: `rpc.voice.read`,
|
|
125
|
+
description: `for local rpc server access, this allows you to read a user's voice settings and listen for voice events - requires Discord approval`,
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
key: `rpc.voice.write`,
|
|
129
|
+
description: `for local rpc server access, this allows you to update a user's voice settings - requires Discord approval`,
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
key: `voice`,
|
|
133
|
+
description: `allows your app to connect to voice on user's behalf and see all the voice members - requires Discord approval`,
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
key: `webhook.incoming`,
|
|
137
|
+
description: `this generates a webhook that is returned in the oauth token response for authorization code grants`,
|
|
138
|
+
},
|
|
139
|
+
];
|
|
140
|
+
|
|
141
|
+
constructor({ config }: { config: DiscordConfig }) {
|
|
142
|
+
super({
|
|
143
|
+
...config,
|
|
144
|
+
authType: IntegrationCredentialType.OAUTH,
|
|
145
|
+
name: 'DISCORD',
|
|
146
|
+
logoUrl: DiscordLogo,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
getOpenApiSpec() {
|
|
151
|
+
return { paths, components } as unknown as OpenAPI;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
getApiClient = async ({ connectionId }: { connectionId: string }): Promise<OASClient<NormalizeOAS<openapi>>> => {
|
|
155
|
+
const connection = await this.dataLayer?.getConnection({ name: this.name, connectionId });
|
|
156
|
+
|
|
157
|
+
if (!connection) {
|
|
158
|
+
throw new Error(`Connection not found for connectionId: ${connectionId}`);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const authenticator = this.getAuthenticator();
|
|
162
|
+
const { accessToken } = await authenticator.getAuthToken({ k_id: connection.id });
|
|
163
|
+
|
|
164
|
+
const client = createClient<NormalizeOAS<openapi>>({
|
|
165
|
+
endpoint: `https://discord.com/api/v10`,
|
|
166
|
+
globalParams: {
|
|
167
|
+
headers: {
|
|
168
|
+
Authorization: `Bearer ${accessToken}`,
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
return client as any;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
registerEvents() {
|
|
177
|
+
this.events = {};
|
|
178
|
+
return this.events;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
getAuthenticator() {
|
|
182
|
+
return new IntegrationAuth({
|
|
183
|
+
dataAccess: this.dataLayer!,
|
|
184
|
+
// @ts-ignore
|
|
185
|
+
onConnectionCreated: () => {
|
|
186
|
+
// TODO
|
|
187
|
+
},
|
|
188
|
+
config: {
|
|
189
|
+
INTEGRATION_NAME: this.name,
|
|
190
|
+
AUTH_TYPE: this.config.authType,
|
|
191
|
+
CLIENT_ID: this.config.CLIENT_ID,
|
|
192
|
+
CLIENT_SECRET: this.config.CLIENT_SECRET,
|
|
193
|
+
REDIRECT_URI: this.config.REDIRECT_URI || this.corePresets.redirectURI,
|
|
194
|
+
SERVER: `https://discord.com/api/v10`,
|
|
195
|
+
AUTHORIZATION_ENDPOINT: `discord.com/oauth2/authorize`,
|
|
196
|
+
TOKEN_ENDPOINT: `https://discord.com/api/oauth2/token`,
|
|
197
|
+
SCOPES: this.config.SCOPES || [],
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|