.workers.dev"
ORGANIZATION_ID="696a21b632ef1f83460d584d"
STEP_RESOLVER_HASH="abc12-def34"
STEP_ID="welcome-email"
SECRET="${STEP_RESOLVER_HMAC_SECRET:?set STEP_RESOLVER_HMAC_SECRET}"
PATHNAME="/resolve/${ORGANIZATION_ID}/sr-${STEP_RESOLVER_HASH}/${STEP_ID}"
BODY='{"payload":{"firstName":"Ada"},"subscriber":{"email":"ada@example.com"},"context":{},"steps":{}}'
```
--------------------------------
### Run ClickHouse Seeding Script (Basic)
Source: https://github.com/novuhq/novu/blob/next/apps/api/scripts/clickhouse-seeder/README.md
Execute the basic ClickHouse seeding script from the 'apps/api' directory. This generates default data volumes for organizations, days, and records.
```bash
pnpm seed:clickhouse
```
--------------------------------
### Initialize Novu Agent Toolkit for OpenAI
Source: https://github.com/novuhq/novu/blob/next/packages/agent-toolkit/README.md
Creates a toolkit instance for use with the OpenAI framework. The `toolkit.tools` property provides OpenAI function tool definitions, and `toolkit.handleToolCall` executes tool calls.
```typescript
import { createNovuAgentToolkit } from '@novu/agent-toolkit/openai';
const toolkit = await createNovuAgentToolkit({
secretKey: process.env.NOVU_SECRET_KEY,
subscriberId: 'user-123',
});
// toolkit.tools — OpenAI function tool definitions
// toolkit.handleToolCall — execute a tool call and return a tool message
```
--------------------------------
### Use Novu Inbox in Keyless Mode
Source: https://github.com/novuhq/novu/blob/next/packages/react/README.md
Import and render the Inbox component for local testing and experimentation without any configuration. This mode is ideal for quick setup and trying out Novu's features.
```jsx
import React from 'react';
import { Inbox } from '@novu/react';
export function App() {
return ;
}
```
--------------------------------
### Migration with ClickHouse Settings
Source: https://github.com/novuhq/novu/blob/next/apps/api/migrations/clickhouse-migrations/README.md
Include query-level settings, such as enabling experimental features, at the beginning of a migration file.
```sql
SET allow_experimental_json_type = 1;
CREATE TABLE IF NOT EXISTS events (data JSON) ENGINE = MergeTree ...;
```
--------------------------------
### Next.js Server Component Layout with Inbox Integration
Source: https://context7.com/novuhq/novu/llms.txt
Example of a Next.js server component layout that fetches user data, generates an HMAC hash on the server for security, and includes the client-side Notifications component.
```tsx
// app/layout.tsx (Server Component)
import { createHmac } from 'crypto';
import { Notifications } from './components/Notifications';
import { getCurrentUser } from './auth';
export default async function RootLayout({ children }: { children: React.ReactNode }) {
const user = await getCurrentUser();
// Generate HMAC on server for security
const subscriberHash = createHmac('sha256', process.env.NOVU_API_KEY!)
.update(user.id)
.digest('hex');
return (
{children}
);
}
```
--------------------------------
### Novu ClickHouse Seeder File Structure
Source: https://github.com/novuhq/novu/blob/next/apps/api/scripts/clickhouse-seeder/README.md
This overview illustrates the directory structure for the ClickHouse seeder script, highlighting the main entry point and the modular components responsible for configuration, data generation, and insertion.
```bash
apps/api/scripts/
├── seed-clickhouse.ts # Main entry point
└── clickhouse-seeder/
├── config.ts # Configuration and CLI parsing
├── time-distribution.ts # Time pattern generation
├── generators.ts # Data generation logic
├── inserter.ts # Batched ClickHouse insertion
└── README.md # This file
```
--------------------------------
### Initialize Novu Agent Toolkit for LangChain
Source: https://github.com/novuhq/novu/blob/next/packages/agent-toolkit/README.md
Creates a toolkit instance for use with the LangChain framework. The `toolkit.tools` property provides `DynamicStructuredTool[]` instances ready for LangChain agents.
```typescript
import { createNovuAgentToolkit } from '@novu/agent-toolkit/langchain';
const toolkit = await createNovuAgentToolkit({
secretKey: process.env.NOVU_SECRET_KEY,
subscriberId: 'user-123',
});
// toolkit.tools — DynamicStructuredTool[] ready for use with LangChain agents
```
--------------------------------
### Add New Workflow Template in config.ts
Source: https://github.com/novuhq/novu/blob/next/apps/api/scripts/clickhouse-seeder/README.md
Customize the types of workflows generated by adding new templates to the `WORKFLOW_TEMPLATES` array in `config.ts`. This example adds a 'support' workflow type with email and SMS channels.
```typescript
export const WORKFLOW_TEMPLATES: WorkflowTemplate[] = [
// ... existing templates
{
type: 'support',
name: 'Support Ticket',
channels: ['email', 'sms'],
weight: 0.1
},
];
```
--------------------------------
### Add New Organization Profile in config.ts
Source: https://github.com/novuhq/novu/blob/next/apps/api/scripts/clickhouse-seeder/README.md
Extend the data generation capabilities by defining new organization profiles in `config.ts`. This example shows how to add a 'startup' profile with specific ranges for daily runs, workflows, subscribers, and environments.
```typescript
export const ORGANIZATION_PROFILES = {
// ... existing profiles
startup: {
type: 'startup',
runsPerDayMin: 10,
runsPerDayMax: 100,
workflowsMin: 1,
workflowsMax: 3,
subscribersMin: 10,
subscribersMax: 100,
environmentsMin: 1,
environmentsMax: 1,
},
};
```
--------------------------------
### Integrate Novu Workflows with Vercel AI SDK
Source: https://context7.com/novuhq/novu/llms.txt
Employ the `createNovuAgentToolkit` for the AI SDK to enable Novu workflow integration within the Vercel AI SDK. This setup involves using `generateText` with the specified model and Novu's tools.
```typescript
// VERCEL AI SDK INTEGRATION
import { createNovuAgentToolkit } from '@novu/agent-toolkit/ai-sdk';
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
const aiSdkToolkit = await createNovuAgentToolkit({
secretKey: process.env.NOVU_SECRET_KEY!,
subscriberId: 'user-123',
});
const { text, toolCalls } = await generateText({
model: openai('gpt-4o'),
tools: aiSdkToolkit.tools,
prompt: 'Notify user-456 about their shipping update',
});
console.log('Response:', text);
console.log('Tool calls:', toolCalls);
```
--------------------------------
### Run Production/Staging ClickHouse Migrations
Source: https://github.com/novuhq/novu/blob/next/apps/api/migrations/clickhouse-migrations/README.md
Execute ClickHouse migrations in production or staging environments using a pnpm script that respects environment variables for connection details.
```bash
pnpm run clickhouse:migrate:prod
```
--------------------------------
### Sending Notifications with Novu Workflow SDK
Source: https://context7.com/novuhq/novu/llms.txt
Demonstrates various step types for sending notifications via email, SMS, push, chat, and in-app messages. Includes examples of delay and digest steps for workflow control. Requires payload schema definition.
```typescript
import { workflow } from '@novu/framework';
import { z } from 'zod';
const multiChannelWorkflow = workflow(
'order-confirmation',
async ({ payload, step }) => {
// EMAIL STEP - Send transactional email
await step.email('order-email', async () => ({
subject: `Order Confirmed #${payload.orderId}`,
body: `
Thank you for your order!
Order ID: ${payload.orderId}
Total: $${payload.total}
`,
}));
// SMS STEP - Send text message
await step.sms('order-sms', async () => ({
body: `Your order #${payload.orderId} is confirmed! Total: $${payload.total}`,
}));
// PUSH STEP - Send push notification
await step.push('order-push', async () => ({
subject: 'Order Confirmed',
body: `Order #${payload.orderId} has been confirmed`,
data: { orderId: payload.orderId },
}));
// CHAT STEP - Send to Slack/Discord/Teams
await step.chat('order-chat', async () => ({
body: `New order received: #${payload.orderId} - $${payload.total}`,
}));
// IN-APP STEP - Send to Novu Inbox
await step.inApp('order-inbox', async () => ({
body: `Your order #${payload.orderId} is confirmed`,
avatar: 'https://example.com/order-icon.png',
primaryAction: {
label: 'View Order',
redirect: { url: `/orders/${payload.orderId}` },
},
secondaryAction: {
label: 'Track Shipment',
redirect: { url: `/track/${payload.orderId}` },
},
data: { orderId: payload.orderId, total: payload.total },
}));
// DELAY STEP - Wait before next step
await step.delay('shipping-delay', async () => ({
amount: 2,
unit: 'hours',
}));
// DIGEST STEP - Aggregate events over time
const digest = await step.digest('daily-digest', async () => ({
amount: 24,
unit: 'hours',
lookBackWindow: { amount: 24, unit: 'hours' },
}));
// Access digest events
if (digest.events.length > 0) {
await step.email('digest-summary', async () => ({
subject: `Daily Summary: ${digest.events.length} orders`,
body: `You had ${digest.events.length} orders today.`,
}));
}
},
{
payloadSchema: z.object({
orderId: z.string(),
total: z.number(),
items: z.array(z.object({
name: z.string(),
quantity: z.number(),
})),
}),
}
);
```
--------------------------------
### Novu Agent Toolkit - Vercel AI SDK Adapter
Source: https://github.com/novuhq/novu/blob/next/packages/agent-toolkit/README.md
Information on using the Novu Agent Toolkit with the Vercel AI SDK.
```APIDOC
## Vercel AI SDK Adapter
```typescript
import { createNovuAgentToolkit } from '@novu/agent-toolkit/ai-sdk';
const toolkit = await createNovuAgentToolkit({
secretKey: process.env.NOVU_SECRET_KEY,
subscriberId: 'user-123',
});
// toolkit.tools — ToolSet compatible with generateText / streamText
```
The returned `toolkit` provides:
- **`tools`** — A `ToolSet` object that can be passed to `generateText`, `streamText`, or other Vercel AI SDK functions.
```
--------------------------------
### Novu Agent Toolkit - OpenAI Adapter
Source: https://github.com/novuhq/novu/blob/next/packages/agent-toolkit/README.md
Information on using the Novu Agent Toolkit with the OpenAI framework.
```APIDOC
## OpenAI Adapter
```typescript
import { createNovuAgentToolkit } from '@novu/agent-toolkit/openai';
const toolkit = await createNovuAgentToolkit({
secretKey: process.env.NOVU_SECRET_KEY,
subscriberId: 'user-123',
});
// toolkit.tools — OpenAI function tool definitions
// toolkit.handleToolCall — execute a tool call and return a tool message
```
The returned `toolkit` provides:
- **`tools`** — Array of OpenAI-compatible function tool definitions.
- **`handleToolCall(toolCall)`** — Executes a tool call and returns a `{ role: 'tool', tool_call_id, content }` message ready to append to the conversation.
```
--------------------------------
### Basic Editor Usage with @novu/maily-core
Source: https://github.com/novuhq/novu/blob/next/libs/maily-core/readme.md
Set up the Maily editor component with initial content and event handlers for creation and updates. Ensure the core styles are imported.
```tsx
import '@novu/maily-core/style.css';
import {
useState
} from 'react';
import { Editor } from '@novu/maily-core';
import type { Editor as TiptapEditor, JSONContent } from '@tiptap/core';
type AppProps = {
contentJson: JSONContent;
};
function App(props: AppProps) {
const { contentJson: defaultContentJson } = props;
const [editor, setEditor] = useState();
return (
);
}
```
--------------------------------
### Migration File with Comments
Source: https://github.com/novuhq/novu/blob/next/apps/api/migrations/clickhouse-migrations/README.md
Document migration files with comments explaining the purpose and any relevant ticket numbers for context.
```sql
-- Add user timezone preference
-- Ticket: NV-1234
ALTER TABLE users ADD COLUMN IF NOT EXISTS timezone String DEFAULT 'UTC';
```
--------------------------------
### Serving Novu Workflows with Remix
Source: https://context7.com/novuhq/novu/llms.txt
Integrates Novu workflows into a Remix application. Requires importing the 'serve' function from '@novu/framework/remix' and your workflow definition.
```typescript
// REMIX (app/routes/api.novu.ts)
import { serve } from '@novu/framework/remix';
import { myWorkflow } from '~/novu/workflows';
const handler = serve({ workflows: [myWorkflow] });
export { handler as loader, handler as action };
```