@serviceagent/nextjs 1.0.0
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/README.md +103 -0
- package/dist/index.d.mts +43 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.js +70 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +47 -0
- package/dist/index.mjs.map +1 -0
- package/dist/server.d.mts +54 -0
- package/dist/server.d.ts +54 -0
- package/dist/server.js +107 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +70 -0
- package/dist/server.mjs.map +1 -0
- package/package.json +75 -0
package/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# @serviceagent/nextjs
|
|
2
|
+
|
|
3
|
+
Next.js integration for ServiceAgent — provider, server client, webhook handler, and all React components.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @serviceagent/nextjs
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
### 1. Add Provider to Layout
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
// app/layout.tsx
|
|
17
|
+
import { ServiceAgentProvider } from '@serviceagent/nextjs';
|
|
18
|
+
|
|
19
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
20
|
+
return (
|
|
21
|
+
<html>
|
|
22
|
+
<body>
|
|
23
|
+
<ServiceAgentProvider>{children}</ServiceAgentProvider>
|
|
24
|
+
</body>
|
|
25
|
+
</html>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
This adds the chat widget to every page. Set environment variables:
|
|
31
|
+
|
|
32
|
+
```env
|
|
33
|
+
NEXT_PUBLIC_SERVICEAGENT_WIDGET_KEY=wid_xxxxx
|
|
34
|
+
NEXT_PUBLIC_SERVICEAGENT_API_URL=https://process.serviceagent.ai
|
|
35
|
+
SERVICEAGENT_API_KEY=your_api_key
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 2. Server-side SDK
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
// In server components or API routes
|
|
42
|
+
import { createServiceAgentClient } from '@serviceagent/nextjs/server';
|
|
43
|
+
|
|
44
|
+
const sa = createServiceAgentClient();
|
|
45
|
+
const results = await sa.searchKnowledgeBase('How to reset password?');
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 3. Webhook Handler
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
// app/api/serviceagent/webhooks/route.ts
|
|
52
|
+
import { handleWebhook } from '@serviceagent/nextjs/server';
|
|
53
|
+
|
|
54
|
+
export const POST = handleWebhook({
|
|
55
|
+
'contact.created': async (event) => {
|
|
56
|
+
console.log('New contact:', event.data);
|
|
57
|
+
},
|
|
58
|
+
'appointment.created': async (event) => {
|
|
59
|
+
console.log('New booking:', event.data);
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 4. Calendar Booking
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
import { CalendarBooking } from '@serviceagent/nextjs';
|
|
68
|
+
|
|
69
|
+
export default function BookingPage() {
|
|
70
|
+
return <CalendarBooking bookingKey="your_booking_key" />;
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 5. Voice Agent
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
import { VoiceAgent } from '@serviceagent/nextjs';
|
|
78
|
+
|
|
79
|
+
export default function CallPage() {
|
|
80
|
+
return <VoiceAgent token="session_token" orgId="org_id" />;
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Exports
|
|
85
|
+
|
|
86
|
+
### Client (`@serviceagent/nextjs`)
|
|
87
|
+
|
|
88
|
+
- `ServiceAgentProvider` — Layout provider with chat widget
|
|
89
|
+
- `Chat`, `ChatIframe` — Chat widget components
|
|
90
|
+
- `CalendarBooking` — Calendar booking widget
|
|
91
|
+
- `VoiceAgent` — Voice agent component
|
|
92
|
+
- `useServiceAgent` — Chat control hook
|
|
93
|
+
- All AIVA voice hooks and components
|
|
94
|
+
|
|
95
|
+
### Server (`@serviceagent/nextjs/server`)
|
|
96
|
+
|
|
97
|
+
- `createServiceAgentClient()` — Server-side SDK client
|
|
98
|
+
- `handleWebhook(handlers)` — Webhook route handler factory
|
|
99
|
+
- `ServiceAgent` — SDK class (re-exported)
|
|
100
|
+
|
|
101
|
+
## License
|
|
102
|
+
|
|
103
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { FC, ReactNode } from 'react';
|
|
2
|
+
export { AivaCallButton, AivaProvider, AivaTranscriptView, AivaTurnIndicator, CalendarBooking, CalendarBookingProps, Chat, ChatIframe, ChatProps, VoiceAgent, VoiceAgentProps, useAiva, useAivaCallState, useAivaTranscript, useServiceAgent } from '@serviceagent/react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @serviceagent/nextjs — Client-side entry
|
|
6
|
+
*
|
|
7
|
+
* Re-exports all React components and adds Next.js-specific wrappers.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
interface ServiceAgentProviderProps {
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
/** Widget key override (defaults to env var) */
|
|
13
|
+
widgetKey?: string;
|
|
14
|
+
/** API URL override (defaults to env var) */
|
|
15
|
+
apiUrl?: string;
|
|
16
|
+
/** Enable chat widget in provider */
|
|
17
|
+
chat?: boolean;
|
|
18
|
+
/** Enable debug mode */
|
|
19
|
+
debug?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Wrap your Next.js app layout with this provider to enable ServiceAgent
|
|
23
|
+
* across all pages.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```tsx
|
|
27
|
+
* // app/layout.tsx
|
|
28
|
+
* import { ServiceAgentProvider } from '@serviceagent/nextjs';
|
|
29
|
+
*
|
|
30
|
+
* export default function RootLayout({ children }) {
|
|
31
|
+
* return (
|
|
32
|
+
* <html>
|
|
33
|
+
* <body>
|
|
34
|
+
* <ServiceAgentProvider>{children}</ServiceAgentProvider>
|
|
35
|
+
* </body>
|
|
36
|
+
* </html>
|
|
37
|
+
* );
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
declare const ServiceAgentProvider: FC<ServiceAgentProviderProps>;
|
|
42
|
+
|
|
43
|
+
export { ServiceAgentProvider, type ServiceAgentProviderProps };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { FC, ReactNode } from 'react';
|
|
2
|
+
export { AivaCallButton, AivaProvider, AivaTranscriptView, AivaTurnIndicator, CalendarBooking, CalendarBookingProps, Chat, ChatIframe, ChatProps, VoiceAgent, VoiceAgentProps, useAiva, useAivaCallState, useAivaTranscript, useServiceAgent } from '@serviceagent/react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @serviceagent/nextjs — Client-side entry
|
|
6
|
+
*
|
|
7
|
+
* Re-exports all React components and adds Next.js-specific wrappers.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
interface ServiceAgentProviderProps {
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
/** Widget key override (defaults to env var) */
|
|
13
|
+
widgetKey?: string;
|
|
14
|
+
/** API URL override (defaults to env var) */
|
|
15
|
+
apiUrl?: string;
|
|
16
|
+
/** Enable chat widget in provider */
|
|
17
|
+
chat?: boolean;
|
|
18
|
+
/** Enable debug mode */
|
|
19
|
+
debug?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Wrap your Next.js app layout with this provider to enable ServiceAgent
|
|
23
|
+
* across all pages.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```tsx
|
|
27
|
+
* // app/layout.tsx
|
|
28
|
+
* import { ServiceAgentProvider } from '@serviceagent/nextjs';
|
|
29
|
+
*
|
|
30
|
+
* export default function RootLayout({ children }) {
|
|
31
|
+
* return (
|
|
32
|
+
* <html>
|
|
33
|
+
* <body>
|
|
34
|
+
* <ServiceAgentProvider>{children}</ServiceAgentProvider>
|
|
35
|
+
* </body>
|
|
36
|
+
* </html>
|
|
37
|
+
* );
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
declare const ServiceAgentProvider: FC<ServiceAgentProviderProps>;
|
|
42
|
+
|
|
43
|
+
export { ServiceAgentProvider, type ServiceAgentProviderProps };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/index.tsx
|
|
22
|
+
var index_exports = {};
|
|
23
|
+
__export(index_exports, {
|
|
24
|
+
AivaCallButton: () => import_react2.AivaCallButton,
|
|
25
|
+
AivaProvider: () => import_react2.AivaProvider,
|
|
26
|
+
AivaTranscriptView: () => import_react2.AivaTranscriptView,
|
|
27
|
+
AivaTurnIndicator: () => import_react2.AivaTurnIndicator,
|
|
28
|
+
CalendarBooking: () => import_react2.CalendarBooking,
|
|
29
|
+
Chat: () => import_react2.Chat,
|
|
30
|
+
ChatIframe: () => import_react2.ChatIframe,
|
|
31
|
+
ServiceAgentProvider: () => ServiceAgentProvider,
|
|
32
|
+
VoiceAgent: () => import_react2.VoiceAgent,
|
|
33
|
+
useAiva: () => import_react2.useAiva,
|
|
34
|
+
useAivaCallState: () => import_react2.useAivaCallState,
|
|
35
|
+
useAivaTranscript: () => import_react2.useAivaTranscript,
|
|
36
|
+
useServiceAgent: () => import_react2.useServiceAgent
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(index_exports);
|
|
39
|
+
var import_react = require("@serviceagent/react");
|
|
40
|
+
var import_react2 = require("@serviceagent/react");
|
|
41
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
42
|
+
var ServiceAgentProvider = ({
|
|
43
|
+
children,
|
|
44
|
+
widgetKey,
|
|
45
|
+
apiUrl,
|
|
46
|
+
chat = true,
|
|
47
|
+
debug = false
|
|
48
|
+
}) => {
|
|
49
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
50
|
+
children,
|
|
51
|
+
chat && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.Chat, { widgetKey, apiUrl, debug })
|
|
52
|
+
] });
|
|
53
|
+
};
|
|
54
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
55
|
+
0 && (module.exports = {
|
|
56
|
+
AivaCallButton,
|
|
57
|
+
AivaProvider,
|
|
58
|
+
AivaTranscriptView,
|
|
59
|
+
AivaTurnIndicator,
|
|
60
|
+
CalendarBooking,
|
|
61
|
+
Chat,
|
|
62
|
+
ChatIframe,
|
|
63
|
+
ServiceAgentProvider,
|
|
64
|
+
VoiceAgent,
|
|
65
|
+
useAiva,
|
|
66
|
+
useAivaCallState,
|
|
67
|
+
useAivaTranscript,
|
|
68
|
+
useServiceAgent
|
|
69
|
+
});
|
|
70
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx"],"sourcesContent":["'use client';\n\n/**\n * @serviceagent/nextjs — Client-side entry\n *\n * Re-exports all React components and adds Next.js-specific wrappers.\n */\n\nimport React, { type FC, type ReactNode } from 'react';\nimport { Chat as ServiceAgentChat } from '@serviceagent/react';\n\n// Re-export everything from @serviceagent/react\nexport {\n Chat,\n ChatIframe,\n CalendarBooking,\n VoiceAgent,\n useServiceAgent,\n AivaProvider,\n useAiva,\n useAivaCallState,\n useAivaTranscript,\n AivaCallButton,\n AivaTurnIndicator,\n AivaTranscriptView,\n} from '@serviceagent/react';\n\nexport type { ChatProps, CalendarBookingProps, VoiceAgentProps } from '@serviceagent/react';\n\n// ---------------------------------------------------------------------------\n// ServiceAgentProvider — drop into app/layout.tsx\n// ---------------------------------------------------------------------------\n\nexport interface ServiceAgentProviderProps {\n children: ReactNode;\n /** Widget key override (defaults to env var) */\n widgetKey?: string;\n /** API URL override (defaults to env var) */\n apiUrl?: string;\n /** Enable chat widget in provider */\n chat?: boolean;\n /** Enable debug mode */\n debug?: boolean;\n}\n\n/**\n * Wrap your Next.js app layout with this provider to enable ServiceAgent\n * across all pages.\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import { ServiceAgentProvider } from '@serviceagent/nextjs';\n *\n * export default function RootLayout({ children }) {\n * return (\n * <html>\n * <body>\n * <ServiceAgentProvider>{children}</ServiceAgentProvider>\n * </body>\n * </html>\n * );\n * }\n * ```\n */\nexport const ServiceAgentProvider: FC<ServiceAgentProviderProps> = ({\n children,\n widgetKey,\n apiUrl,\n chat = true,\n debug = false,\n}) => {\n return (\n <>\n {children}\n {chat && <ServiceAgentChat widgetKey={widgetKey} apiUrl={apiUrl} debug={debug} />}\n </>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,mBAAyC;AAGzC,IAAAA,gBAaO;AAgDH;AARG,IAAM,uBAAsD,CAAC;AAAA,EAClE;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,QAAQ;AACV,MAAM;AACJ,SACE,4EACG;AAAA;AAAA,IACA,QAAQ,4CAAC,aAAAC,MAAA,EAAiB,WAAsB,QAAgB,OAAc;AAAA,KACjF;AAEJ;","names":["import_react","ServiceAgentChat"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/index.tsx
|
|
4
|
+
import { Chat as ServiceAgentChat } from "@serviceagent/react";
|
|
5
|
+
import {
|
|
6
|
+
Chat,
|
|
7
|
+
ChatIframe,
|
|
8
|
+
CalendarBooking,
|
|
9
|
+
VoiceAgent,
|
|
10
|
+
useServiceAgent,
|
|
11
|
+
AivaProvider,
|
|
12
|
+
useAiva,
|
|
13
|
+
useAivaCallState,
|
|
14
|
+
useAivaTranscript,
|
|
15
|
+
AivaCallButton,
|
|
16
|
+
AivaTurnIndicator,
|
|
17
|
+
AivaTranscriptView
|
|
18
|
+
} from "@serviceagent/react";
|
|
19
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
20
|
+
var ServiceAgentProvider = ({
|
|
21
|
+
children,
|
|
22
|
+
widgetKey,
|
|
23
|
+
apiUrl,
|
|
24
|
+
chat = true,
|
|
25
|
+
debug = false
|
|
26
|
+
}) => {
|
|
27
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
28
|
+
children,
|
|
29
|
+
chat && /* @__PURE__ */ jsx(ServiceAgentChat, { widgetKey, apiUrl, debug })
|
|
30
|
+
] });
|
|
31
|
+
};
|
|
32
|
+
export {
|
|
33
|
+
AivaCallButton,
|
|
34
|
+
AivaProvider,
|
|
35
|
+
AivaTranscriptView,
|
|
36
|
+
AivaTurnIndicator,
|
|
37
|
+
CalendarBooking,
|
|
38
|
+
Chat,
|
|
39
|
+
ChatIframe,
|
|
40
|
+
ServiceAgentProvider,
|
|
41
|
+
VoiceAgent,
|
|
42
|
+
useAiva,
|
|
43
|
+
useAivaCallState,
|
|
44
|
+
useAivaTranscript,
|
|
45
|
+
useServiceAgent
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx"],"sourcesContent":["'use client';\n\n/**\n * @serviceagent/nextjs — Client-side entry\n *\n * Re-exports all React components and adds Next.js-specific wrappers.\n */\n\nimport React, { type FC, type ReactNode } from 'react';\nimport { Chat as ServiceAgentChat } from '@serviceagent/react';\n\n// Re-export everything from @serviceagent/react\nexport {\n Chat,\n ChatIframe,\n CalendarBooking,\n VoiceAgent,\n useServiceAgent,\n AivaProvider,\n useAiva,\n useAivaCallState,\n useAivaTranscript,\n AivaCallButton,\n AivaTurnIndicator,\n AivaTranscriptView,\n} from '@serviceagent/react';\n\nexport type { ChatProps, CalendarBookingProps, VoiceAgentProps } from '@serviceagent/react';\n\n// ---------------------------------------------------------------------------\n// ServiceAgentProvider — drop into app/layout.tsx\n// ---------------------------------------------------------------------------\n\nexport interface ServiceAgentProviderProps {\n children: ReactNode;\n /** Widget key override (defaults to env var) */\n widgetKey?: string;\n /** API URL override (defaults to env var) */\n apiUrl?: string;\n /** Enable chat widget in provider */\n chat?: boolean;\n /** Enable debug mode */\n debug?: boolean;\n}\n\n/**\n * Wrap your Next.js app layout with this provider to enable ServiceAgent\n * across all pages.\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import { ServiceAgentProvider } from '@serviceagent/nextjs';\n *\n * export default function RootLayout({ children }) {\n * return (\n * <html>\n * <body>\n * <ServiceAgentProvider>{children}</ServiceAgentProvider>\n * </body>\n * </html>\n * );\n * }\n * ```\n */\nexport const ServiceAgentProvider: FC<ServiceAgentProviderProps> = ({\n children,\n widgetKey,\n apiUrl,\n chat = true,\n debug = false,\n}) => {\n return (\n <>\n {children}\n {chat && <ServiceAgentChat widgetKey={widgetKey} apiUrl={apiUrl} debug={debug} />}\n </>\n );\n};\n"],"mappings":";;;AASA,SAAS,QAAQ,wBAAwB;AAGzC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAgDH,mBAEW,KAFX;AARG,IAAM,uBAAsD,CAAC;AAAA,EAClE;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,QAAQ;AACV,MAAM;AACJ,SACE,iCACG;AAAA;AAAA,IACA,QAAQ,oBAAC,oBAAiB,WAAsB,QAAgB,OAAc;AAAA,KACjF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ServiceAgentConfig, ServiceAgent } from '@serviceagent/sdk';
|
|
2
|
+
export { ServiceAgent, ServiceAgentConfig } from '@serviceagent/sdk';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @serviceagent/nextjs/server — Server-side utilities
|
|
6
|
+
*
|
|
7
|
+
* Use in server components, API routes, and middleware.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Create a ServiceAgent server client. Reads SERVICEAGENT_API_KEY from env.
|
|
12
|
+
* Instances are cached for the lifetime of the process.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { createServiceAgentClient } from '@serviceagent/nextjs/server';
|
|
17
|
+
*
|
|
18
|
+
* const sa = createServiceAgentClient();
|
|
19
|
+
* const results = await sa.searchKnowledgeBase('query');
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
declare function createServiceAgentClient(config?: Partial<ServiceAgentConfig>): ServiceAgent;
|
|
23
|
+
interface WebhookEvent {
|
|
24
|
+
event: string;
|
|
25
|
+
data: Record<string, unknown>;
|
|
26
|
+
timestamp: string;
|
|
27
|
+
webhookId?: string;
|
|
28
|
+
}
|
|
29
|
+
type WebhookHandler = (event: WebhookEvent) => void | Promise<void>;
|
|
30
|
+
interface HandleWebhookOptions {
|
|
31
|
+
/** Secret for signature verification (defaults to SERVICEAGENT_WEBHOOK_SECRET env var) */
|
|
32
|
+
secret?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create a Next.js API route handler for ServiceAgent webhooks.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* // app/api/serviceagent/webhooks/route.ts
|
|
40
|
+
* import { handleWebhook } from '@serviceagent/nextjs/server';
|
|
41
|
+
*
|
|
42
|
+
* export const POST = handleWebhook({
|
|
43
|
+
* 'contact.created': async (event) => {
|
|
44
|
+
* console.log('New contact:', event.data);
|
|
45
|
+
* },
|
|
46
|
+
* 'appointment.created': async (event) => {
|
|
47
|
+
* console.log('New booking:', event.data);
|
|
48
|
+
* },
|
|
49
|
+
* });
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
declare function handleWebhook(handlers: Record<string, WebhookHandler>, options?: HandleWebhookOptions): (request: Request) => Promise<Response>;
|
|
53
|
+
|
|
54
|
+
export { type HandleWebhookOptions, type WebhookEvent, type WebhookHandler, createServiceAgentClient, handleWebhook };
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ServiceAgentConfig, ServiceAgent } from '@serviceagent/sdk';
|
|
2
|
+
export { ServiceAgent, ServiceAgentConfig } from '@serviceagent/sdk';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @serviceagent/nextjs/server — Server-side utilities
|
|
6
|
+
*
|
|
7
|
+
* Use in server components, API routes, and middleware.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Create a ServiceAgent server client. Reads SERVICEAGENT_API_KEY from env.
|
|
12
|
+
* Instances are cached for the lifetime of the process.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { createServiceAgentClient } from '@serviceagent/nextjs/server';
|
|
17
|
+
*
|
|
18
|
+
* const sa = createServiceAgentClient();
|
|
19
|
+
* const results = await sa.searchKnowledgeBase('query');
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
declare function createServiceAgentClient(config?: Partial<ServiceAgentConfig>): ServiceAgent;
|
|
23
|
+
interface WebhookEvent {
|
|
24
|
+
event: string;
|
|
25
|
+
data: Record<string, unknown>;
|
|
26
|
+
timestamp: string;
|
|
27
|
+
webhookId?: string;
|
|
28
|
+
}
|
|
29
|
+
type WebhookHandler = (event: WebhookEvent) => void | Promise<void>;
|
|
30
|
+
interface HandleWebhookOptions {
|
|
31
|
+
/** Secret for signature verification (defaults to SERVICEAGENT_WEBHOOK_SECRET env var) */
|
|
32
|
+
secret?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create a Next.js API route handler for ServiceAgent webhooks.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* // app/api/serviceagent/webhooks/route.ts
|
|
40
|
+
* import { handleWebhook } from '@serviceagent/nextjs/server';
|
|
41
|
+
*
|
|
42
|
+
* export const POST = handleWebhook({
|
|
43
|
+
* 'contact.created': async (event) => {
|
|
44
|
+
* console.log('New contact:', event.data);
|
|
45
|
+
* },
|
|
46
|
+
* 'appointment.created': async (event) => {
|
|
47
|
+
* console.log('New booking:', event.data);
|
|
48
|
+
* },
|
|
49
|
+
* });
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
declare function handleWebhook(handlers: Record<string, WebhookHandler>, options?: HandleWebhookOptions): (request: Request) => Promise<Response>;
|
|
53
|
+
|
|
54
|
+
export { type HandleWebhookOptions, type WebhookEvent, type WebhookHandler, createServiceAgentClient, handleWebhook };
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/server.ts
|
|
31
|
+
var server_exports = {};
|
|
32
|
+
__export(server_exports, {
|
|
33
|
+
ServiceAgent: () => import_sdk2.ServiceAgent,
|
|
34
|
+
createServiceAgentClient: () => createServiceAgentClient,
|
|
35
|
+
handleWebhook: () => handleWebhook
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(server_exports);
|
|
38
|
+
var import_sdk = require("@serviceagent/sdk");
|
|
39
|
+
var import_crypto = __toESM(require("crypto"));
|
|
40
|
+
var import_sdk2 = require("@serviceagent/sdk");
|
|
41
|
+
var cachedClient = null;
|
|
42
|
+
function createServiceAgentClient(config) {
|
|
43
|
+
if (cachedClient && !config) return cachedClient;
|
|
44
|
+
const client = new import_sdk.ServiceAgent({
|
|
45
|
+
apiKey: process.env.SERVICEAGENT_API_KEY,
|
|
46
|
+
baseURL: process.env.SERVICEAGENT_API_URL || "https://process.serviceagent.ai",
|
|
47
|
+
...config
|
|
48
|
+
});
|
|
49
|
+
if (!config) cachedClient = client;
|
|
50
|
+
return client;
|
|
51
|
+
}
|
|
52
|
+
function handleWebhook(handlers, options) {
|
|
53
|
+
return async (request) => {
|
|
54
|
+
const secret = options?.secret || process.env.SERVICEAGENT_WEBHOOK_SECRET || "";
|
|
55
|
+
let body;
|
|
56
|
+
try {
|
|
57
|
+
body = await request.text();
|
|
58
|
+
} catch {
|
|
59
|
+
return new Response(JSON.stringify({ error: "Invalid body" }), {
|
|
60
|
+
status: 400,
|
|
61
|
+
headers: { "Content-Type": "application/json" }
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
if (secret) {
|
|
65
|
+
const signature = request.headers.get?.("x-serviceagent-signature") || "";
|
|
66
|
+
const expected = import_crypto.default.createHmac("sha256", secret).update(body).digest("hex");
|
|
67
|
+
if (signature !== expected) {
|
|
68
|
+
return new Response(JSON.stringify({ error: "Invalid signature" }), {
|
|
69
|
+
status: 401,
|
|
70
|
+
headers: { "Content-Type": "application/json" }
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
let event;
|
|
75
|
+
try {
|
|
76
|
+
event = JSON.parse(body);
|
|
77
|
+
} catch {
|
|
78
|
+
return new Response(JSON.stringify({ error: "Invalid JSON" }), {
|
|
79
|
+
status: 400,
|
|
80
|
+
headers: { "Content-Type": "application/json" }
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
const handler = handlers[event.event];
|
|
84
|
+
if (handler) {
|
|
85
|
+
try {
|
|
86
|
+
await handler(event);
|
|
87
|
+
} catch (err) {
|
|
88
|
+
console.error(`[ServiceAgent] Webhook handler error for ${event.event}:`, err);
|
|
89
|
+
return new Response(JSON.stringify({ error: "Handler failed" }), {
|
|
90
|
+
status: 500,
|
|
91
|
+
headers: { "Content-Type": "application/json" }
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return new Response(JSON.stringify({ received: true }), {
|
|
96
|
+
status: 200,
|
|
97
|
+
headers: { "Content-Type": "application/json" }
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
102
|
+
0 && (module.exports = {
|
|
103
|
+
ServiceAgent,
|
|
104
|
+
createServiceAgentClient,
|
|
105
|
+
handleWebhook
|
|
106
|
+
});
|
|
107
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["/**\n * @serviceagent/nextjs/server — Server-side utilities\n *\n * Use in server components, API routes, and middleware.\n */\n\nimport { ServiceAgent, type ServiceAgentConfig } from '@serviceagent/sdk';\nimport crypto from 'crypto';\n\n// ---------------------------------------------------------------------------\n// Server-side client\n// ---------------------------------------------------------------------------\n\nlet cachedClient: ServiceAgent | null = null;\n\n/**\n * Create a ServiceAgent server client. Reads SERVICEAGENT_API_KEY from env.\n * Instances are cached for the lifetime of the process.\n *\n * @example\n * ```ts\n * import { createServiceAgentClient } from '@serviceagent/nextjs/server';\n *\n * const sa = createServiceAgentClient();\n * const results = await sa.searchKnowledgeBase('query');\n * ```\n */\nexport function createServiceAgentClient(config?: Partial<ServiceAgentConfig>): ServiceAgent {\n if (cachedClient && !config) return cachedClient;\n\n const client = new ServiceAgent({\n apiKey: process.env.SERVICEAGENT_API_KEY,\n baseURL: process.env.SERVICEAGENT_API_URL || 'https://process.serviceagent.ai',\n ...config,\n });\n\n if (!config) cachedClient = client;\n return client;\n}\n\n// ---------------------------------------------------------------------------\n// Webhook handler\n// ---------------------------------------------------------------------------\n\nexport interface WebhookEvent {\n event: string;\n data: Record<string, unknown>;\n timestamp: string;\n webhookId?: string;\n}\n\nexport type WebhookHandler = (event: WebhookEvent) => void | Promise<void>;\n\nexport interface HandleWebhookOptions {\n /** Secret for signature verification (defaults to SERVICEAGENT_WEBHOOK_SECRET env var) */\n secret?: string;\n}\n\n/**\n * Create a Next.js API route handler for ServiceAgent webhooks.\n *\n * @example\n * ```ts\n * // app/api/serviceagent/webhooks/route.ts\n * import { handleWebhook } from '@serviceagent/nextjs/server';\n *\n * export const POST = handleWebhook({\n * 'contact.created': async (event) => {\n * console.log('New contact:', event.data);\n * },\n * 'appointment.created': async (event) => {\n * console.log('New booking:', event.data);\n * },\n * });\n * ```\n */\nexport function handleWebhook(\n handlers: Record<string, WebhookHandler>,\n options?: HandleWebhookOptions,\n) {\n return async (request: Request): Promise<Response> => {\n const secret = options?.secret || process.env.SERVICEAGENT_WEBHOOK_SECRET || '';\n\n let body: string;\n try {\n body = await request.text();\n } catch {\n return new Response(JSON.stringify({ error: 'Invalid body' }), {\n status: 400,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n // Verify signature\n if (secret) {\n const signature = (request.headers as any).get?.('x-serviceagent-signature') || '';\n const expected = crypto.createHmac('sha256', secret).update(body).digest('hex');\n if (signature !== expected) {\n return new Response(JSON.stringify({ error: 'Invalid signature' }), {\n status: 401,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n }\n\n let event: WebhookEvent;\n try {\n event = JSON.parse(body);\n } catch {\n return new Response(JSON.stringify({ error: 'Invalid JSON' }), {\n status: 400,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n // Dispatch to handler\n const handler = handlers[event.event];\n if (handler) {\n try {\n await handler(event);\n } catch (err) {\n console.error(`[ServiceAgent] Webhook handler error for ${event.event}:`, err);\n return new Response(JSON.stringify({ error: 'Handler failed' }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n }\n\n return new Response(JSON.stringify({ received: true }), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n };\n}\n\n// Re-export SDK types\nexport { ServiceAgent } from '@serviceagent/sdk';\nexport type { ServiceAgentConfig } from '@serviceagent/sdk';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,iBAAsD;AACtD,oBAAmB;AAkInB,IAAAA,cAA6B;AA5H7B,IAAI,eAAoC;AAcjC,SAAS,yBAAyB,QAAoD;AAC3F,MAAI,gBAAgB,CAAC,OAAQ,QAAO;AAEpC,QAAM,SAAS,IAAI,wBAAa;AAAA,IAC9B,QAAQ,QAAQ,IAAI;AAAA,IACpB,SAAS,QAAQ,IAAI,wBAAwB;AAAA,IAC7C,GAAG;AAAA,EACL,CAAC;AAED,MAAI,CAAC,OAAQ,gBAAe;AAC5B,SAAO;AACT;AAsCO,SAAS,cACd,UACA,SACA;AACA,SAAO,OAAO,YAAwC;AACpD,UAAM,SAAS,SAAS,UAAU,QAAQ,IAAI,+BAA+B;AAE7E,QAAI;AACJ,QAAI;AACF,aAAO,MAAM,QAAQ,KAAK;AAAA,IAC5B,QAAQ;AACN,aAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,eAAe,CAAC,GAAG;AAAA,QAC7D,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAChD,CAAC;AAAA,IACH;AAGA,QAAI,QAAQ;AACV,YAAM,YAAa,QAAQ,QAAgB,MAAM,0BAA0B,KAAK;AAChF,YAAM,WAAW,cAAAC,QAAO,WAAW,UAAU,MAAM,EAAE,OAAO,IAAI,EAAE,OAAO,KAAK;AAC9E,UAAI,cAAc,UAAU;AAC1B,eAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,oBAAoB,CAAC,GAAG;AAAA,UAClE,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAChD,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI;AACJ,QAAI;AACF,cAAQ,KAAK,MAAM,IAAI;AAAA,IACzB,QAAQ;AACN,aAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,eAAe,CAAC,GAAG;AAAA,QAC7D,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAChD,CAAC;AAAA,IACH;AAGA,UAAM,UAAU,SAAS,MAAM,KAAK;AACpC,QAAI,SAAS;AACX,UAAI;AACF,cAAM,QAAQ,KAAK;AAAA,MACrB,SAAS,KAAK;AACZ,gBAAQ,MAAM,4CAA4C,MAAM,KAAK,KAAK,GAAG;AAC7E,eAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,iBAAiB,CAAC,GAAG;AAAA,UAC/D,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAChD,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO,IAAI,SAAS,KAAK,UAAU,EAAE,UAAU,KAAK,CAAC,GAAG;AAAA,MACtD,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAChD,CAAC;AAAA,EACH;AACF;","names":["import_sdk","crypto"]}
|
package/dist/server.mjs
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// src/server.ts
|
|
2
|
+
import { ServiceAgent } from "@serviceagent/sdk";
|
|
3
|
+
import crypto from "crypto";
|
|
4
|
+
import { ServiceAgent as ServiceAgent2 } from "@serviceagent/sdk";
|
|
5
|
+
var cachedClient = null;
|
|
6
|
+
function createServiceAgentClient(config) {
|
|
7
|
+
if (cachedClient && !config) return cachedClient;
|
|
8
|
+
const client = new ServiceAgent({
|
|
9
|
+
apiKey: process.env.SERVICEAGENT_API_KEY,
|
|
10
|
+
baseURL: process.env.SERVICEAGENT_API_URL || "https://process.serviceagent.ai",
|
|
11
|
+
...config
|
|
12
|
+
});
|
|
13
|
+
if (!config) cachedClient = client;
|
|
14
|
+
return client;
|
|
15
|
+
}
|
|
16
|
+
function handleWebhook(handlers, options) {
|
|
17
|
+
return async (request) => {
|
|
18
|
+
const secret = options?.secret || process.env.SERVICEAGENT_WEBHOOK_SECRET || "";
|
|
19
|
+
let body;
|
|
20
|
+
try {
|
|
21
|
+
body = await request.text();
|
|
22
|
+
} catch {
|
|
23
|
+
return new Response(JSON.stringify({ error: "Invalid body" }), {
|
|
24
|
+
status: 400,
|
|
25
|
+
headers: { "Content-Type": "application/json" }
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
if (secret) {
|
|
29
|
+
const signature = request.headers.get?.("x-serviceagent-signature") || "";
|
|
30
|
+
const expected = crypto.createHmac("sha256", secret).update(body).digest("hex");
|
|
31
|
+
if (signature !== expected) {
|
|
32
|
+
return new Response(JSON.stringify({ error: "Invalid signature" }), {
|
|
33
|
+
status: 401,
|
|
34
|
+
headers: { "Content-Type": "application/json" }
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
let event;
|
|
39
|
+
try {
|
|
40
|
+
event = JSON.parse(body);
|
|
41
|
+
} catch {
|
|
42
|
+
return new Response(JSON.stringify({ error: "Invalid JSON" }), {
|
|
43
|
+
status: 400,
|
|
44
|
+
headers: { "Content-Type": "application/json" }
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
const handler = handlers[event.event];
|
|
48
|
+
if (handler) {
|
|
49
|
+
try {
|
|
50
|
+
await handler(event);
|
|
51
|
+
} catch (err) {
|
|
52
|
+
console.error(`[ServiceAgent] Webhook handler error for ${event.event}:`, err);
|
|
53
|
+
return new Response(JSON.stringify({ error: "Handler failed" }), {
|
|
54
|
+
status: 500,
|
|
55
|
+
headers: { "Content-Type": "application/json" }
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return new Response(JSON.stringify({ received: true }), {
|
|
60
|
+
status: 200,
|
|
61
|
+
headers: { "Content-Type": "application/json" }
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export {
|
|
66
|
+
ServiceAgent2 as ServiceAgent,
|
|
67
|
+
createServiceAgentClient,
|
|
68
|
+
handleWebhook
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=server.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["/**\n * @serviceagent/nextjs/server — Server-side utilities\n *\n * Use in server components, API routes, and middleware.\n */\n\nimport { ServiceAgent, type ServiceAgentConfig } from '@serviceagent/sdk';\nimport crypto from 'crypto';\n\n// ---------------------------------------------------------------------------\n// Server-side client\n// ---------------------------------------------------------------------------\n\nlet cachedClient: ServiceAgent | null = null;\n\n/**\n * Create a ServiceAgent server client. Reads SERVICEAGENT_API_KEY from env.\n * Instances are cached for the lifetime of the process.\n *\n * @example\n * ```ts\n * import { createServiceAgentClient } from '@serviceagent/nextjs/server';\n *\n * const sa = createServiceAgentClient();\n * const results = await sa.searchKnowledgeBase('query');\n * ```\n */\nexport function createServiceAgentClient(config?: Partial<ServiceAgentConfig>): ServiceAgent {\n if (cachedClient && !config) return cachedClient;\n\n const client = new ServiceAgent({\n apiKey: process.env.SERVICEAGENT_API_KEY,\n baseURL: process.env.SERVICEAGENT_API_URL || 'https://process.serviceagent.ai',\n ...config,\n });\n\n if (!config) cachedClient = client;\n return client;\n}\n\n// ---------------------------------------------------------------------------\n// Webhook handler\n// ---------------------------------------------------------------------------\n\nexport interface WebhookEvent {\n event: string;\n data: Record<string, unknown>;\n timestamp: string;\n webhookId?: string;\n}\n\nexport type WebhookHandler = (event: WebhookEvent) => void | Promise<void>;\n\nexport interface HandleWebhookOptions {\n /** Secret for signature verification (defaults to SERVICEAGENT_WEBHOOK_SECRET env var) */\n secret?: string;\n}\n\n/**\n * Create a Next.js API route handler for ServiceAgent webhooks.\n *\n * @example\n * ```ts\n * // app/api/serviceagent/webhooks/route.ts\n * import { handleWebhook } from '@serviceagent/nextjs/server';\n *\n * export const POST = handleWebhook({\n * 'contact.created': async (event) => {\n * console.log('New contact:', event.data);\n * },\n * 'appointment.created': async (event) => {\n * console.log('New booking:', event.data);\n * },\n * });\n * ```\n */\nexport function handleWebhook(\n handlers: Record<string, WebhookHandler>,\n options?: HandleWebhookOptions,\n) {\n return async (request: Request): Promise<Response> => {\n const secret = options?.secret || process.env.SERVICEAGENT_WEBHOOK_SECRET || '';\n\n let body: string;\n try {\n body = await request.text();\n } catch {\n return new Response(JSON.stringify({ error: 'Invalid body' }), {\n status: 400,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n // Verify signature\n if (secret) {\n const signature = (request.headers as any).get?.('x-serviceagent-signature') || '';\n const expected = crypto.createHmac('sha256', secret).update(body).digest('hex');\n if (signature !== expected) {\n return new Response(JSON.stringify({ error: 'Invalid signature' }), {\n status: 401,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n }\n\n let event: WebhookEvent;\n try {\n event = JSON.parse(body);\n } catch {\n return new Response(JSON.stringify({ error: 'Invalid JSON' }), {\n status: 400,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n // Dispatch to handler\n const handler = handlers[event.event];\n if (handler) {\n try {\n await handler(event);\n } catch (err) {\n console.error(`[ServiceAgent] Webhook handler error for ${event.event}:`, err);\n return new Response(JSON.stringify({ error: 'Handler failed' }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n }\n\n return new Response(JSON.stringify({ received: true }), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n };\n}\n\n// Re-export SDK types\nexport { ServiceAgent } from '@serviceagent/sdk';\nexport type { ServiceAgentConfig } from '@serviceagent/sdk';\n"],"mappings":";AAMA,SAAS,oBAA6C;AACtD,OAAO,YAAY;AAkInB,SAAS,gBAAAA,qBAAoB;AA5H7B,IAAI,eAAoC;AAcjC,SAAS,yBAAyB,QAAoD;AAC3F,MAAI,gBAAgB,CAAC,OAAQ,QAAO;AAEpC,QAAM,SAAS,IAAI,aAAa;AAAA,IAC9B,QAAQ,QAAQ,IAAI;AAAA,IACpB,SAAS,QAAQ,IAAI,wBAAwB;AAAA,IAC7C,GAAG;AAAA,EACL,CAAC;AAED,MAAI,CAAC,OAAQ,gBAAe;AAC5B,SAAO;AACT;AAsCO,SAAS,cACd,UACA,SACA;AACA,SAAO,OAAO,YAAwC;AACpD,UAAM,SAAS,SAAS,UAAU,QAAQ,IAAI,+BAA+B;AAE7E,QAAI;AACJ,QAAI;AACF,aAAO,MAAM,QAAQ,KAAK;AAAA,IAC5B,QAAQ;AACN,aAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,eAAe,CAAC,GAAG;AAAA,QAC7D,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAChD,CAAC;AAAA,IACH;AAGA,QAAI,QAAQ;AACV,YAAM,YAAa,QAAQ,QAAgB,MAAM,0BAA0B,KAAK;AAChF,YAAM,WAAW,OAAO,WAAW,UAAU,MAAM,EAAE,OAAO,IAAI,EAAE,OAAO,KAAK;AAC9E,UAAI,cAAc,UAAU;AAC1B,eAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,oBAAoB,CAAC,GAAG;AAAA,UAClE,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAChD,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI;AACJ,QAAI;AACF,cAAQ,KAAK,MAAM,IAAI;AAAA,IACzB,QAAQ;AACN,aAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,eAAe,CAAC,GAAG;AAAA,QAC7D,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAChD,CAAC;AAAA,IACH;AAGA,UAAM,UAAU,SAAS,MAAM,KAAK;AACpC,QAAI,SAAS;AACX,UAAI;AACF,cAAM,QAAQ,KAAK;AAAA,MACrB,SAAS,KAAK;AACZ,gBAAQ,MAAM,4CAA4C,MAAM,KAAK,KAAK,GAAG;AAC7E,eAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,iBAAiB,CAAC,GAAG;AAAA,UAC/D,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAChD,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO,IAAI,SAAS,KAAK,UAAU,EAAE,UAAU,KAAK,CAAC,GAAG;AAAA,MACtD,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAChD,CAAC;AAAA,EACH;AACF;","names":["ServiceAgent"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@serviceagent/nextjs",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "ServiceAgent Next.js integration — provider, server client, webhook handler, and middleware",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./server": {
|
|
15
|
+
"types": "./dist/server.d.ts",
|
|
16
|
+
"import": "./dist/server.mjs",
|
|
17
|
+
"require": "./dist/server.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"README.md"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsup",
|
|
26
|
+
"dev": "tsup --watch",
|
|
27
|
+
"typecheck": "tsc --noEmit",
|
|
28
|
+
"prepublishOnly": "npm run build"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"next": ">=13.0.0",
|
|
32
|
+
"react": ">=17.0.0",
|
|
33
|
+
"react-dom": ">=17.0.0"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@serviceagent/react": "file:../react",
|
|
37
|
+
"@serviceagent/sdk": "file:../../sdk/javascript"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^20.0.0",
|
|
41
|
+
"@types/react": "^18.0.0",
|
|
42
|
+
"next": "^14.0.0",
|
|
43
|
+
"react": "^18.0.0",
|
|
44
|
+
"react-dom": "^18.0.0",
|
|
45
|
+
"tsup": "^8.0.0",
|
|
46
|
+
"typescript": "^5.0.0"
|
|
47
|
+
},
|
|
48
|
+
"keywords": [
|
|
49
|
+
"serviceagent",
|
|
50
|
+
"nextjs",
|
|
51
|
+
"react",
|
|
52
|
+
"chat",
|
|
53
|
+
"voice",
|
|
54
|
+
"calendar",
|
|
55
|
+
"ai",
|
|
56
|
+
"server-components"
|
|
57
|
+
],
|
|
58
|
+
"author": "ServiceAgent",
|
|
59
|
+
"license": "MIT",
|
|
60
|
+
"repository": {
|
|
61
|
+
"type": "git",
|
|
62
|
+
"url": "https://github.com/serviceagent/serviceagent-backend.git",
|
|
63
|
+
"directory": "packages/nextjs"
|
|
64
|
+
},
|
|
65
|
+
"homepage": "https://docs.serviceagent.ai",
|
|
66
|
+
"bugs": {
|
|
67
|
+
"url": "https://github.com/serviceagent/serviceagent-backend/issues"
|
|
68
|
+
},
|
|
69
|
+
"publishConfig": {
|
|
70
|
+
"access": "public"
|
|
71
|
+
},
|
|
72
|
+
"engines": {
|
|
73
|
+
"node": ">=18"
|
|
74
|
+
}
|
|
75
|
+
}
|