feat: Discord + Instagram integrations
Discord Bot API
- New client: src/clients/discord.ts
- Tools: discord_get_me, discord_get_guilds, discord_get_channels, discord_send_message, discord_get_messages
- REST endpoints: GET /api/discord/me, /api/discord/guilds, /api/discord/channels, /api/discord/messages, POST /api/discord/message
- Multi-account env var: DISCORD_{ACCOUNT}_BOT_TOKEN
Instagram Graph API
- New client: src/clients/instagram.ts
- Tools: instagram_get_profile, instagram_get_media, instagram_create_post
- REST endpoints: GET /api/instagram/profile, /api/instagram/media, POST /api/instagram/post
- Multi-account env vars: INSTAGRAM_{ACCOUNT}_ACCESS_TOKEN, INSTAGRAM_{ACCOUNT}_BUSINESS_ACCOUNT_ID
Total tools: 32
This commit is contained in:
101
src/clients/discord.ts
Normal file
101
src/clients/discord.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
const DISCORD_API_BASE = 'https://discord.com/api/v10';
|
||||
|
||||
function getToken(account: string): string {
|
||||
const envKey = `DISCORD_${account.toUpperCase()}_BOT_TOKEN`;
|
||||
return process.env[envKey] ?? '';
|
||||
}
|
||||
|
||||
async function discordRequest(
|
||||
token: string,
|
||||
endpoint: string,
|
||||
method: 'GET' | 'POST' = 'GET',
|
||||
body?: unknown
|
||||
) {
|
||||
const url = `${DISCORD_API_BASE}${endpoint}`;
|
||||
const res = await fetch(url, {
|
||||
method,
|
||||
headers: {
|
||||
'Authorization': `Bot ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: body ? JSON.stringify(body) : undefined,
|
||||
signal: AbortSignal.timeout(15000),
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
const error = await res.text();
|
||||
throw new Error(`Discord API error (${res.status}): ${error}`);
|
||||
}
|
||||
|
||||
return res.json();
|
||||
}
|
||||
|
||||
export async function getMe(args: { account?: string }): Promise<{
|
||||
id: string;
|
||||
username: string;
|
||||
bot: boolean;
|
||||
}> {
|
||||
const token = getToken(args.account ?? 'default');
|
||||
if (!token) {
|
||||
throw new Error('Missing Discord credentials. Set DISCORD_{ACCOUNT}_BOT_TOKEN');
|
||||
}
|
||||
return discordRequest(token, '/users/@me');
|
||||
}
|
||||
|
||||
export async function getGuilds(args: { account?: string }): Promise<Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
icon?: string;
|
||||
}>> {
|
||||
const token = getToken(args.account ?? 'default');
|
||||
if (!token) {
|
||||
throw new Error('Missing Discord credentials. Set DISCORD_{ACCOUNT}_BOT_TOKEN');
|
||||
}
|
||||
return discordRequest(token, '/users/@me/guilds');
|
||||
}
|
||||
|
||||
export async function getChannels(args: { guild_id: string; account?: string }): Promise<Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
type: number;
|
||||
}>> {
|
||||
const token = getToken(args.account ?? 'default');
|
||||
if (!token) {
|
||||
throw new Error('Missing Discord credentials. Set DISCORD_{ACCOUNT}_BOT_TOKEN');
|
||||
}
|
||||
return discordRequest(token, `/guilds/${args.guild_id}/channels`);
|
||||
}
|
||||
|
||||
export async function sendMessage(args: {
|
||||
channel_id: string;
|
||||
content: string;
|
||||
account?: string;
|
||||
}): Promise<{ id: string; channel_id: string }> {
|
||||
const token = getToken(args.account ?? 'default');
|
||||
if (!token) {
|
||||
throw new Error('Missing Discord credentials. Set DISCORD_{ACCOUNT}_BOT_TOKEN');
|
||||
}
|
||||
|
||||
return discordRequest(token, `/channels/${args.channel_id}/messages`, 'POST', {
|
||||
content: args.content,
|
||||
});
|
||||
}
|
||||
|
||||
export async function getMessages(args: {
|
||||
channel_id: string;
|
||||
limit?: number;
|
||||
account?: string;
|
||||
}): Promise<Array<{
|
||||
id: string;
|
||||
content: string;
|
||||
author: { username: string; id: string };
|
||||
timestamp: string;
|
||||
}>> {
|
||||
const token = getToken(args.account ?? 'default');
|
||||
if (!token) {
|
||||
throw new Error('Missing Discord credentials. Set DISCORD_{ACCOUNT}_BOT_TOKEN');
|
||||
}
|
||||
|
||||
const limit = args.limit ?? 10;
|
||||
return discordRequest(token, `/channels/${args.channel_id}/messages?limit=${limit}`);
|
||||
}
|
||||
Reference in New Issue
Block a user