How to Send Your First AI Prompt
Send a one-shot AI prompt over HTTP, choose an optional provider and model, and read the response returned by sendAI.
The simplest AI integration is a single prompt via sendAI. You pass a message object, usually { text: "..." }, and the SDK returns the AI response from the HTTP call. AI calls are request/response: use transport: "http" so responses return directly from the async method.
Prerequisites
- App credentials — appId and secret from app.dnotifier.com.
- AI enabled on your plan — after connecting, check notifier.aiEnabled and getPlanLimits().
- HTTP transport — set transport: "http" in the constructor.
const notifier = new DNotifier({
appId: process.env.DNOTIFIER_APP_ID,
secret: process.env.DNOTIFIER_SECRET,
transport: "http",
userId: "user-123",
onConnected: () => {},
onMessage: () => {},
onDisconnected: () => {},
});
await notifier.connect();
if (!notifier.aiEnabled) {
throw new Error("AI is not enabled for this plan");
}Requirements
| Requirement | Details |
|---|---|
| Transport | http — required for request/response AI |
| Connection | Await connect() before sendAI |
| Plan | aiEnabled === true after connecting |
| senderId | Must match the connecting userId or an explicit service account ID |
Message Shape
sendAI accepts a flexible message payload. For your first prompt, use simple text:
| Shape | Example | Use case |
|---|---|---|
| Simple text | { text: "Summarize this." } | One-shot instructions |
Method Signature
sendAI({
senderId: string,
message: object | string,
saveHistory?: boolean, // default true
sessionId?: string, // omit on first turn; pass on follow-ups
provider?: string, // optional override
model?: string, // optional override
})| Option | Default | Description |
|---|---|---|
| senderId | — | User ID for the AI call |
| message | — | Prompt payload, messages, or RAG flags |
| saveHistory | true | Persist the turn to AI history |
| sessionId | new UUID | Continue an existing session |
| provider | project default | Merged into request data when provided |
| model | project default | Merged into request data and recorded in session observability |
When provider and model are omitted, the project default from authentication is used. Agents can define their own defaults; an explicit value on sendAI takes precedence.
Provider and model override
await notifier.sendAI({
senderId: USER_ID,
provider: "open_ai",
model: "gpt-4o",
message: {
useKnowledgeBase: false,
messages: [
{
role: "user",
content: "Reply with exactly one word: ok",
},
],
},
saveHistory: true,
});Response Handling
HTTP sendAI resolves with the server response object. Extract the assistant text from the common response fields:
function extractContent(response) {
return (
response?.data?.content ??
response?.content ??
(typeof response === "string"
? response
: JSON.stringify(response))
);
}Error Handling
| Error | Likely cause |
|---|---|
| Not connected | Call connect() first |
| senderId required | Pass a senderId matching your user |
| AI is not enabled | Enable AI or upgrade your plan |
| null response (JavaScript) | Network or server error — inspect SDK logs |
JavaScript / TypeScript
Send a single AI prompt over HTTP and read the response from the returned promise.
Complete Example
import { DNotifier } from "@dnotifier-realtime/dnotifier";
const USER_ID = "user-123";
const notifier = new DNotifier({
appId: process.env.DNOTIFIER_APP_ID,
secret: process.env.DNOTIFIER_SECRET,
transport: "http",
userId: USER_ID,
onConnected: () => console.log("Authenticated"),
onMessage: () => {},
onDisconnected: () => {},
});
await notifier.connect();
if (!notifier.aiEnabled) {
throw new Error("AI is not enabled for this plan");
}
const response = await notifier.sendAI({
senderId: USER_ID,
message: {
text: "Summarize our refund policy in two sentences.",
},
});
const answer =
response?.data?.content ??
response?.content ??
JSON.stringify(response);
console.log("AI:", answer);Browser / Vite
import { DNotifier } from "@dnotifier-realtime/dnotifier";
const notifier = new DNotifier({
appId: import.meta.env.VITE_DNOTIFIER_APP_ID,
secret: import.meta.env.VITE_DNOTIFIER_SECRET,
transport: "http",
userId: "user-123",
onConnected: () => {},
onMessage: () => {},
onDisconnected: () => {},
});
await notifier.connect();
const response = await notifier.sendAI({
senderId: "user-123",
message: {
text: "What are three benefits of HTTP transport for AI?",
},
});Express API Route
import express from "express";
import { DNotifier } from "@dnotifier-realtime/dnotifier";
const app = express();
app.use(express.json());
const notifier = new DNotifier({
appId: process.env.DNOTIFIER_APP_ID,
secret: process.env.DNOTIFIER_SECRET,
transport: "http",
userId: "api-service",
onConnected: () => {},
onMessage: () => {},
onDisconnected: () => {},
});
await notifier.connect();
app.post("/api/ask", async (req, res) => {
const { userId, question } = req.body;
const response = await notifier.sendAI({
senderId: userId,
message: { text: question },
saveHistory: true,
});
res.json({ answer: response?.data?.content ?? response });
});
app.listen(3000);Without Saving History
await notifier.sendAI({
senderId: USER_ID,
message: {
text: "Classify this ticket as billing or technical.",
},
saveHistory: false,
});Choose Provider and Model
Configure the provider connection in the portal, then identify it in the call. Other providers use the same shape with a different provider string.
await notifier.sendAI({
senderId: USER_ID,
provider: "open_ai",
model: "gpt-4o",
message: {
useKnowledgeBase: false,
messages: [
{
role: "user",
content: "Reply with exactly one word: ok",
},
],
},
saveHistory: true,
});TypeScript
type AiTextMessage = { text: string };
const response = await notifier.sendAI({
senderId: USER_ID,
message: { text: "Hello" } satisfies AiTextMessage,
});Troubleshooting
| Issue | Fix |
|---|---|
| Not connected | await notifier.connect() |
| Response is null | Check credentials and confirm HTTP transport |
| Empty content | Inspect the complete response object |
Dart / Flutter
Send a single AI prompt over HTTP and await the response from sendAI.
Complete Example
import 'package:dnotifier/dnotifier.dart';
const userId = 'user-123';
Future<void> main() async {
final notifier = DNotifier(
appId: 'your-app-id',
secret: 'your-app-secret',
transport: 'http',
userId: userId,
onConnected: () => print('Authenticated'),
onMessage: (_) {},
onDisconnected: ({code, reason}) {},
);
await notifier.connect();
if (!notifier.aiEnabled) {
throw StateError('AI is not enabled for this plan');
}
final response = await notifier.sendAI(
senderId: userId,
message: {
'text': 'Summarize our refund policy in two sentences.',
},
);
final answer = extractContent(response);
print('AI: $answer');
}
String extractContent(dynamic response) {
if (response is Map) {
final data = response['data'];
if (data is Map && data['content'] != null) {
return data['content'].toString();
}
if (response['content'] != null) {
return response['content'].toString();
}
}
return response.toString();
}Flutter Service Class
class AiService {
AiService(this._notifier);
final DNotifier _notifier;
Future<String> ask(String userId, String question) async {
final response = await _notifier.sendAI(
senderId: userId,
message: {'text': question},
saveHistory: true,
);
return extractContent(response);
}
}Without Saving History
await notifier.sendAI(
senderId: userId,
message: {
'text': 'Classify this ticket as billing or technical.',
},
saveHistory: false,
);Environment Variables (CLI)
import 'dart:io';
import 'package:dnotifier/dnotifier.dart';
Future<void> main() async {
final notifier = DNotifier(
appId: Platform.environment['DNOTIFIER_APP_ID']!,
secret: Platform.environment['DNOTIFIER_SECRET']!,
transport: 'http',
userId: 'user-123',
onConnected: () {},
onMessage: (_) {},
);
await notifier.connect();
// ...
}Troubleshooting
| Issue | Fix |
|---|---|
| StateError: Not connected | Await notifier.connect() first |
| ArgumentError: senderId required | Pass a non-empty senderId |
| Empty answer | Print the complete response map |
Python
Send a single AI prompt over HTTP and await the response from send_ai.
Complete Example
import asyncio
from dnotifier import DNotifier
USER_ID = "user-123"
def extract_content(response) -> str:
if isinstance(response, dict):
data = response.get("data")
if isinstance(data, dict) and data.get("content") is not None:
return str(data["content"])
if response.get("content") is not None:
return str(response["content"])
return str(response)
async def main():
notifier = DNotifier(
app_id="your-app-id",
secret="your-app-secret",
transport="http",
user_id=USER_ID,
on_connected=lambda: print("Authenticated"),
on_message=lambda _: None,
)
await notifier.connect()
if not notifier.ai_enabled:
raise RuntimeError("AI is not enabled for this plan")
response = await notifier.send_ai(
sender_id=USER_ID,
message={
"text": "Summarize our refund policy in two sentences."
},
)
answer = extract_content(response)
print(f"AI: {answer}")
asyncio.run(main())Service Class
class AiService:
def __init__(self, notifier: DNotifier):
self._notifier = notifier
async def ask(self, user_id: str, question: str) -> str:
response = await self._notifier.send_ai(
sender_id=user_id,
message={"text": question},
save_history=True,
)
return extract_content(response)Without Saving History
await notifier.send_ai(
sender_id=USER_ID,
message={
"text": "Classify this ticket as billing or technical."
},
save_history=False,
)Environment Variables (CLI)
import os
import asyncio
from dnotifier import DNotifier
async def main():
notifier = DNotifier(
app_id=os.environ["DNOTIFIER_APP_ID"],
secret=os.environ["DNOTIFIER_SECRET"],
transport="http",
user_id="user-123",
)
await notifier.connect()
# ...
asyncio.run(main())Troubleshooting
| Issue | Fix |
|---|---|
| RuntimeError: Not connected | Await notifier.connect() first |
| ValueError: sender_id required | Pass a non-empty sender_id |
| Empty answer | Print the complete response dictionary |