veryfront 0.0.48 → 0.0.50
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/dist/ai/components.js +260 -56
- package/dist/ai/components.js.map +4 -4
- package/dist/ai/index.d.ts +1 -0
- package/dist/ai/index.js +12 -4
- package/dist/ai/index.js.map +2 -2
- package/dist/ai/primitives.js +55 -10
- package/dist/ai/primitives.js.map +3 -3
- package/dist/ai/react.js +140 -1
- package/dist/ai/react.js.map +3 -3
- package/dist/ai/workflow-react.js +458 -0
- package/dist/ai/workflow-react.js.map +7 -0
- package/dist/ai/workflow.js +5422 -0
- package/dist/ai/workflow.js.map +7 -0
- package/dist/cli.js +976 -234
- package/dist/components.js +12 -4
- package/dist/components.js.map +2 -2
- package/dist/config.js +12 -4
- package/dist/config.js.map +2 -2
- package/dist/data.js +12 -4
- package/dist/data.js.map +2 -2
- package/dist/index.js +12 -8
- package/dist/index.js.map +2 -2
- package/dist/integrations/_base/files/SETUP.md +667 -98
- package/dist/integrations/_base/files/app/api/integrations/token-storage/route.ts +14 -0
- package/dist/integrations/_base/files/app/components/ServiceConnections.tsx +2 -1
- package/dist/integrations/_base/files/app/setup/page.tsx +858 -54
- package/dist/integrations/_base/files/lib/token-store-examples.ts +435 -0
- package/dist/integrations/_base/files/lib/token-store.ts +273 -23
- package/dist/integrations/airtable/connector.json +99 -0
- package/dist/integrations/airtable/files/ai/tools/create-record.ts +25 -0
- package/dist/integrations/airtable/files/ai/tools/get-base.ts +34 -0
- package/dist/integrations/airtable/files/ai/tools/get-record.ts +23 -0
- package/dist/integrations/airtable/files/ai/tools/list-bases.ts +19 -0
- package/dist/integrations/airtable/files/ai/tools/list-records.ts +47 -0
- package/dist/integrations/airtable/files/app/api/auth/airtable/callback/route.ts +11 -0
- package/dist/integrations/airtable/files/app/api/auth/airtable/route.ts +9 -0
- package/dist/integrations/airtable/files/lib/airtable-client.ts +244 -0
- package/dist/integrations/airtable/files/lib/token-store.ts +5 -0
- package/dist/integrations/anthropic/README.md +181 -0
- package/dist/integrations/anthropic/connector.json +88 -0
- package/dist/integrations/anthropic/files/_env.example +4 -0
- package/dist/integrations/anthropic/files/ai/tools/get-organization.ts +36 -0
- package/dist/integrations/anthropic/files/ai/tools/get-usage.ts +100 -0
- package/dist/integrations/anthropic/files/ai/tools/list-api-keys.ts +64 -0
- package/dist/integrations/anthropic/files/ai/tools/list-members.ts +65 -0
- package/dist/integrations/anthropic/files/ai/tools/list-workspaces.ts +35 -0
- package/dist/integrations/anthropic/files/lib/anthropic-admin-client.ts +264 -0
- package/dist/integrations/asana/connector.json +85 -0
- package/dist/integrations/asana/files/_env.example +4 -0
- package/dist/integrations/asana/files/ai/tools/create-task.ts +34 -0
- package/dist/integrations/asana/files/ai/tools/get-task.ts +26 -0
- package/dist/integrations/asana/files/ai/tools/list-projects.ts +26 -0
- package/dist/integrations/asana/files/ai/tools/list-tasks.ts +50 -0
- package/dist/integrations/asana/files/ai/tools/update-task.ts +36 -0
- package/dist/integrations/asana/files/app/api/auth/asana/callback/route.ts +11 -0
- package/dist/integrations/asana/files/app/api/auth/asana/route.ts +7 -0
- package/dist/integrations/asana/files/lib/asana-client.ts +162 -0
- package/dist/integrations/asana/files/lib/token-store.ts +11 -0
- package/dist/integrations/aws/connector.json +72 -0
- package/dist/integrations/aws/files/_env.example +10 -0
- package/dist/integrations/aws/files/ai/tools/get-s3-object.ts +62 -0
- package/dist/integrations/aws/files/ai/tools/list-ec2-instances.ts +56 -0
- package/dist/integrations/aws/files/ai/tools/list-lambda-functions.ts +57 -0
- package/dist/integrations/aws/files/ai/tools/list-s3-buckets.ts +44 -0
- package/dist/integrations/aws/files/ai/tools/list-s3-objects.ts +58 -0
- package/dist/integrations/aws/files/lib/aws-client.ts +255 -0
- package/dist/integrations/bitbucket/connector.json +85 -0
- package/dist/integrations/bitbucket/files/_env.example +9 -0
- package/dist/integrations/bitbucket/files/ai/tools/create-pull-request.ts +83 -0
- package/dist/integrations/bitbucket/files/ai/tools/list-issues.ts +112 -0
- package/dist/integrations/bitbucket/files/ai/tools/list-pull-requests.ts +91 -0
- package/dist/integrations/bitbucket/files/ai/tools/list-repositories.ts +78 -0
- package/dist/integrations/bitbucket/files/app/api/auth/bitbucket/callback/route.ts +11 -0
- package/dist/integrations/bitbucket/files/app/api/auth/bitbucket/route.ts +9 -0
- package/dist/integrations/bitbucket/files/lib/bitbucket-client.ts +316 -0
- package/dist/integrations/bitbucket/files/lib/token-store.ts +5 -0
- package/dist/integrations/box/connector.json +85 -0
- package/dist/integrations/box/files/_env.example +4 -0
- package/dist/integrations/box/files/ai/tools/create-folder.ts +28 -0
- package/dist/integrations/box/files/ai/tools/get-file.ts +29 -0
- package/dist/integrations/box/files/ai/tools/list-files.ts +33 -0
- package/dist/integrations/box/files/ai/tools/search-files.ts +35 -0
- package/dist/integrations/box/files/ai/tools/upload-file.ts +32 -0
- package/dist/integrations/box/files/app/api/auth/box/callback/route.ts +11 -0
- package/dist/integrations/box/files/app/api/auth/box/route.ts +7 -0
- package/dist/integrations/box/files/lib/box-client.ts +280 -0
- package/dist/integrations/box/files/lib/token-store.ts +11 -0
- package/dist/integrations/calendar/files/app/api/auth/calendar/callback/route.ts +7 -110
- package/dist/integrations/calendar/files/app/api/auth/calendar/route.ts +5 -25
- package/dist/integrations/calendar/files/lib/token-store.ts +2 -110
- package/dist/integrations/clickup/connector.json +85 -0
- package/dist/integrations/clickup/files/_env.example +4 -0
- package/dist/integrations/clickup/files/ai/tools/create-task.ts +64 -0
- package/dist/integrations/clickup/files/ai/tools/get-task.ts +59 -0
- package/dist/integrations/clickup/files/ai/tools/list-lists.ts +109 -0
- package/dist/integrations/clickup/files/ai/tools/list-tasks.ts +95 -0
- package/dist/integrations/clickup/files/ai/tools/update-task.ts +85 -0
- package/dist/integrations/clickup/files/app/api/auth/clickup/callback/route.ts +11 -0
- package/dist/integrations/clickup/files/app/api/auth/clickup/route.ts +7 -0
- package/dist/integrations/clickup/files/lib/clickup-client.ts +439 -0
- package/dist/integrations/clickup/files/lib/token-store.ts +11 -0
- package/dist/integrations/confluence/README.md +246 -0
- package/dist/integrations/confluence/connector.json +104 -0
- package/dist/integrations/confluence/files/_env.example +4 -0
- package/dist/integrations/confluence/files/ai/tools/create-page.ts +43 -0
- package/dist/integrations/confluence/files/ai/tools/get-page.ts +30 -0
- package/dist/integrations/confluence/files/ai/tools/list-spaces.ts +31 -0
- package/dist/integrations/confluence/files/ai/tools/search-content.ts +38 -0
- package/dist/integrations/confluence/files/ai/tools/update-page.ts +45 -0
- package/dist/integrations/confluence/files/app/api/auth/confluence/callback/route.ts +11 -0
- package/dist/integrations/confluence/files/app/api/auth/confluence/route.ts +9 -0
- package/dist/integrations/confluence/files/lib/confluence-client.ts +281 -0
- package/dist/integrations/confluence/files/lib/token-store.ts +5 -0
- package/dist/integrations/discord/connector.json +100 -0
- package/dist/integrations/discord/files/_env.example +12 -0
- package/dist/integrations/discord/files/ai/tools/get-messages.ts +55 -0
- package/dist/integrations/discord/files/ai/tools/get-user.ts +32 -0
- package/dist/integrations/discord/files/ai/tools/list-channels.ts +32 -0
- package/dist/integrations/discord/files/ai/tools/list-guilds.ts +24 -0
- package/dist/integrations/discord/files/ai/tools/send-message.ts +33 -0
- package/dist/integrations/discord/files/app/api/auth/discord/callback/route.ts +11 -0
- package/dist/integrations/discord/files/app/api/auth/discord/route.ts +9 -0
- package/dist/integrations/discord/files/lib/discord-client.ts +273 -0
- package/dist/integrations/discord/files/lib/token-store.ts +5 -0
- package/dist/integrations/docs-google/connector.json +101 -0
- package/dist/integrations/docs-google/files/_env.example +8 -0
- package/dist/integrations/docs-google/files/ai/tools/create-document.ts +46 -0
- package/dist/integrations/docs-google/files/ai/tools/get-document.ts +46 -0
- package/dist/integrations/docs-google/files/ai/tools/list-documents.ts +42 -0
- package/dist/integrations/docs-google/files/ai/tools/search-documents.ts +38 -0
- package/dist/integrations/docs-google/files/ai/tools/update-document.ts +131 -0
- package/dist/integrations/docs-google/files/app/api/auth/docs-google/callback/route.ts +11 -0
- package/dist/integrations/docs-google/files/app/api/auth/docs-google/route.ts +9 -0
- package/dist/integrations/docs-google/files/lib/docs-client.ts +582 -0
- package/dist/integrations/docs-google/files/lib/token-store.ts +5 -0
- package/dist/integrations/drive/connector.json +134 -0
- package/dist/integrations/drive/files/_env.example +9 -0
- package/dist/integrations/drive/files/ai/tools/create-folder.ts +47 -0
- package/dist/integrations/drive/files/ai/tools/get-file.ts +55 -0
- package/dist/integrations/drive/files/ai/tools/list-files.ts +78 -0
- package/dist/integrations/drive/files/ai/tools/search-files.ts +79 -0
- package/dist/integrations/drive/files/ai/tools/upload-file.ts +59 -0
- package/dist/integrations/drive/files/app/api/auth/drive/callback/route.ts +11 -0
- package/dist/integrations/drive/files/app/api/auth/drive/route.ts +9 -0
- package/dist/integrations/drive/files/lib/drive-client.ts +359 -0
- package/dist/integrations/drive/files/lib/token-store.ts +113 -0
- package/dist/integrations/dropbox/connector.json +107 -0
- package/dist/integrations/dropbox/files/_env.example +24 -0
- package/dist/integrations/dropbox/files/ai/tools/get-account.ts +58 -0
- package/dist/integrations/dropbox/files/ai/tools/get-file.ts +61 -0
- package/dist/integrations/dropbox/files/ai/tools/list-files.ts +56 -0
- package/dist/integrations/dropbox/files/ai/tools/search-files.ts +70 -0
- package/dist/integrations/dropbox/files/ai/tools/upload-file.ts +48 -0
- package/dist/integrations/dropbox/files/app/api/auth/dropbox/callback/route.ts +11 -0
- package/dist/integrations/dropbox/files/app/api/auth/dropbox/route.ts +9 -0
- package/dist/integrations/dropbox/files/lib/dropbox-client.ts +397 -0
- package/dist/integrations/dropbox/files/lib/token-store.ts +5 -0
- package/dist/integrations/figma/INTEGRATION_SUMMARY.md +436 -0
- package/dist/integrations/figma/README.md +287 -0
- package/dist/integrations/figma/connector.json +100 -0
- package/dist/integrations/figma/files/_env.example +5 -0
- package/dist/integrations/figma/files/ai/tools/get-comments.ts +72 -0
- package/dist/integrations/figma/files/ai/tools/get-file.ts +54 -0
- package/dist/integrations/figma/files/ai/tools/list-files.ts +39 -0
- package/dist/integrations/figma/files/ai/tools/list-projects.ts +69 -0
- package/dist/integrations/figma/files/ai/tools/post-comment.ts +54 -0
- package/dist/integrations/figma/files/app/api/auth/figma/callback/route.ts +11 -0
- package/dist/integrations/figma/files/app/api/auth/figma/route.ts +9 -0
- package/dist/integrations/figma/files/lib/figma-client.ts +355 -0
- package/dist/integrations/figma/files/lib/token-store.ts +5 -0
- package/dist/integrations/figma/files/lib/types.ts +503 -0
- package/dist/integrations/freshdesk/connector.json +85 -0
- package/dist/integrations/freshdesk/files/_env.example +4 -0
- package/dist/integrations/freshdesk/files/ai/tools/create-ticket.ts +60 -0
- package/dist/integrations/freshdesk/files/ai/tools/get-ticket.ts +46 -0
- package/dist/integrations/freshdesk/files/ai/tools/list-contacts.ts +37 -0
- package/dist/integrations/freshdesk/files/ai/tools/list-tickets.ts +59 -0
- package/dist/integrations/freshdesk/files/ai/tools/update-ticket.ts +61 -0
- package/dist/integrations/freshdesk/files/app/api/auth/freshdesk/callback/route.ts +11 -0
- package/dist/integrations/freshdesk/files/app/api/auth/freshdesk/route.ts +7 -0
- package/dist/integrations/freshdesk/files/lib/freshdesk-client.ts +178 -0
- package/dist/integrations/freshdesk/files/lib/token-store.ts +11 -0
- package/dist/integrations/github/files/app/api/auth/github/callback/route.ts +6 -127
- package/dist/integrations/github/files/app/api/auth/github/route.ts +4 -24
- package/dist/integrations/github/files/lib/token-store.ts +2 -110
- package/dist/integrations/gitlab/connector.json +100 -0
- package/dist/integrations/gitlab/files/_env.example +7 -0
- package/dist/integrations/gitlab/files/ai/tools/create-issue.ts +49 -0
- package/dist/integrations/gitlab/files/ai/tools/get-issue.ts +56 -0
- package/dist/integrations/gitlab/files/ai/tools/list-merge-requests.ts +75 -0
- package/dist/integrations/gitlab/files/ai/tools/list-projects.ts +51 -0
- package/dist/integrations/gitlab/files/ai/tools/search-issues.ts +67 -0
- package/dist/integrations/gitlab/files/app/api/auth/gitlab/callback/route.ts +11 -0
- package/dist/integrations/gitlab/files/app/api/auth/gitlab/route.ts +9 -0
- package/dist/integrations/gitlab/files/lib/gitlab-client.ts +366 -0
- package/dist/integrations/gitlab/files/lib/token-store.ts +5 -0
- package/dist/integrations/gmail/files/app/api/auth/gmail/callback/route.ts +7 -108
- package/dist/integrations/gmail/files/app/api/auth/gmail/route.ts +5 -23
- package/dist/integrations/gmail/files/lib/gmail-client.ts +16 -55
- package/dist/integrations/gmail/files/lib/token-store.ts +4 -109
- package/dist/integrations/hubspot/connector.json +98 -0
- package/dist/integrations/hubspot/files/_env.example +5 -0
- package/dist/integrations/hubspot/files/ai/tools/create-contact.ts +41 -0
- package/dist/integrations/hubspot/files/ai/tools/create-deal.ts +41 -0
- package/dist/integrations/hubspot/files/ai/tools/get-contact.ts +39 -0
- package/dist/integrations/hubspot/files/ai/tools/list-contacts.ts +43 -0
- package/dist/integrations/hubspot/files/ai/tools/list-deals.ts +41 -0
- package/dist/integrations/hubspot/files/app/api/auth/hubspot/callback/route.ts +11 -0
- package/dist/integrations/hubspot/files/app/api/auth/hubspot/route.ts +9 -0
- package/dist/integrations/hubspot/files/lib/hubspot-client.ts +393 -0
- package/dist/integrations/hubspot/files/lib/token-store.ts +5 -0
- package/dist/integrations/intercom/connector.json +85 -0
- package/dist/integrations/intercom/files/_env.example +4 -0
- package/dist/integrations/intercom/files/ai/tools/get-contact.ts +35 -0
- package/dist/integrations/intercom/files/ai/tools/get-conversation.ts +55 -0
- package/dist/integrations/intercom/files/ai/tools/list-contacts.ts +35 -0
- package/dist/integrations/intercom/files/ai/tools/list-conversations.ts +49 -0
- package/dist/integrations/intercom/files/ai/tools/send-message.ts +34 -0
- package/dist/integrations/intercom/files/app/api/auth/intercom/callback/route.ts +11 -0
- package/dist/integrations/intercom/files/app/api/auth/intercom/route.ts +7 -0
- package/dist/integrations/intercom/files/lib/intercom-client.ts +308 -0
- package/dist/integrations/intercom/files/lib/token-store.ts +11 -0
- package/dist/integrations/jira/connector.json +109 -0
- package/dist/integrations/jira/files/ai/tools/create-issue.ts +47 -0
- package/dist/integrations/jira/files/ai/tools/get-issue.ts +57 -0
- package/dist/integrations/jira/files/ai/tools/list-projects.ts +30 -0
- package/dist/integrations/jira/files/ai/tools/search-issues.ts +49 -0
- package/dist/integrations/jira/files/ai/tools/update-issue.ts +81 -0
- package/dist/integrations/jira/files/app/api/auth/jira/callback/route.ts +11 -0
- package/dist/integrations/jira/files/app/api/auth/jira/route.ts +9 -0
- package/dist/integrations/jira/files/lib/jira-client.ts +338 -0
- package/dist/integrations/jira/files/lib/token-store.ts +5 -0
- package/dist/integrations/linear/connector.json +100 -0
- package/dist/integrations/linear/files/_env.example +6 -0
- package/dist/integrations/linear/files/ai/tools/create-issue.ts +71 -0
- package/dist/integrations/linear/files/ai/tools/get-issue.ts +55 -0
- package/dist/integrations/linear/files/ai/tools/list-projects.ts +43 -0
- package/dist/integrations/linear/files/ai/tools/search-issues.ts +54 -0
- package/dist/integrations/linear/files/ai/tools/update-issue.ts +71 -0
- package/dist/integrations/linear/files/app/api/auth/linear/callback/route.ts +11 -0
- package/dist/integrations/linear/files/app/api/auth/linear/route.ts +9 -0
- package/dist/integrations/linear/files/lib/linear-client.ts +464 -0
- package/dist/integrations/linear/files/lib/token-store.ts +5 -0
- package/dist/integrations/mailchimp/connector.json +85 -0
- package/dist/integrations/mailchimp/files/_env.example +4 -0
- package/dist/integrations/mailchimp/files/ai/tools/get-campaign.ts +45 -0
- package/dist/integrations/mailchimp/files/ai/tools/get-list.ts +51 -0
- package/dist/integrations/mailchimp/files/ai/tools/list-campaigns.ts +46 -0
- package/dist/integrations/mailchimp/files/ai/tools/list-lists.ts +46 -0
- package/dist/integrations/mailchimp/files/ai/tools/list-members.ts +58 -0
- package/dist/integrations/mailchimp/files/app/api/auth/mailchimp/callback/route.ts +11 -0
- package/dist/integrations/mailchimp/files/app/api/auth/mailchimp/route.ts +7 -0
- package/dist/integrations/mailchimp/files/lib/mailchimp-client.ts +267 -0
- package/dist/integrations/mailchimp/files/lib/token-store.ts +11 -0
- package/dist/integrations/mixpanel/connector.json +96 -0
- package/dist/integrations/mixpanel/files/_env.example +11 -0
- package/dist/integrations/mixpanel/files/ai/tools/get-funnel.ts +46 -0
- package/dist/integrations/mixpanel/files/ai/tools/get-retention.ts +64 -0
- package/dist/integrations/mixpanel/files/ai/tools/list-cohorts.ts +46 -0
- package/dist/integrations/mixpanel/files/ai/tools/query-events.ts +43 -0
- package/dist/integrations/mixpanel/files/ai/tools/track-event.ts +41 -0
- package/dist/integrations/mixpanel/files/lib/mixpanel-client.ts +319 -0
- package/dist/integrations/mixpanel/files/lib/token-store.ts +43 -0
- package/dist/integrations/monday/connector.json +85 -0
- package/dist/integrations/monday/files/_env.example +4 -0
- package/dist/integrations/monday/files/ai/tools/create-item.ts +36 -0
- package/dist/integrations/monday/files/ai/tools/get-item.ts +31 -0
- package/dist/integrations/monday/files/ai/tools/list-boards.ts +29 -0
- package/dist/integrations/monday/files/ai/tools/list-items.ts +36 -0
- package/dist/integrations/monday/files/ai/tools/update-item.ts +36 -0
- package/dist/integrations/monday/files/app/api/auth/monday/callback/route.ts +11 -0
- package/dist/integrations/monday/files/app/api/auth/monday/route.ts +7 -0
- package/dist/integrations/monday/files/lib/monday-client.ts +329 -0
- package/dist/integrations/monday/files/lib/token-store.ts +11 -0
- package/dist/integrations/neon/connector.json +89 -0
- package/dist/integrations/neon/files/_env.example +6 -0
- package/dist/integrations/neon/files/ai/tools/describe-table.ts +38 -0
- package/dist/integrations/neon/files/ai/tools/list-branches.ts +35 -0
- package/dist/integrations/neon/files/ai/tools/list-projects.ts +31 -0
- package/dist/integrations/neon/files/ai/tools/list-tables.ts +49 -0
- package/dist/integrations/neon/files/ai/tools/query-database.ts +33 -0
- package/dist/integrations/neon/files/app/api/auth/neon/route.ts +51 -0
- package/dist/integrations/neon/files/lib/neon-client.ts +294 -0
- package/dist/integrations/neon/files/lib/token-store.ts +29 -0
- package/dist/integrations/notion/connector.json +87 -0
- package/dist/integrations/notion/files/_env.example +6 -0
- package/dist/integrations/notion/files/ai/tools/create-page.ts +32 -0
- package/dist/integrations/notion/files/ai/tools/query-database.ts +44 -0
- package/dist/integrations/notion/files/ai/tools/read-page.ts +34 -0
- package/dist/integrations/notion/files/ai/tools/search-notion.ts +51 -0
- package/dist/integrations/notion/files/app/api/auth/notion/callback/route.ts +11 -0
- package/dist/integrations/notion/files/app/api/auth/notion/route.ts +9 -0
- package/dist/integrations/notion/files/lib/notion-client.ts +218 -0
- package/dist/integrations/notion/files/lib/token-store.ts +5 -0
- package/dist/integrations/onedrive/connector.json +100 -0
- package/dist/integrations/onedrive/files/_env.example +23 -0
- package/dist/integrations/onedrive/files/ai/tools/download-file.ts +38 -0
- package/dist/integrations/onedrive/files/ai/tools/list-files.ts +63 -0
- package/dist/integrations/onedrive/files/ai/tools/search-files.ts +59 -0
- package/dist/integrations/onedrive/files/ai/tools/upload-file.ts +43 -0
- package/dist/integrations/onedrive/files/app/api/auth/onedrive/callback/route.ts +11 -0
- package/dist/integrations/onedrive/files/app/api/auth/onedrive/route.ts +9 -0
- package/dist/integrations/onedrive/files/lib/onedrive-client.ts +314 -0
- package/dist/integrations/onedrive/files/lib/token-store.ts +5 -0
- package/dist/integrations/outlook/README.md +308 -0
- package/dist/integrations/outlook/connector.json +98 -0
- package/dist/integrations/outlook/files/_env.example +8 -0
- package/dist/integrations/outlook/files/ai/tools/get-email.ts +47 -0
- package/dist/integrations/outlook/files/ai/tools/list-emails.ts +46 -0
- package/dist/integrations/outlook/files/ai/tools/list-folders.ts +22 -0
- package/dist/integrations/outlook/files/ai/tools/search-emails.ts +41 -0
- package/dist/integrations/outlook/files/ai/tools/send-email.ts +41 -0
- package/dist/integrations/outlook/files/app/api/auth/outlook/callback/route.ts +11 -0
- package/dist/integrations/outlook/files/app/api/auth/outlook/route.ts +9 -0
- package/dist/integrations/outlook/files/lib/outlook-client.ts +204 -0
- package/dist/integrations/outlook/files/lib/token-store.ts +5 -0
- package/dist/integrations/pipedrive/connector.json +85 -0
- package/dist/integrations/pipedrive/files/_env.example +4 -0
- package/dist/integrations/pipedrive/files/ai/tools/create-deal.ts +44 -0
- package/dist/integrations/pipedrive/files/ai/tools/get-deal.ts +34 -0
- package/dist/integrations/pipedrive/files/ai/tools/list-deals.ts +40 -0
- package/dist/integrations/pipedrive/files/ai/tools/list-persons.ts +33 -0
- package/dist/integrations/pipedrive/files/ai/tools/update-deal.ts +46 -0
- package/dist/integrations/pipedrive/files/app/api/auth/pipedrive/callback/route.ts +11 -0
- package/dist/integrations/pipedrive/files/app/api/auth/pipedrive/route.ts +7 -0
- package/dist/integrations/pipedrive/files/lib/pipedrive-client.ts +259 -0
- package/dist/integrations/pipedrive/files/lib/token-store.ts +11 -0
- package/dist/integrations/posthog/connector.json +84 -0
- package/dist/integrations/posthog/files/_env.example +6 -0
- package/dist/integrations/posthog/files/ai/tools/capture-event.ts +37 -0
- package/dist/integrations/posthog/files/ai/tools/get-trends.ts +44 -0
- package/dist/integrations/posthog/files/ai/tools/list-feature-flags.ts +38 -0
- package/dist/integrations/posthog/files/ai/tools/list-persons.ts +32 -0
- package/dist/integrations/posthog/files/lib/posthog-client.ts +286 -0
- package/dist/integrations/posthog/files/lib/token-store.ts +21 -0
- package/dist/integrations/quickbooks/connector.json +85 -0
- package/dist/integrations/quickbooks/files/_env.example +4 -0
- package/dist/integrations/quickbooks/files/ai/tools/create-invoice.ts +48 -0
- package/dist/integrations/quickbooks/files/ai/tools/get-customer.ts +36 -0
- package/dist/integrations/quickbooks/files/ai/tools/get-invoice.ts +46 -0
- package/dist/integrations/quickbooks/files/ai/tools/list-customers.ts +37 -0
- package/dist/integrations/quickbooks/files/ai/tools/list-invoices.ts +40 -0
- package/dist/integrations/quickbooks/files/app/api/auth/quickbooks/callback/route.ts +11 -0
- package/dist/integrations/quickbooks/files/app/api/auth/quickbooks/route.ts +7 -0
- package/dist/integrations/quickbooks/files/lib/quickbooks-client.ts +252 -0
- package/dist/integrations/quickbooks/files/lib/token-store.ts +11 -0
- package/dist/integrations/salesforce/connector.json +104 -0
- package/dist/integrations/salesforce/files/ai/tools/create-lead.ts +101 -0
- package/dist/integrations/salesforce/files/ai/tools/get-account.ts +53 -0
- package/dist/integrations/salesforce/files/ai/tools/list-accounts.ts +50 -0
- package/dist/integrations/salesforce/files/ai/tools/list-contacts.ts +54 -0
- package/dist/integrations/salesforce/files/ai/tools/list-opportunities.ts +55 -0
- package/dist/integrations/salesforce/files/app/api/auth/salesforce/callback/route.ts +11 -0
- package/dist/integrations/salesforce/files/app/api/auth/salesforce/route.ts +9 -0
- package/dist/integrations/salesforce/files/lib/salesforce-client.ts +539 -0
- package/dist/integrations/salesforce/files/lib/token-store.ts +5 -0
- package/dist/integrations/sentry/connector.json +84 -0
- package/dist/integrations/sentry/files/_env.example +6 -0
- package/dist/integrations/sentry/files/ai/tools/get-issue.ts +66 -0
- package/dist/integrations/sentry/files/ai/tools/list-issues.ts +57 -0
- package/dist/integrations/sentry/files/ai/tools/list-projects.ts +32 -0
- package/dist/integrations/sentry/files/ai/tools/resolve-issue.ts +28 -0
- package/dist/integrations/sentry/files/lib/sentry-client.ts +268 -0
- package/dist/integrations/sentry/files/lib/token-store.ts +29 -0
- package/dist/integrations/servicenow/connector.json +66 -0
- package/dist/integrations/servicenow/files/_env.example +5 -0
- package/dist/integrations/servicenow/files/ai/tools/create-incident.ts +58 -0
- package/dist/integrations/servicenow/files/ai/tools/get-incident.ts +59 -0
- package/dist/integrations/servicenow/files/ai/tools/list-incidents.ts +72 -0
- package/dist/integrations/servicenow/files/ai/tools/search-knowledge.ts +48 -0
- package/dist/integrations/servicenow/files/ai/tools/update-incident.ts +60 -0
- package/dist/integrations/servicenow/files/app/api/auth/servicenow/callback/route.ts +89 -0
- package/dist/integrations/servicenow/files/app/api/auth/servicenow/route.ts +42 -0
- package/dist/integrations/servicenow/files/lib/servicenow-client.ts +239 -0
- package/dist/integrations/servicenow/files/lib/token-store.ts +42 -0
- package/dist/integrations/sharepoint/connector.json +99 -0
- package/dist/integrations/sharepoint/files/ai/tools/get-file.ts +93 -0
- package/dist/integrations/sharepoint/files/ai/tools/get-site.ts +51 -0
- package/dist/integrations/sharepoint/files/ai/tools/list-files.ts +63 -0
- package/dist/integrations/sharepoint/files/ai/tools/list-sites.ts +28 -0
- package/dist/integrations/sharepoint/files/ai/tools/upload-file.ts +72 -0
- package/dist/integrations/sharepoint/files/app/api/auth/sharepoint/callback/route.ts +11 -0
- package/dist/integrations/sharepoint/files/app/api/auth/sharepoint/route.ts +9 -0
- package/dist/integrations/sharepoint/files/lib/sharepoint-client.ts +420 -0
- package/dist/integrations/sharepoint/files/lib/token-store.ts +5 -0
- package/dist/integrations/sheets/README.md +331 -0
- package/dist/integrations/sheets/connector.json +99 -0
- package/dist/integrations/sheets/files/_env.example +8 -0
- package/dist/integrations/sheets/files/ai/tools/create-spreadsheet.ts +85 -0
- package/dist/integrations/sheets/files/ai/tools/get-spreadsheet.ts +39 -0
- package/dist/integrations/sheets/files/ai/tools/list-spreadsheets.ts +41 -0
- package/dist/integrations/sheets/files/ai/tools/read-range.ts +35 -0
- package/dist/integrations/sheets/files/ai/tools/write-range.ts +51 -0
- package/dist/integrations/sheets/files/app/api/auth/sheets/callback/route.ts +11 -0
- package/dist/integrations/sheets/files/app/api/auth/sheets/route.ts +9 -0
- package/dist/integrations/sheets/files/lib/sheets-client.ts +425 -0
- package/dist/integrations/sheets/files/lib/token-store.ts +5 -0
- package/dist/integrations/shopify/connector.json +99 -0
- package/dist/integrations/shopify/files/_env.example +5 -0
- package/dist/integrations/shopify/files/ai/tools/get-order.ts +49 -0
- package/dist/integrations/shopify/files/ai/tools/get-product.ts +39 -0
- package/dist/integrations/shopify/files/ai/tools/list-customers.ts +40 -0
- package/dist/integrations/shopify/files/ai/tools/list-orders.ts +52 -0
- package/dist/integrations/shopify/files/ai/tools/list-products.ts +39 -0
- package/dist/integrations/shopify/files/app/api/auth/shopify/callback/route.ts +11 -0
- package/dist/integrations/shopify/files/app/api/auth/shopify/route.ts +7 -0
- package/dist/integrations/shopify/files/lib/shopify-client.ts +198 -0
- package/dist/integrations/shopify/files/lib/token-store.ts +11 -0
- package/dist/integrations/slack/files/app/api/auth/slack/callback/route.ts +6 -127
- package/dist/integrations/slack/files/app/api/auth/slack/route.ts +4 -24
- package/dist/integrations/slack/files/lib/token-store.ts +2 -110
- package/dist/integrations/snowflake/connector.json +151 -0
- package/dist/integrations/snowflake/files/_env.example +16 -0
- package/dist/integrations/snowflake/files/ai/tools/describe-table.ts +57 -0
- package/dist/integrations/snowflake/files/ai/tools/list-databases.ts +34 -0
- package/dist/integrations/snowflake/files/ai/tools/list-schemas.ts +40 -0
- package/dist/integrations/snowflake/files/ai/tools/list-tables.ts +49 -0
- package/dist/integrations/snowflake/files/ai/tools/run-query.ts +119 -0
- package/dist/integrations/snowflake/files/lib/snowflake-client.ts +389 -0
- package/dist/integrations/snowflake/files/lib/token-store.ts +77 -0
- package/dist/integrations/stripe/connector.json +97 -0
- package/dist/integrations/stripe/files/_env.example +6 -0
- package/dist/integrations/stripe/files/ai/tools/get-balance.ts +28 -0
- package/dist/integrations/stripe/files/ai/tools/get-customer.ts +26 -0
- package/dist/integrations/stripe/files/ai/tools/list-customers.ts +42 -0
- package/dist/integrations/stripe/files/ai/tools/list-payments.ts +45 -0
- package/dist/integrations/stripe/files/ai/tools/list-subscriptions.ts +67 -0
- package/dist/integrations/stripe/files/app/api/auth/stripe/route.ts +71 -0
- package/dist/integrations/stripe/files/lib/stripe-client.ts +376 -0
- package/dist/integrations/stripe/files/lib/token-store.ts +21 -0
- package/dist/integrations/supabase/connector.json +101 -0
- package/dist/integrations/supabase/files/_env.example +6 -0
- package/dist/integrations/supabase/files/ai/tools/delete-row.ts +77 -0
- package/dist/integrations/supabase/files/ai/tools/insert-row.ts +35 -0
- package/dist/integrations/supabase/files/ai/tools/list-tables.ts +60 -0
- package/dist/integrations/supabase/files/ai/tools/query-table.ts +48 -0
- package/dist/integrations/supabase/files/ai/tools/update-row.ts +64 -0
- package/dist/integrations/supabase/files/app/api/auth/supabase/route.ts +91 -0
- package/dist/integrations/supabase/files/lib/supabase-client.ts +296 -0
- package/dist/integrations/supabase/files/lib/token-store.ts +47 -0
- package/dist/integrations/teams/README.md +256 -0
- package/dist/integrations/teams/connector.json +99 -0
- package/dist/integrations/teams/files/ai/tools/get-messages.ts +55 -0
- package/dist/integrations/teams/files/ai/tools/list-channels.ts +28 -0
- package/dist/integrations/teams/files/ai/tools/list-chats.ts +41 -0
- package/dist/integrations/teams/files/ai/tools/list-teams.ts +27 -0
- package/dist/integrations/teams/files/ai/tools/send-message.ts +61 -0
- package/dist/integrations/teams/files/app/api/auth/teams/callback/route.ts +11 -0
- package/dist/integrations/teams/files/app/api/auth/teams/route.ts +9 -0
- package/dist/integrations/teams/files/lib/teams-client.ts +345 -0
- package/dist/integrations/teams/files/lib/token-store.ts +5 -0
- package/dist/integrations/trello/connector.json +85 -0
- package/dist/integrations/trello/files/_env.example +4 -0
- package/dist/integrations/trello/files/ai/tools/create-card.ts +54 -0
- package/dist/integrations/trello/files/ai/tools/get-card.ts +33 -0
- package/dist/integrations/trello/files/ai/tools/list-boards.ts +29 -0
- package/dist/integrations/trello/files/ai/tools/list-cards.ts +52 -0
- package/dist/integrations/trello/files/ai/tools/update-card.ts +65 -0
- package/dist/integrations/trello/files/app/api/auth/trello/callback/route.ts +11 -0
- package/dist/integrations/trello/files/app/api/auth/trello/route.ts +7 -0
- package/dist/integrations/trello/files/lib/token-store.ts +11 -0
- package/dist/integrations/trello/files/lib/trello-client.ts +202 -0
- package/dist/integrations/twilio/connector.json +146 -0
- package/dist/integrations/twilio/files/_env.example +14 -0
- package/dist/integrations/twilio/files/ai/tools/get-message.ts +58 -0
- package/dist/integrations/twilio/files/ai/tools/list-calls.ts +129 -0
- package/dist/integrations/twilio/files/ai/tools/list-messages.ts +97 -0
- package/dist/integrations/twilio/files/ai/tools/send-sms.ts +75 -0
- package/dist/integrations/twilio/files/ai/tools/send-whatsapp.ts +81 -0
- package/dist/integrations/twilio/files/lib/token-store.ts +60 -0
- package/dist/integrations/twilio/files/lib/twilio-client.ts +375 -0
- package/dist/integrations/twitter/connector.json +87 -0
- package/dist/integrations/twitter/files/_env.example +6 -0
- package/dist/integrations/twitter/files/ai/tools/get-timeline.ts +59 -0
- package/dist/integrations/twitter/files/ai/tools/post-tweet.ts +49 -0
- package/dist/integrations/twitter/files/ai/tools/search-tweets.ts +71 -0
- package/dist/integrations/twitter/files/app/api/auth/twitter/callback/route.ts +11 -0
- package/dist/integrations/twitter/files/app/api/auth/twitter/route.ts +9 -0
- package/dist/integrations/twitter/files/lib/token-store.ts +5 -0
- package/dist/integrations/twitter/files/lib/twitter-client.ts +236 -0
- package/dist/integrations/webex/connector.json +85 -0
- package/dist/integrations/webex/files/_env.example +4 -0
- package/dist/integrations/webex/files/ai/tools/create-meeting.ts +69 -0
- package/dist/integrations/webex/files/ai/tools/get-meeting.ts +31 -0
- package/dist/integrations/webex/files/ai/tools/list-meetings.ts +44 -0
- package/dist/integrations/webex/files/ai/tools/list-rooms.ts +35 -0
- package/dist/integrations/webex/files/ai/tools/send-message.ts +51 -0
- package/dist/integrations/webex/files/app/api/auth/webex/callback/route.ts +11 -0
- package/dist/integrations/webex/files/app/api/auth/webex/route.ts +7 -0
- package/dist/integrations/webex/files/lib/token-store.ts +11 -0
- package/dist/integrations/webex/files/lib/webex-client.ts +279 -0
- package/dist/integrations/xero/connector.json +85 -0
- package/dist/integrations/xero/files/_env.example +4 -0
- package/dist/integrations/xero/files/ai/tools/create-invoice.ts +65 -0
- package/dist/integrations/xero/files/ai/tools/get-contact.ts +40 -0
- package/dist/integrations/xero/files/ai/tools/get-invoice.ts +44 -0
- package/dist/integrations/xero/files/ai/tools/list-contacts.ts +54 -0
- package/dist/integrations/xero/files/ai/tools/list-invoices.ts +54 -0
- package/dist/integrations/xero/files/app/api/auth/xero/callback/route.ts +11 -0
- package/dist/integrations/xero/files/app/api/auth/xero/route.ts +7 -0
- package/dist/integrations/xero/files/lib/token-store.ts +11 -0
- package/dist/integrations/xero/files/lib/xero-client.ts +292 -0
- package/dist/integrations/zendesk/connector.json +61 -0
- package/dist/integrations/zendesk/files/_env.example +5 -0
- package/dist/integrations/zendesk/files/ai/tools/create-ticket.ts +82 -0
- package/dist/integrations/zendesk/files/ai/tools/get-ticket.ts +53 -0
- package/dist/integrations/zendesk/files/ai/tools/list-tickets.ts +60 -0
- package/dist/integrations/zendesk/files/ai/tools/search-tickets.ts +56 -0
- package/dist/integrations/zendesk/files/app/api/auth/zendesk/callback/route.ts +91 -0
- package/dist/integrations/zendesk/files/app/api/auth/zendesk/route.ts +41 -0
- package/dist/integrations/zendesk/files/lib/token-store.ts +47 -0
- package/dist/integrations/zendesk/files/lib/zendesk-client.ts +265 -0
- package/dist/integrations/zoom/connector.json +85 -0
- package/dist/integrations/zoom/files/_env.example +4 -0
- package/dist/integrations/zoom/files/ai/tools/create-meeting.ts +106 -0
- package/dist/integrations/zoom/files/ai/tools/delete-meeting.ts +32 -0
- package/dist/integrations/zoom/files/ai/tools/get-meeting.ts +44 -0
- package/dist/integrations/zoom/files/ai/tools/list-meetings.ts +47 -0
- package/dist/integrations/zoom/files/ai/tools/update-meeting.ts +111 -0
- package/dist/integrations/zoom/files/app/api/auth/zoom/callback/route.ts +11 -0
- package/dist/integrations/zoom/files/app/api/auth/zoom/route.ts +7 -0
- package/dist/integrations/zoom/files/lib/token-store.ts +11 -0
- package/dist/integrations/zoom/files/lib/zoom-client.ts +228 -0
- package/dist/oauth/handlers.js +554 -0
- package/dist/oauth/handlers.js.map +7 -0
- package/dist/oauth/index.js +1157 -0
- package/dist/oauth/index.js.map +7 -0
- package/dist/oauth/providers.js +927 -0
- package/dist/oauth/providers.js.map +7 -0
- package/dist/oauth/token-store.js +82 -0
- package/dist/oauth/token-store.js.map +7 -0
- package/package.json +25 -1
- package/dist/integrations/gmail/files/lib/oauth.ts +0 -145
- package/dist/integrations/slack/files/lib/oauth.ts +0 -145
- /package/dist/integrations/{calendar → docs-google}/files/lib/oauth.ts +0 -0
- /package/dist/integrations/{github → drive}/files/lib/oauth.ts +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// In-memory API key store for development
|
|
2
|
+
// For production, replace with a database-backed implementation
|
|
3
|
+
|
|
4
|
+
interface SupabaseConfig {
|
|
5
|
+
url: string;
|
|
6
|
+
anonKey: string;
|
|
7
|
+
serviceKey: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let configStore: SupabaseConfig | null = null;
|
|
11
|
+
|
|
12
|
+
export function setSupabaseConfig(config: SupabaseConfig): void {
|
|
13
|
+
configStore = config;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function getSupabaseUrl(): string {
|
|
17
|
+
if (!configStore?.url) {
|
|
18
|
+
throw new Error("Supabase URL not configured. Please set SUPABASE_URL environment variable.");
|
|
19
|
+
}
|
|
20
|
+
return configStore.url;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function getAnonKey(): string {
|
|
24
|
+
if (!configStore?.anonKey) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
"Supabase anon key not configured. Please set SUPABASE_ANON_KEY environment variable.",
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
return configStore.anonKey;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function getServiceKey(): string {
|
|
33
|
+
if (!configStore?.serviceKey) {
|
|
34
|
+
throw new Error(
|
|
35
|
+
"Supabase service key not configured. Please set SUPABASE_SERVICE_KEY environment variable.",
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
return configStore.serviceKey;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function clearConfig(): void {
|
|
42
|
+
configStore = null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function isConfigured(): boolean {
|
|
46
|
+
return configStore !== null;
|
|
47
|
+
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# Microsoft Teams Integration for Veryfront
|
|
2
|
+
|
|
3
|
+
This integration enables AI agents to interact with Microsoft Teams, allowing them to read chats, send messages, and manage team channels.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **List Chats**: Retrieve recent Teams chats with filtering options
|
|
8
|
+
- **Get Messages**: Read messages from specific chats or channels
|
|
9
|
+
- **Send Messages**: Send messages to chats or team channels
|
|
10
|
+
- **List Teams**: Get all teams the user is a member of
|
|
11
|
+
- **List Channels**: List channels within a specific team
|
|
12
|
+
|
|
13
|
+
## Setup
|
|
14
|
+
|
|
15
|
+
### 1. Register an Azure Application
|
|
16
|
+
|
|
17
|
+
1. Go to the [Azure Portal](https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade)
|
|
18
|
+
2. Click "New registration"
|
|
19
|
+
3. Enter a name for your application (e.g., "Veryfront Teams Integration")
|
|
20
|
+
4. Set the redirect URI to: `https://yourdomain.com/api/auth/teams/callback`
|
|
21
|
+
5. Click "Register"
|
|
22
|
+
|
|
23
|
+
### 2. Configure API Permissions
|
|
24
|
+
|
|
25
|
+
After registering your app:
|
|
26
|
+
|
|
27
|
+
1. Go to "API permissions" in the left sidebar
|
|
28
|
+
2. Click "Add a permission"
|
|
29
|
+
3. Select "Microsoft Graph"
|
|
30
|
+
4. Choose "Delegated permissions"
|
|
31
|
+
5. Add the following permissions:
|
|
32
|
+
- `Chat.Read` - Read user chats
|
|
33
|
+
- `Chat.ReadWrite` - Read and write user chats
|
|
34
|
+
- `ChannelMessage.Send` - Send channel messages
|
|
35
|
+
- `Team.ReadBasic.All` - Read team information
|
|
36
|
+
- `offline_access` - Maintain access to data
|
|
37
|
+
6. Click "Grant admin consent" if required by your organization
|
|
38
|
+
|
|
39
|
+
### 3. Create a Client Secret
|
|
40
|
+
|
|
41
|
+
1. Go to "Certificates & secrets"
|
|
42
|
+
2. Click "New client secret"
|
|
43
|
+
3. Add a description and set expiration
|
|
44
|
+
4. Copy the secret value immediately (it won't be shown again)
|
|
45
|
+
|
|
46
|
+
### 4. Configure Environment Variables
|
|
47
|
+
|
|
48
|
+
Add the following to your `.env` file:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
MICROSOFT_CLIENT_ID=your_application_id_here
|
|
52
|
+
MICROSOFT_CLIENT_SECRET=your_client_secret_here
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Usage
|
|
56
|
+
|
|
57
|
+
### Authentication
|
|
58
|
+
|
|
59
|
+
Users need to authenticate with Microsoft Teams before using the tools:
|
|
60
|
+
|
|
61
|
+
1. Navigate to `/api/auth/teams` in your application
|
|
62
|
+
2. Complete the Microsoft OAuth flow
|
|
63
|
+
3. You'll be redirected back to your application with access granted
|
|
64
|
+
|
|
65
|
+
### AI Tools
|
|
66
|
+
|
|
67
|
+
#### list-chats
|
|
68
|
+
|
|
69
|
+
List recent Teams chats:
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
{
|
|
73
|
+
limit: 20, // Number of chats to return (1-50)
|
|
74
|
+
expandMembers: false // Include member information
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Returns chat IDs, names, types, and timestamps.
|
|
79
|
+
|
|
80
|
+
#### get-messages
|
|
81
|
+
|
|
82
|
+
Get messages from a specific chat:
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
{
|
|
86
|
+
chatId: "19:...", // Chat ID from list-chats
|
|
87
|
+
limit: 20, // Number of messages (1-50)
|
|
88
|
+
includeHtml: false // Include HTML formatted content
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Returns message content, sender info, attachments, and reactions.
|
|
93
|
+
|
|
94
|
+
#### send-message
|
|
95
|
+
|
|
96
|
+
Send a message to a chat or channel:
|
|
97
|
+
|
|
98
|
+
**For Chats:**
|
|
99
|
+
```typescript
|
|
100
|
+
{
|
|
101
|
+
chatId: "19:...",
|
|
102
|
+
content: "Hello from the AI!",
|
|
103
|
+
contentType: "text" // "text" or "html"
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**For Channels:**
|
|
108
|
+
```typescript
|
|
109
|
+
{
|
|
110
|
+
teamId: "team-id",
|
|
111
|
+
channelId: "channel-id",
|
|
112
|
+
content: "Update: Project completed!",
|
|
113
|
+
contentType: "text",
|
|
114
|
+
subject: "Project Update" // Optional
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### list-teams
|
|
119
|
+
|
|
120
|
+
List all teams the user has joined:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
{
|
|
124
|
+
limit: 25 // Number of teams (1-50)
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Returns team IDs, names, descriptions, and metadata.
|
|
129
|
+
|
|
130
|
+
#### list-channels
|
|
131
|
+
|
|
132
|
+
List channels in a specific team:
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
{
|
|
136
|
+
teamId: "team-id",
|
|
137
|
+
limit: 25 // Number of channels (1-50)
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Returns channel IDs, names, types, and links.
|
|
142
|
+
|
|
143
|
+
## API Client
|
|
144
|
+
|
|
145
|
+
The Teams client (`teams-client.ts`) provides typed methods for all Microsoft Graph API operations:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import {
|
|
149
|
+
listChats,
|
|
150
|
+
getChatMessages,
|
|
151
|
+
sendChatMessage,
|
|
152
|
+
listTeams,
|
|
153
|
+
listChannels,
|
|
154
|
+
sendChannelMessage,
|
|
155
|
+
getChatDisplayName,
|
|
156
|
+
getPlainTextContent
|
|
157
|
+
} from "./lib/teams-client.ts";
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Key Methods
|
|
161
|
+
|
|
162
|
+
- `listChats(options)` - List user chats
|
|
163
|
+
- `getChatMessages(chatId, options)` - Get chat messages
|
|
164
|
+
- `sendChatMessage(chatId, content, contentType)` - Send chat message
|
|
165
|
+
- `listTeams(options)` - List joined teams
|
|
166
|
+
- `listChannels(teamId, options)` - List team channels
|
|
167
|
+
- `sendChannelMessage(teamId, channelId, content, contentType, subject)` - Send channel message
|
|
168
|
+
- `getCurrentUser()` - Get current user profile
|
|
169
|
+
|
|
170
|
+
### Helper Functions
|
|
171
|
+
|
|
172
|
+
- `getChatDisplayName(chat)` - Format chat display name
|
|
173
|
+
- `getPlainTextContent(message)` - Extract plain text from message
|
|
174
|
+
|
|
175
|
+
## Token Management
|
|
176
|
+
|
|
177
|
+
The integration uses an in-memory token store for development. For production:
|
|
178
|
+
|
|
179
|
+
1. Replace `token-store.ts` with a database-backed implementation
|
|
180
|
+
2. Store tokens securely with encryption
|
|
181
|
+
3. Implement token refresh logic using the `refreshAccessToken()` function in `oauth.ts`
|
|
182
|
+
4. Handle token expiration gracefully
|
|
183
|
+
|
|
184
|
+
## Security Considerations
|
|
185
|
+
|
|
186
|
+
- **Scopes**: Only request the minimum required permissions
|
|
187
|
+
- **Token Storage**: Use encrypted database storage in production
|
|
188
|
+
- **Token Refresh**: Implement automatic token refresh before expiration
|
|
189
|
+
- **CSRF Protection**: State parameter is included in OAuth flow
|
|
190
|
+
- **Environment Variables**: Keep client secrets secure and never commit them
|
|
191
|
+
|
|
192
|
+
## Integration with Other Services
|
|
193
|
+
|
|
194
|
+
This integration works well with:
|
|
195
|
+
|
|
196
|
+
- **Outlook**: Shared Microsoft OAuth credentials
|
|
197
|
+
- **Calendar**: Microsoft Calendar integration
|
|
198
|
+
- **Slack**: Cross-platform messaging
|
|
199
|
+
- **Gmail**: Email and chat integration
|
|
200
|
+
|
|
201
|
+
Set `suggestedWith` in connector.json to recommend related integrations.
|
|
202
|
+
|
|
203
|
+
## Troubleshooting
|
|
204
|
+
|
|
205
|
+
### Authentication Fails
|
|
206
|
+
|
|
207
|
+
- Verify client ID and secret are correct
|
|
208
|
+
- Check redirect URI matches Azure app configuration
|
|
209
|
+
- Ensure required API permissions are granted
|
|
210
|
+
|
|
211
|
+
### Cannot Read Messages
|
|
212
|
+
|
|
213
|
+
- Verify `Chat.Read` permission is granted
|
|
214
|
+
- Check user has access to the chat
|
|
215
|
+
- Ensure token hasn't expired
|
|
216
|
+
|
|
217
|
+
### Cannot Send Messages
|
|
218
|
+
|
|
219
|
+
- Verify `Chat.ReadWrite` or `ChannelMessage.Send` permissions
|
|
220
|
+
- Check user is a member of the chat/channel
|
|
221
|
+
- Ensure message content is not empty
|
|
222
|
+
|
|
223
|
+
### Token Expired
|
|
224
|
+
|
|
225
|
+
- Implement token refresh using `refreshAccessToken()` in `oauth.ts`
|
|
226
|
+
- Store refresh tokens securely
|
|
227
|
+
- Handle 401 responses by triggering re-authentication
|
|
228
|
+
|
|
229
|
+
## API Limits
|
|
230
|
+
|
|
231
|
+
Microsoft Graph API has rate limits:
|
|
232
|
+
|
|
233
|
+
- **Per-app limit**: 2000 requests per second
|
|
234
|
+
- **Per-user limit**: 50 requests per second
|
|
235
|
+
- **Concurrent requests**: 20 per user
|
|
236
|
+
|
|
237
|
+
Implement exponential backoff and retry logic for production use.
|
|
238
|
+
|
|
239
|
+
## TypeScript Types
|
|
240
|
+
|
|
241
|
+
All API responses are fully typed. Key interfaces:
|
|
242
|
+
|
|
243
|
+
- `TeamsChat` - Chat information
|
|
244
|
+
- `ChatMessage` - Message with content and metadata
|
|
245
|
+
- `Team` - Team information
|
|
246
|
+
- `Channel` - Channel information
|
|
247
|
+
- `ChatMember` - Member information
|
|
248
|
+
|
|
249
|
+
See `teams-client.ts` for complete type definitions.
|
|
250
|
+
|
|
251
|
+
## Resources
|
|
252
|
+
|
|
253
|
+
- [Microsoft Graph Teams API](https://learn.microsoft.com/en-us/graph/api/resources/teams-api-overview)
|
|
254
|
+
- [Azure App Registration](https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade)
|
|
255
|
+
- [Microsoft Graph Explorer](https://developer.microsoft.com/en-us/graph/graph-explorer)
|
|
256
|
+
- [OAuth 2.0 Authorization](https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow)
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "teams",
|
|
3
|
+
"displayName": "Microsoft Teams",
|
|
4
|
+
"icon": "teams.svg",
|
|
5
|
+
"description": "Send messages and manage Teams chats and channels",
|
|
6
|
+
"auth": {
|
|
7
|
+
"type": "oauth2",
|
|
8
|
+
"provider": "microsoft",
|
|
9
|
+
"authorizationUrl": "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
|
|
10
|
+
"tokenUrl": "https://login.microsoftonline.com/common/oauth2/v2.0/token",
|
|
11
|
+
"scopes": [
|
|
12
|
+
"Chat.Read",
|
|
13
|
+
"Chat.ReadWrite",
|
|
14
|
+
"ChannelMessage.Send",
|
|
15
|
+
"Team.ReadBasic.All",
|
|
16
|
+
"offline_access"
|
|
17
|
+
],
|
|
18
|
+
"callbackPath": "/api/auth/teams/callback",
|
|
19
|
+
"tokenAuthMethod": "body",
|
|
20
|
+
"requiredApis": [
|
|
21
|
+
{
|
|
22
|
+
"name": "Microsoft Graph API",
|
|
23
|
+
"enableUrl": "https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade"
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
"envVars": [
|
|
28
|
+
{
|
|
29
|
+
"name": "MICROSOFT_CLIENT_ID",
|
|
30
|
+
"description": "Microsoft Azure App Client ID (Application ID)",
|
|
31
|
+
"required": true,
|
|
32
|
+
"sensitive": false,
|
|
33
|
+
"docsUrl": "https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "MICROSOFT_CLIENT_SECRET",
|
|
37
|
+
"description": "Microsoft Azure App Client Secret",
|
|
38
|
+
"required": true,
|
|
39
|
+
"sensitive": true,
|
|
40
|
+
"docsUrl": "https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade"
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
"tools": [
|
|
44
|
+
{
|
|
45
|
+
"id": "list-chats",
|
|
46
|
+
"name": "List Chats",
|
|
47
|
+
"description": "List recent Teams chats",
|
|
48
|
+
"requiresWrite": false
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"id": "get-messages",
|
|
52
|
+
"name": "Get Messages",
|
|
53
|
+
"description": "Get messages from a specific chat",
|
|
54
|
+
"requiresWrite": false
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"id": "send-message",
|
|
58
|
+
"name": "Send Message",
|
|
59
|
+
"description": "Send a message to a chat or channel",
|
|
60
|
+
"requiresWrite": true
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"id": "list-teams",
|
|
64
|
+
"name": "List Teams",
|
|
65
|
+
"description": "List all joined Teams",
|
|
66
|
+
"requiresWrite": false
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"id": "list-channels",
|
|
70
|
+
"name": "List Channels",
|
|
71
|
+
"description": "List channels in a specific Team",
|
|
72
|
+
"requiresWrite": false
|
|
73
|
+
}
|
|
74
|
+
],
|
|
75
|
+
"prompts": [
|
|
76
|
+
{
|
|
77
|
+
"id": "check-messages",
|
|
78
|
+
"title": "Check my messages",
|
|
79
|
+
"prompt": "Check my recent Teams messages and summarize any important conversations or action items.",
|
|
80
|
+
"category": "communication",
|
|
81
|
+
"icon": "message"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"id": "send-update",
|
|
85
|
+
"title": "Send team update",
|
|
86
|
+
"prompt": "Send a status update message to a specific Teams channel about project progress.",
|
|
87
|
+
"category": "communication",
|
|
88
|
+
"icon": "send"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"id": "find-conversation",
|
|
92
|
+
"title": "Find a conversation",
|
|
93
|
+
"prompt": "Search through my Teams chats to find discussions about a specific topic.",
|
|
94
|
+
"category": "communication",
|
|
95
|
+
"icon": "search"
|
|
96
|
+
}
|
|
97
|
+
],
|
|
98
|
+
"suggestedWith": ["outlook", "slack", "calendar"]
|
|
99
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { tool } from "veryfront/ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { getChatMessages, getPlainTextContent } from "../../lib/teams-client.ts";
|
|
4
|
+
|
|
5
|
+
export default tool({
|
|
6
|
+
id: "get-messages",
|
|
7
|
+
description:
|
|
8
|
+
"Get messages from a specific Microsoft Teams chat. Returns message content, sender information, and timestamps. Use list-chats first to get chat IDs.",
|
|
9
|
+
inputSchema: z.object({
|
|
10
|
+
chatId: z.string().describe("The ID of the chat to get messages from"),
|
|
11
|
+
limit: z.number().min(1).max(50).default(20).describe(
|
|
12
|
+
"Maximum number of messages to return (1-50)",
|
|
13
|
+
),
|
|
14
|
+
includeHtml: z.boolean().default(false).describe(
|
|
15
|
+
"Include HTML formatted content in addition to plain text",
|
|
16
|
+
),
|
|
17
|
+
}),
|
|
18
|
+
async execute({ chatId, limit, includeHtml }) {
|
|
19
|
+
const messages = await getChatMessages(chatId, {
|
|
20
|
+
limit,
|
|
21
|
+
orderBy: "createdDateTime desc",
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
return messages
|
|
25
|
+
.filter((msg) => msg.messageType === "message") // Filter out typing indicators and events
|
|
26
|
+
.map((msg) => ({
|
|
27
|
+
id: msg.id,
|
|
28
|
+
content: getPlainTextContent(msg),
|
|
29
|
+
htmlContent: includeHtml ? msg.body.content : undefined,
|
|
30
|
+
contentType: msg.body.contentType,
|
|
31
|
+
sender: {
|
|
32
|
+
id: msg.from.user?.id,
|
|
33
|
+
displayName: msg.from.user?.displayName,
|
|
34
|
+
},
|
|
35
|
+
createdAt: msg.createdDateTime,
|
|
36
|
+
lastModified: msg.lastModifiedDateTime,
|
|
37
|
+
importance: msg.importance,
|
|
38
|
+
subject: msg.subject,
|
|
39
|
+
hasAttachments: msg.attachments && msg.attachments.length > 0,
|
|
40
|
+
attachmentCount: msg.attachments?.length || 0,
|
|
41
|
+
attachments: msg.attachments?.map((att) => ({
|
|
42
|
+
id: att.id,
|
|
43
|
+
name: att.name,
|
|
44
|
+
contentType: att.contentType,
|
|
45
|
+
contentUrl: att.contentUrl,
|
|
46
|
+
})),
|
|
47
|
+
mentions: msg.mentions?.map((mention) => ({
|
|
48
|
+
text: mention.mentionText,
|
|
49
|
+
userId: mention.mentioned.user.id,
|
|
50
|
+
displayName: mention.mentioned.user.displayName,
|
|
51
|
+
})),
|
|
52
|
+
reactionCount: msg.reactions?.length || 0,
|
|
53
|
+
}));
|
|
54
|
+
},
|
|
55
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { tool } from "veryfront/ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { listChannels } from "../../lib/teams-client.ts";
|
|
4
|
+
|
|
5
|
+
export default tool({
|
|
6
|
+
id: "list-channels",
|
|
7
|
+
description:
|
|
8
|
+
"List all channels in a specific Microsoft Team. Use list-teams first to get team IDs. Returns channel IDs, names, descriptions, and types.",
|
|
9
|
+
inputSchema: z.object({
|
|
10
|
+
teamId: z.string().describe("The ID of the team to list channels from"),
|
|
11
|
+
limit: z.number().min(1).max(50).default(25).describe(
|
|
12
|
+
"Maximum number of channels to return (1-50)",
|
|
13
|
+
),
|
|
14
|
+
}),
|
|
15
|
+
async execute({ teamId, limit }) {
|
|
16
|
+
const channels = await listChannels(teamId, { limit });
|
|
17
|
+
|
|
18
|
+
return channels.map((channel) => ({
|
|
19
|
+
id: channel.id,
|
|
20
|
+
name: channel.displayName,
|
|
21
|
+
description: channel.description,
|
|
22
|
+
email: channel.email,
|
|
23
|
+
webUrl: channel.webUrl,
|
|
24
|
+
membershipType: channel.membershipType,
|
|
25
|
+
createdAt: channel.createdDateTime,
|
|
26
|
+
}));
|
|
27
|
+
},
|
|
28
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { tool } from "veryfront/ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { getChatDisplayName, listChats } from "../../lib/teams-client.ts";
|
|
4
|
+
|
|
5
|
+
export default tool({
|
|
6
|
+
id: "list-chats",
|
|
7
|
+
description:
|
|
8
|
+
"List recent Microsoft Teams chats for the authenticated user. Returns chat IDs, names, types, and last updated timestamps.",
|
|
9
|
+
inputSchema: z.object({
|
|
10
|
+
limit: z.number().min(1).max(50).default(20).describe(
|
|
11
|
+
"Maximum number of chats to return (1-50)",
|
|
12
|
+
),
|
|
13
|
+
expandMembers: z.boolean().default(false).describe("Include chat member information"),
|
|
14
|
+
}),
|
|
15
|
+
async execute({ limit, expandMembers }) {
|
|
16
|
+
const expand = expandMembers ? ["members"] : undefined;
|
|
17
|
+
|
|
18
|
+
const chats = await listChats({
|
|
19
|
+
limit,
|
|
20
|
+
expand,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
return chats.map((chat) => ({
|
|
24
|
+
id: chat.id,
|
|
25
|
+
name: getChatDisplayName(chat),
|
|
26
|
+
type: chat.chatType,
|
|
27
|
+
topic: chat.topic,
|
|
28
|
+
lastUpdated: chat.lastUpdatedDateTime,
|
|
29
|
+
created: chat.createdDateTime,
|
|
30
|
+
webUrl: chat.webUrl,
|
|
31
|
+
memberCount: chat.members?.length,
|
|
32
|
+
members: expandMembers
|
|
33
|
+
? chat.members?.map((m) => ({
|
|
34
|
+
id: m.id,
|
|
35
|
+
displayName: m.displayName,
|
|
36
|
+
email: m.email,
|
|
37
|
+
}))
|
|
38
|
+
: undefined,
|
|
39
|
+
}));
|
|
40
|
+
},
|
|
41
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { tool } from "veryfront/ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { listTeams } from "../../lib/teams-client.ts";
|
|
4
|
+
|
|
5
|
+
export default tool({
|
|
6
|
+
id: "list-teams",
|
|
7
|
+
description:
|
|
8
|
+
"List all Microsoft Teams that the authenticated user is a member of. Returns team IDs, names, descriptions, and metadata.",
|
|
9
|
+
inputSchema: z.object({
|
|
10
|
+
limit: z.number().min(1).max(50).default(25).describe(
|
|
11
|
+
"Maximum number of teams to return (1-50)",
|
|
12
|
+
),
|
|
13
|
+
}),
|
|
14
|
+
async execute({ limit }) {
|
|
15
|
+
const teams = await listTeams({ limit });
|
|
16
|
+
|
|
17
|
+
return teams.map((team) => ({
|
|
18
|
+
id: team.id,
|
|
19
|
+
name: team.displayName,
|
|
20
|
+
description: team.description,
|
|
21
|
+
visibility: team.visibility,
|
|
22
|
+
isArchived: team.isArchived,
|
|
23
|
+
createdAt: team.createdDateTime,
|
|
24
|
+
webUrl: team.webUrl,
|
|
25
|
+
}));
|
|
26
|
+
},
|
|
27
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { tool } from "veryfront/ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { sendChannelMessage, sendChatMessage } from "../../lib/teams-client.ts";
|
|
4
|
+
|
|
5
|
+
export default tool({
|
|
6
|
+
id: "send-message",
|
|
7
|
+
description:
|
|
8
|
+
"Send a message to a Microsoft Teams chat or channel. For chats, use the chatId. For channels, use both teamId and channelId.",
|
|
9
|
+
inputSchema: z.object({
|
|
10
|
+
chatId: z.string().optional().describe(
|
|
11
|
+
"The ID of the chat to send the message to (use this for direct/group chats)",
|
|
12
|
+
),
|
|
13
|
+
teamId: z.string().optional().describe(
|
|
14
|
+
"The ID of the team (use with channelId for channel messages)",
|
|
15
|
+
),
|
|
16
|
+
channelId: z.string().optional().describe(
|
|
17
|
+
"The ID of the channel (use with teamId for channel messages)",
|
|
18
|
+
),
|
|
19
|
+
content: z.string().min(1).describe("The message content to send"),
|
|
20
|
+
contentType: z.enum(["text", "html"]).default("text").describe("Content format: text or html"),
|
|
21
|
+
subject: z.string().optional().describe("Subject line (only for channel messages)"),
|
|
22
|
+
}).refine(
|
|
23
|
+
(data) =>
|
|
24
|
+
(data.chatId && !data.teamId && !data.channelId) ||
|
|
25
|
+
(!data.chatId && data.teamId && data.channelId),
|
|
26
|
+
{
|
|
27
|
+
message: "Either provide chatId OR both teamId and channelId",
|
|
28
|
+
},
|
|
29
|
+
),
|
|
30
|
+
async execute({ chatId, teamId, channelId, content, contentType, subject }) {
|
|
31
|
+
// Send to chat
|
|
32
|
+
if (chatId) {
|
|
33
|
+
const message = await sendChatMessage(chatId, content, contentType);
|
|
34
|
+
return {
|
|
35
|
+
success: true,
|
|
36
|
+
messageId: message.id,
|
|
37
|
+
type: "chat",
|
|
38
|
+
chatId,
|
|
39
|
+
createdAt: message.createdDateTime,
|
|
40
|
+
content: message.body.content,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Send to channel
|
|
45
|
+
if (teamId && channelId) {
|
|
46
|
+
const message = await sendChannelMessage(teamId, channelId, content, contentType, subject);
|
|
47
|
+
return {
|
|
48
|
+
success: true,
|
|
49
|
+
messageId: message.id,
|
|
50
|
+
type: "channel",
|
|
51
|
+
teamId,
|
|
52
|
+
channelId,
|
|
53
|
+
subject,
|
|
54
|
+
createdAt: message.createdDateTime,
|
|
55
|
+
content: message.body.content,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
throw new Error("Invalid parameters: provide either chatId or both teamId and channelId");
|
|
60
|
+
},
|
|
61
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Teams OAuth Callback
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { createOAuthCallbackHandler, memoryTokenStore, teamsConfig } from "veryfront/oauth";
|
|
6
|
+
|
|
7
|
+
export const GET = createOAuthCallbackHandler(teamsConfig, {
|
|
8
|
+
tokenStore: memoryTokenStore,
|
|
9
|
+
onSuccess: () => "/",
|
|
10
|
+
onError: () => "/",
|
|
11
|
+
});
|