diff --git a/content/docs/agents/add-connect-components.mdx b/content/docs/agents/add-connect-components.mdx index 2ac0c6c76..90404af4f 100644 --- a/content/docs/agents/add-connect-components.mdx +++ b/content/docs/agents/add-connect-components.mdx @@ -3,3 +3,111 @@ title: "Add Connect Components" pageTitle: 'Novu Agents Add Connect Components' description: 'Add Connect UI components so users can link accounts and channels to your agent.' --- + +Novu provides pre-built UI components for chat platforms like Slack and Microsoft Teams. Add these components so users can install the Slack or Microsoft Teams app in their workspace and connect it to your agent. + +## Slack connect button + +`SlackConnectButton` is a pre-built UI component in the `@novu/react` SDK that connects an agent to a Slack workspace. Check out the example below. + +```tsx +import { SlackConnectButton } from '@novu/react'; + +const SlackConnectButtonComponent = () => { + const subscriberId = 'subscriber-id'; + const integrationIdentifier = 'integration-identifier'; + const agent = { + identifier: 'agent-identifier', + name: 'agent-name', + }; + + const handleSlackOAuthSuccess = () => { + // Handle success + }; + + return ( + { + console.error(error); + }} + /> + ); +}; + +export default SlackConnectButtonComponent; +``` + +### API reference + +`SlackConnectButton` accepts the following props to customize the UI and behavior: + +>" + }, + "scope": { + "description": "", + "type": "string[]" + }, + "connectionMode": { + "description": "", + "type": "ConnectionMode" + }, + "onConnectSuccess": { + "description": "", + "type": "((connectionIdentifier: string) => void)" + }, + "onConnectError": { + "description": "", + "type": "((error: unknown) => void)" + }, + "onDisconnectSuccess": { + "description": "", + "type": "(() => void)" + }, + "onDisconnectError": { + "description": "", + "type": "((error: unknown) => void)" + }, + "connectLabel": { + "description": "", + "type": "string" + }, + "connectedLabel": { + "description": "", + "type": "string" + }, + "appearance": { + "description": "", + "type": "ReactInboxAppearance | ReactSubscriptionAppearance | ReactAllAppearance" + }, + "container": { + "description": "", + "type": "string | Node | null" + } +}} /> + +## Microsoft Teams connect button + + + We are working on adding a Microsoft Teams connect button to the `@novu/react` SDK. Reach out to us at support@novu.co to get access to a pre-release version. + diff --git a/content/docs/agents/add-connect-components.model.mdx b/content/docs/agents/add-connect-components.model.mdx new file mode 100644 index 000000000..9f568e5b7 --- /dev/null +++ b/content/docs/agents/add-connect-components.model.mdx @@ -0,0 +1,58 @@ +--- +title: "Add Connect Components" +pageTitle: 'Novu Agents Add Connect Components' +description: 'Add Connect UI components so users can link accounts and channels to your agent.' +--- + +Novu provides pre-built UI components for chat platforms like Slack and Microsoft Teams. Add these components so users can install the Slack or Microsoft Teams app in their workspace and connect it to your agent. + +## Slack connect button + +`SlackConnectButton` is a pre-built UI component in the `@novu/react` SDK that connects an agent to a Slack workspace. Check out the example below. + +```tsx +import { SlackConnectButton } from '@novu/react'; + +const SlackConnectButtonComponent = () => { + const subscriberId = 'subscriber-id'; + const integrationIdentifier = 'integration-identifier'; + const agent = { + identifier: 'agent-identifier', + name: 'agent-name', + }; + + const handleSlackOAuthSuccess = () => { + // Handle success + }; + + return ( + { + console.error(error); + }} + /> + ); +}; + +export default SlackConnectButtonComponent; +``` + +### API reference + +`SlackConnectButton` accepts the following props to customize the UI and behavior: + +---type-table--- +../platform/sdks/types/react-types.ts#SlackConnectButtonProps +---end--- + +## Microsoft Teams connect button + + + We are working on adding a Microsoft Teams connect button to the `@novu/react` SDK. Reach out to us at support@novu.co to get access to a pre-release version. + diff --git a/content/docs/agents/deploy-your-agent.mdx b/content/docs/agents/deploy-your-agent.mdx index 52daeec2b..1792f422d 100644 --- a/content/docs/agents/deploy-your-agent.mdx +++ b/content/docs/agents/deploy-your-agent.mdx @@ -1,5 +1,110 @@ --- -title: "Deploy Your Agent" -pageTitle: 'Novu Agents Deployment' -description: 'Deploy your Novu Agent to production environments.' +title: "Agent Deployment" +pageTitle: 'Agent Deployment' +description: 'Learn how to run a conversational agent on your local machine, test it in a development environment, and deploy it to production.' --- + +Agents built with Novu can run on your local machine. Deploy them to development and production environments when you are ready. + +## Agent on your local machine + +By default, the agent runs on your local machine. To run the agent locally: + +* Scaffold your agent with `npx novu init -t agent`. +* Add valid `NOVU_SECRET_KEY` and `NOVU_API_URL` values to your `.env` file. +* Run the scaffolded project on your local machine. +* Set the bridge option to `Local` in the agent overview section. + +When you complete these steps, run the agent using the Novu CLI command below. + +```bash +npx novu@latest dev --port --no-studio +``` + +* **bridge_application_port** - Port where your scaffolded project runs. Defaults to 4000. +* **no-studio** - Disables Studio. + +After you run the command, a tunnel starts on your machine. It forwards requests to your scaffolded project on `bridge_application_port`. + +Novu sets the bridge URL automatically to `tunnel-url/api/novu`. + +The agent listens for new messages and responds while running locally. + +## Agent in development + +After you test the agent locally, deploy it to a development environment. A scaffolded app from `npx novu init -t agent` uses Next.js and exposes a `/api/novu` endpoint for communicating with Novu. Deploy the app to your preferred hosting provider, then copy the deployed URL. + +* Add valid `NOVU_SECRET_KEY` and `NOVU_API_URL` values in the environment variables section of your hosting provider. +* Toggle the bridge option to `Development` in the agent overview section. +* For a deployed app at `https://dev.my-agent-app.com`, use `https://dev.my-agent-app.com/api/novu` as the bridge URL in the agent overview section. + +## Agent in production + +Before you use an agent in production, publish the agent from the development environment to the production environment. Use the *Publish changes* option on the dashboard. + +After you publish: + +* Publishing sends the agent to production with the same name, identifier, and description. +* The agent stays inactive until you activate it from the agent overview section. +* Configure and connect every provider again in the production environment. +* Deploy the agent bridge application to the production environment. +* Add valid `NOVU_SECRET_KEY` and `NOVU_API_URL` values in the environment variables section of your hosting provider. + +### Deploying to production + +After you publish the agent and complete the above steps, deploy the agent bridge application to the production environment. + +#### Using Novu CLI + +```bash +npx novu@latest sync --bridge-url --secret-key --api-url +``` + +For example, with `https://prod.my-agent-app.com` as the bridge app URL, use `https://prod.my-agent-app.com/api/novu` as the bridge URL. + +In the command above: + +* ``: URL of your deployed agent bridge application. +* ``: secret key for your Novu account. +* ``: API URL for your Novu account. + +After you run the command, the agent overview section shows the updated production bridge URL. + +#### Using GitHub Actions + +You can use our built-in GitHub Action to deploy your agent to the production environment.--> + +```yaml +name: Deploy agent to Novu Cloud + +on: + workflow_dispatch: + push: + branches: + - main + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + # https://github.com/novuhq/actions-novu-sync + - name: Deploy agent to Novu Cloud + uses: novuhq/actions-novu-sync@v2 + with: + # The secret key used to authenticate with Novu Cloud + # To get the secret key, go to https://web.novu.co/api-keys. + # Required. + secret-key: ${{ secrets.NOVU_SECRET_KEY }} + + # The publicly available endpoint hosting the bridge application + # where notification entities (e.g. workflows, topics) are defined. + # Required. + bridge-url: ${{ secrets.NOVU_BRIDGE_URL }} + + # The Novu Cloud API URL to sync with. + # Optional. + # Defaults to https://api.novu.co + api-url: https://api.novu.co +``` + +Local tunnel bridge URLs cannot be activated on production environments (returns 403 Forbidden) to prevent accidental routing of production traffic to a local machine. diff --git a/content/docs/platform/sdks/javascript/index.mdx b/content/docs/platform/sdks/javascript/index.mdx index 492f66695..c527e3f3f 100644 --- a/content/docs/platform/sdks/javascript/index.mdx +++ b/content/docs/platform/sdks/javascript/index.mdx @@ -137,7 +137,7 @@ Fetches a list of notifications based on provided filters. `. When omitted, the provider value (default `true`) is used.", + "type": "boolean" + }, "onSuccess": { "description": "", "type": "((data: Notification[]) => void)" diff --git a/content/docs/platform/sdks/react/index.mdx b/content/docs/platform/sdks/react/index.mdx index 230796e20..23cfec9e3 100644 --- a/content/docs/platform/sdks/react/index.mdx +++ b/content/docs/platform/sdks/react/index.mdx @@ -835,6 +835,30 @@ function NovuInbox() { "description": "", "type": "ElementStyles" }, + "connectChatContainer": { + "description": "", + "type": "ElementStyles" + }, + "connectChatButton": { + "description": "", + "type": "ElementStyles" + }, + "connectChatButtonContainer": { + "description": "", + "type": "ElementStyles" + }, + "connectChatButtonLabel": { + "description": "", + "type": "ElementStyles" + }, + "connectChatMisconfiguredTooltip": { + "description": "", + "type": "ElementStyles" + }, + "channelConnectButtonMisconfiguredTooltip": { + "description": "", + "type": "ElementStyles" + }, "bellIcon": { "description": "", "type": "ElementStyles | ((context: { unreadCount: { total: number; severity: Record; }; }) => string)" @@ -1310,6 +1334,46 @@ function NovuInbox() { "subscriptionPreferenceGroupWorkflowLabel": { "description": "", "type": "ElementStyles | ((context: { preference: { label: string; preference: SubscriptionPreference; }; }) => string)" + }, + "linkSlackUserContainer": { + "description": "", + "type": "ElementStyles | ((context: { linked: boolean; }) => string)" + }, + "linkSlackUserButton": { + "description": "", + "type": "ElementStyles | ((context: { linked: boolean; }) => string)" + }, + "linkSlackUserButtonContainer": { + "description": "", + "type": "ElementStyles | ((context: { linked: boolean; }) => string)" + }, + "linkSlackUserButtonIcon": { + "description": "", + "type": "ElementStyles | ((context: { linked: boolean; }) => string)" + }, + "linkSlackUserButtonLabel": { + "description": "", + "type": "ElementStyles | ((context: { linked: boolean; }) => string)" + }, + "channelConnectButtonContainer": { + "description": "", + "type": "ElementStyles | ((context: { connected: boolean; }) => string)" + }, + "channelConnectButton": { + "description": "", + "type": "ElementStyles | ((context: { connected: boolean; }) => string)" + }, + "channelConnectButtonInner": { + "description": "", + "type": "ElementStyles | ((context: { connected: boolean; }) => string)" + }, + "channelConnectButtonIcon": { + "description": "", + "type": "ElementStyles | ((context: { connected: boolean; }) => string)" + }, + "channelConnectButtonLabel": { + "description": "", + "type": "ElementStyles | ((context: { connected: boolean; }) => string)" } }} /> diff --git a/content/docs/platform/sdks/types/react-types.ts b/content/docs/platform/sdks/types/react-types.ts index 6056e8c94..d4abe3ec6 100644 --- a/content/docs/platform/sdks/types/react-types.ts +++ b/content/docs/platform/sdks/types/react-types.ts @@ -8,6 +8,7 @@ import type { UseNotificationsProps, UseNotificationsResult, Notification as NotificationType, + SlackConnectButtonProps, } from '@novu/react'; import type { AllAppearance, AllElements, Variables } from '@novu/js/ui'; @@ -24,3 +25,5 @@ export type { SubscriptionProps, SubscriptionAppearance }; export type { UseNotificationsProps, UseNotificationsResult }; export type { NotificationType }; + +export type { SlackConnectButtonProps }; diff --git a/package.json b/package.json index 24d40b706..72ed2aec6 100644 --- a/package.json +++ b/package.json @@ -22,10 +22,10 @@ "@clerk/nextjs": "^6.12.4", "@inkeep/cxkit-react": "^0.5.82", "@next/third-parties": "^15.2.1", - "@novu/api": "3.14.4", + "@novu/api": "3.15.0", "@novu/framework": "2.10.0", - "@novu/js": "3.14.1", - "@novu/react": "3.14.1", + "@novu/js": "3.16.0", + "@novu/react": "3.16.0", "@radix-ui/react-accordion": "^1.2.3", "@radix-ui/react-hover-card": "^1.1.6", "@radix-ui/react-popover": "^1.1.6", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 25e2399b8..e9a0d2c0e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,17 +18,17 @@ importers: specifier: ^15.2.1 version: 15.2.3(next@15.2.8(@babel/core@7.27.4)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0) '@novu/api': - specifier: 3.14.4 - version: 3.14.4 + specifier: 3.15.0 + version: 3.15.0 '@novu/framework': specifier: 2.10.0 version: 2.10.0(next@15.2.8(@babel/core@7.27.4)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(zod-to-json-schema@3.24.5(zod@3.24.2))(zod@3.24.2) '@novu/js': - specifier: 3.14.1 - version: 3.14.1 + specifier: 3.16.0 + version: 3.16.0 '@novu/react': - specifier: 3.14.1 - version: 3.14.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + specifier: 3.16.0 + version: 3.16.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@radix-ui/react-accordion': specifier: ^1.2.3 version: 1.2.3(@types/react-dom@19.0.4(@types/react@19.0.12))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -1489,8 +1489,8 @@ packages: resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} engines: {node: '>=12.4.0'} - '@novu/api@3.14.4': - resolution: {integrity: sha512-xEajsWYNBog3wLOKCH4D2DS8PFi1EYP05fnV0tQgrZoafiQNtEOZOsTvY/l01iq7PA0DN64Qp/tYj57MSN8OiA==} + '@novu/api@3.15.0': + resolution: {integrity: sha512-S1fK3S+qxfTe0bbU0NstNR7EZic500j5YcF9Cg8OdTxw+IDzUGZPjBdzE1G1JHZdhfNQBBuplb9w4wCZC7us1Q==} '@novu/framework@2.10.0': resolution: {integrity: sha512-tKJLJrWwdJ6iG9LuncqSj2hO5oLlzJneyhMsfeA15Uv1AeZQsGAIJNtrJFiIE7jOQPbVtaGDdEm0swcwUhDRfw==} @@ -1527,11 +1527,11 @@ packages: zod-to-json-schema: optional: true - '@novu/js@3.14.1': - resolution: {integrity: sha512-Og9IrPPunw3XleaMl8nkV0vSu0rGXE75CO/CP/upEQWpbK+KvMZbN6rF9+KTrcO1EDG6DwNjI+jhZO83KaIQNg==} + '@novu/js@3.16.0': + resolution: {integrity: sha512-8e9ALu32ny1FgbketokXj0amG73aAcqK/9s+LeTJzlck0m3zdttGfzHMmMy0lxDu0+xFcehRYRL55dUzWbdn2w==} - '@novu/react@3.14.1': - resolution: {integrity: sha512-hRdjpg0Ld+8bBJjDlJFotbSCYjbuuDfvRS6ymY2l+rf3fToVRDx+ph7fa178ONJOGcfdw/Zg1mXp88GwaZeAFg==} + '@novu/react@3.16.0': + resolution: {integrity: sha512-SFYXz/6YfhnD2quEN7LMlvEQbAG9GcP6zw0LBr09ohsCT1lCXOHRNGlk8SifbIYzu4nMFvDtCMeIvzYQ63PNBQ==} peerDependencies: react: ^18.0.0 || ^19.0.0 || ^19.0.0-0 react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-0 @@ -8465,7 +8465,7 @@ snapshots: '@nolyfill/is-core-module@1.0.39': {} - '@novu/api@3.14.4': + '@novu/api@3.15.0': dependencies: zod: 3.25.76 @@ -8488,7 +8488,7 @@ snapshots: transitivePeerDependencies: - encoding - '@novu/js@3.14.1': + '@novu/js@3.16.0': dependencies: '@floating-ui/dom': 1.6.13 '@kobalte/core': 0.13.10(solid-js@1.9.4) @@ -8508,9 +8508,9 @@ snapshots: - supports-color - utf-8-validate - '@novu/react@3.14.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@novu/react@3.16.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: - '@novu/js': 3.14.1 + '@novu/js': 3.16.0 react: 19.0.0 optionalDependencies: react-dom: 19.0.0(react@19.0.0)