feat: Slack platform + Claude-powered chat support widget
- Add Slack as customer-facing messaging platform (client, 4 MCP tools, dashboard card) - Add /api/chat endpoint powered by Claude Haiku with SquareMCP system prompt - Add embeddable chat-widget.js injected into all 3 sites (docs, app, www) - Add ANTHROPIC_API_KEY, serve product/ as static files - Update Platform type to include slack Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
86
src/tools.ts
86
src/tools.ts
@@ -14,6 +14,7 @@ import { searchTweets, getUserProfile, getUserTweets, createTweet, uploadVideoAn
|
||||
import { getUserProfile as getTikTokProfile, getCreatorInfo, createVideo, getVideoStatus } from './clients/tiktok.js';
|
||||
import { getMe as getSnapchatMe, createSnap, getAdAccounts } from './clients/snapchat.js';
|
||||
import { getPage, getPosts, createPost as createFacebookPost, createPhotoPost, createVideoPost as createFacebookVideoPost } from './clients/facebook.js';
|
||||
import { getMe as getSlackMe, getChannels as getSlackChannels, sendMessage as sendSlackMessage, getMessages as getSlackMessages } from './clients/slack.js';
|
||||
|
||||
const ACCOUNT_PARAM = {
|
||||
account: {
|
||||
@@ -443,6 +444,59 @@ export const tools: Tool[] = [
|
||||
},
|
||||
},
|
||||
|
||||
// ── Slack tools ──────────────────────────────────────────────
|
||||
{
|
||||
name: 'slack_get_me',
|
||||
description:
|
||||
'Verify the Slack bot is connected and return workspace info. Use to confirm credentials are working.',
|
||||
inputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
account: { type: 'string', description: 'Which Slack account to use (default: "default")' },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'slack_get_channels',
|
||||
description:
|
||||
'List Slack channels the bot has access to. Use to find channel IDs before sending messages.',
|
||||
inputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
limit: { type: 'number', description: 'Max channels to return (default: 100)' },
|
||||
account: { type: 'string', description: 'Which Slack account to use (default: "default")' },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'slack_send_message',
|
||||
description:
|
||||
'Send a message to a Slack channel. Uses the default channel if channel_id is omitted.',
|
||||
inputSchema: {
|
||||
type: 'object',
|
||||
required: ['text'],
|
||||
properties: {
|
||||
channel_id: { type: 'string', description: 'Slack channel ID (e.g. C0123456). Uses default channel if omitted.' },
|
||||
text: { type: 'string', description: 'Message text. Supports Slack mrkdwn formatting.' },
|
||||
account: { type: 'string', description: 'Which Slack account to use (default: "default")' },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'slack_get_messages',
|
||||
description:
|
||||
'Get recent messages from a Slack channel.',
|
||||
inputSchema: {
|
||||
type: 'object',
|
||||
required: ['channel_id'],
|
||||
properties: {
|
||||
channel_id: { type: 'string', description: 'Slack channel ID' },
|
||||
limit: { type: 'number', description: 'Max messages to return (default: 10)' },
|
||||
account: { type: 'string', description: 'Which Slack account to use (default: "default")' },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// ── Instagram tools ──────────────────────────────────────────
|
||||
{
|
||||
name: 'instagram_get_profile',
|
||||
@@ -738,7 +792,7 @@ async function resolveEmailCtx(args: Record<string, unknown>, customer?: Custome
|
||||
|
||||
const PLATFORM_PREFIXES = [
|
||||
'linkedin', 'obsidian', 'whatsapp', 'telegram', 'discord',
|
||||
'instagram', 'twitter', 'tiktok', 'snapchat', 'facebook',
|
||||
'instagram', 'twitter', 'tiktok', 'snapchat', 'facebook', 'slack',
|
||||
];
|
||||
|
||||
function toolPlatform(name: string): string {
|
||||
@@ -984,6 +1038,36 @@ export async function handleToolCall(
|
||||
}, customer);
|
||||
break;
|
||||
|
||||
// ── Slack ───────────────────────────────────────────────────
|
||||
case 'slack_get_me':
|
||||
result = await getSlackMe({
|
||||
account: args.account as string | undefined,
|
||||
}, customer);
|
||||
break;
|
||||
|
||||
case 'slack_get_channels':
|
||||
result = await getSlackChannels({
|
||||
limit: args.limit as number | undefined,
|
||||
account: args.account as string | undefined,
|
||||
}, customer);
|
||||
break;
|
||||
|
||||
case 'slack_send_message':
|
||||
result = await sendSlackMessage({
|
||||
channel_id: args.channel_id as string | undefined,
|
||||
text: args.text as string,
|
||||
account: args.account as string | undefined,
|
||||
}, customer);
|
||||
break;
|
||||
|
||||
case 'slack_get_messages':
|
||||
result = await getSlackMessages({
|
||||
channel_id: args.channel_id as string,
|
||||
limit: args.limit as number | undefined,
|
||||
account: args.account as string | undefined,
|
||||
}, customer);
|
||||
break;
|
||||
|
||||
// ── Instagram ───────────────────────────────────────────────
|
||||
case 'instagram_get_profile':
|
||||
result = await getInstagramProfile({
|
||||
|
||||
Reference in New Issue
Block a user