@rivium/chat 0.1.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/LICENSE +21 -0
- package/README.md +169 -0
- package/dist/client.d.ts +17 -0
- package/dist/client.js +95 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +39 -0
- package/dist/modules/messages.d.ts +24 -0
- package/dist/modules/messages.js +49 -0
- package/dist/modules/pins.d.ts +14 -0
- package/dist/modules/pins.js +21 -0
- package/dist/modules/reactions.d.ts +14 -0
- package/dist/modules/reactions.js +21 -0
- package/dist/modules/rooms.d.ts +20 -0
- package/dist/modules/rooms.js +37 -0
- package/dist/modules/tokens.d.ts +10 -0
- package/dist/modules/tokens.js +13 -0
- package/dist/modules/webhooks.d.ts +35 -0
- package/dist/modules/webhooks.js +37 -0
- package/dist/types.d.ts +162 -0
- package/dist/types.js +3 -0
- package/package.json +36 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Rivium
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# RiviumChat Node.js SDK
|
|
2
|
+
|
|
3
|
+
Server-side SDK for RiviumChat. Manage chat rooms, messages, reactions, pins, webhooks, and push notification templates from your Node.js backend.
|
|
4
|
+
|
|
5
|
+
> **Server-side only.** This SDK requires a server secret and must never be used in client-side applications. The server secret can be extracted from client apps.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- Room management (create, find, list, add participants)
|
|
10
|
+
- Message operations (send, edit, delete, search, mentions)
|
|
11
|
+
- Read receipts and unread counts
|
|
12
|
+
- Emoji reactions
|
|
13
|
+
- Message pinning
|
|
14
|
+
- Webhook configuration
|
|
15
|
+
- Push notification templates (via Rivium Push)
|
|
16
|
+
- Centrifugo connection token generation
|
|
17
|
+
- Zero runtime dependencies — uses native Node.js `http`/`https`
|
|
18
|
+
- TypeScript declarations included
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install @rivium/chat
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { RiviumChat } from '@rivium/chat';
|
|
30
|
+
|
|
31
|
+
const riviumChat = new RiviumChat({
|
|
32
|
+
apiKey: 'YOUR_API_KEY',
|
|
33
|
+
serverSecret: 'YOUR_SERVER_SECRET',
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Create a Room
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
const room = await riviumChat.rooms.findOrCreate({
|
|
41
|
+
externalId: 'order-123',
|
|
42
|
+
participants: [
|
|
43
|
+
{ externalUserId: 'user-1', displayName: 'Alice', role: 'member' },
|
|
44
|
+
{ externalUserId: 'user-2', displayName: 'Bob', role: 'member' },
|
|
45
|
+
],
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Send a Message
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
const message = await riviumChat.messages.send(room.id, {
|
|
53
|
+
senderUserId: 'user-1',
|
|
54
|
+
content: 'Hello from the server!',
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Get Message History
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
const { messages, hasMore } = await riviumChat.messages.getHistory(room.id, {
|
|
62
|
+
userId: 'user-1',
|
|
63
|
+
limit: 50,
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Mark as Read
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
await riviumChat.messages.markAsRead(room.id, 'user-1');
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Unread Counts
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
const summary = await riviumChat.rooms.getUnreadSummary('user-1');
|
|
77
|
+
// { totalUnread: 5, rooms: [{ roomId, externalId, unreadCount }] }
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## API Reference
|
|
81
|
+
|
|
82
|
+
### Rooms
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
riviumChat.rooms.create(options) // Create a room
|
|
86
|
+
riviumChat.rooms.findOrCreate(options) // Find or create by externalId
|
|
87
|
+
riviumChat.rooms.get(roomId) // Get room by ID
|
|
88
|
+
riviumChat.rooms.getByExternalId(externalId) // Get room by external ID
|
|
89
|
+
riviumChat.rooms.list(userId) // List rooms for a user
|
|
90
|
+
riviumChat.rooms.addParticipant(roomId, options) // Add participant to room
|
|
91
|
+
riviumChat.rooms.getUnreadSummary(userId) // Get unread counts
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Messages
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
riviumChat.messages.send(roomId, options) // Send a message
|
|
98
|
+
riviumChat.messages.getHistory(roomId, options) // Get paginated history
|
|
99
|
+
riviumChat.messages.markAsRead(roomId, userId) // Mark messages as read
|
|
100
|
+
riviumChat.messages.edit(messageId, userId, content) // Edit a message
|
|
101
|
+
riviumChat.messages.delete(messageId, userId) // Delete a message
|
|
102
|
+
riviumChat.messages.search(roomId, options) // Search messages
|
|
103
|
+
riviumChat.messages.getMentions(roomId, options) // Get @mentions
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Reactions
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
riviumChat.reactions.add(messageId, userId, emoji) // Add reaction
|
|
110
|
+
riviumChat.reactions.remove(messageId, userId, emoji) // Remove reaction
|
|
111
|
+
riviumChat.reactions.list(messageId) // List reactions
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Pins
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
riviumChat.pins.pin(messageId, userId) // Pin a message
|
|
118
|
+
riviumChat.pins.unpin(messageId, userId) // Unpin a message
|
|
119
|
+
riviumChat.pins.list(roomId) // List pinned messages
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Webhooks
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
riviumChat.webhooks.get() // Get webhook config
|
|
126
|
+
riviumChat.webhooks.setWebhook({ url, secret? }) // Set webhook URL
|
|
127
|
+
riviumChat.webhooks.removeWebhook() // Remove webhook
|
|
128
|
+
riviumChat.webhooks.setPushTemplate(templateId) // Set push template
|
|
129
|
+
riviumChat.webhooks.removePushTemplate() // Remove push template
|
|
130
|
+
riviumChat.webhooks.setPushTemplates(templates) // Per-event push templates
|
|
131
|
+
riviumChat.webhooks.removePushTemplates() // Remove per-event templates
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Tokens
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
riviumChat.tokens.getConnectionToken({ userId, info? }) // Get Centrifugo token
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Push Notifications
|
|
141
|
+
|
|
142
|
+
Configure push notifications for offline users via [Rivium Push](https://rivium.co/cloud/rivium-push):
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
// Use a Rivium Push template
|
|
146
|
+
await riviumChat.webhooks.setPushTemplate('your-template-id');
|
|
147
|
+
|
|
148
|
+
// Or use per-event inline templates
|
|
149
|
+
await riviumChat.webhooks.setPushTemplates({
|
|
150
|
+
new_message: {
|
|
151
|
+
title: '{{senderName}}',
|
|
152
|
+
body: '{{messagePreview}}',
|
|
153
|
+
},
|
|
154
|
+
mention: {
|
|
155
|
+
title: '{{senderName}} mentioned you',
|
|
156
|
+
body: '{{messagePreview}}',
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Links
|
|
162
|
+
|
|
163
|
+
- [Rivium Chat](https://rivium.co/cloud/rivium-chat) - Learn more about Rivium Chat
|
|
164
|
+
- [Documentation](https://rivium.co/cloud/rivium-chat/docs/quick-start) - Full documentation and guides
|
|
165
|
+
- [Rivium Console](https://console.rivium.co) - Manage your chat rooms
|
|
166
|
+
|
|
167
|
+
## License
|
|
168
|
+
|
|
169
|
+
MIT
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { RiviumChatConfig } from './types';
|
|
2
|
+
export declare class HttpClient {
|
|
3
|
+
private apiKey;
|
|
4
|
+
private serverSecret;
|
|
5
|
+
private baseUrl;
|
|
6
|
+
constructor(config: RiviumChatConfig);
|
|
7
|
+
request<T>(method: string, path: string, body?: any, query?: Record<string, any>): Promise<T>;
|
|
8
|
+
get<T>(path: string, query?: Record<string, any>): Promise<T>;
|
|
9
|
+
post<T>(path: string, body?: any, query?: Record<string, any>): Promise<T>;
|
|
10
|
+
put<T>(path: string, body?: any, query?: Record<string, any>): Promise<T>;
|
|
11
|
+
delete<T>(path: string, body?: any, query?: Record<string, any>): Promise<T>;
|
|
12
|
+
}
|
|
13
|
+
export declare class RiviumChatError extends Error {
|
|
14
|
+
statusCode: number;
|
|
15
|
+
response: any;
|
|
16
|
+
constructor(message: string, statusCode: number, response: any);
|
|
17
|
+
}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RiviumChatError = exports.HttpClient = void 0;
|
|
7
|
+
const https_1 = __importDefault(require("https"));
|
|
8
|
+
const http_1 = __importDefault(require("http"));
|
|
9
|
+
const BASE_URL = 'https://chat.rivium.co';
|
|
10
|
+
class HttpClient {
|
|
11
|
+
constructor(config) {
|
|
12
|
+
if (!config.apiKey) {
|
|
13
|
+
throw new Error('RiviumChat: apiKey is required');
|
|
14
|
+
}
|
|
15
|
+
if (!config.serverSecret) {
|
|
16
|
+
throw new Error('RiviumChat: serverSecret is required');
|
|
17
|
+
}
|
|
18
|
+
this.apiKey = config.apiKey;
|
|
19
|
+
this.serverSecret = config.serverSecret;
|
|
20
|
+
this.baseUrl = BASE_URL;
|
|
21
|
+
}
|
|
22
|
+
async request(method, path, body, query) {
|
|
23
|
+
const url = new URL(path, this.baseUrl);
|
|
24
|
+
if (query) {
|
|
25
|
+
for (const [k, v] of Object.entries(query)) {
|
|
26
|
+
if (v !== undefined && v !== null) {
|
|
27
|
+
url.searchParams.set(k, String(v));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const payload = body ? JSON.stringify(body) : undefined;
|
|
32
|
+
const isHttps = url.protocol === 'https:';
|
|
33
|
+
const lib = isHttps ? https_1.default : http_1.default;
|
|
34
|
+
const headers = {
|
|
35
|
+
'x-api-key': this.apiKey,
|
|
36
|
+
'x-server-secret': this.serverSecret,
|
|
37
|
+
'Content-Type': 'application/json',
|
|
38
|
+
};
|
|
39
|
+
if (payload) {
|
|
40
|
+
headers['Content-Length'] = Buffer.byteLength(payload);
|
|
41
|
+
}
|
|
42
|
+
return new Promise((resolve, reject) => {
|
|
43
|
+
const req = lib.request(url, {
|
|
44
|
+
method,
|
|
45
|
+
headers,
|
|
46
|
+
}, (res) => {
|
|
47
|
+
let data = '';
|
|
48
|
+
res.on('data', (chunk) => (data += chunk));
|
|
49
|
+
res.on('end', () => {
|
|
50
|
+
const statusCode = res.statusCode || 0;
|
|
51
|
+
let parsed;
|
|
52
|
+
try {
|
|
53
|
+
parsed = data ? JSON.parse(data) : {};
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
parsed = { message: data };
|
|
57
|
+
}
|
|
58
|
+
if (statusCode >= 200 && statusCode < 300) {
|
|
59
|
+
resolve(parsed);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
const err = new RiviumChatError(parsed.message || `Request failed with status ${statusCode}`, statusCode, parsed);
|
|
63
|
+
reject(err);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
req.on('error', reject);
|
|
68
|
+
if (payload)
|
|
69
|
+
req.write(payload);
|
|
70
|
+
req.end();
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
get(path, query) {
|
|
74
|
+
return this.request('GET', path, undefined, query);
|
|
75
|
+
}
|
|
76
|
+
post(path, body, query) {
|
|
77
|
+
return this.request('POST', path, body, query);
|
|
78
|
+
}
|
|
79
|
+
put(path, body, query) {
|
|
80
|
+
return this.request('PUT', path, body, query);
|
|
81
|
+
}
|
|
82
|
+
delete(path, body, query) {
|
|
83
|
+
return this.request('DELETE', path, body, query);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
exports.HttpClient = HttpClient;
|
|
87
|
+
class RiviumChatError extends Error {
|
|
88
|
+
constructor(message, statusCode, response) {
|
|
89
|
+
super(message);
|
|
90
|
+
this.name = 'RiviumChatError';
|
|
91
|
+
this.statusCode = statusCode;
|
|
92
|
+
this.response = response;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.RiviumChatError = RiviumChatError;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Rooms } from './modules/rooms';
|
|
2
|
+
import { Messages } from './modules/messages';
|
|
3
|
+
import { Reactions } from './modules/reactions';
|
|
4
|
+
import { Pins } from './modules/pins';
|
|
5
|
+
import { Webhooks } from './modules/webhooks';
|
|
6
|
+
import { Tokens } from './modules/tokens';
|
|
7
|
+
import { RiviumChatConfig } from './types';
|
|
8
|
+
export declare class RiviumChat {
|
|
9
|
+
private client;
|
|
10
|
+
/** Room management */
|
|
11
|
+
rooms: Rooms;
|
|
12
|
+
/** Message operations */
|
|
13
|
+
messages: Messages;
|
|
14
|
+
/** Message reactions */
|
|
15
|
+
reactions: Reactions;
|
|
16
|
+
/** Pinned messages */
|
|
17
|
+
pins: Pins;
|
|
18
|
+
/** Webhook & push configuration */
|
|
19
|
+
webhooks: Webhooks;
|
|
20
|
+
/** Centrifugo connection tokens */
|
|
21
|
+
tokens: Tokens;
|
|
22
|
+
constructor(config: RiviumChatConfig);
|
|
23
|
+
}
|
|
24
|
+
export { RiviumChatError } from './client';
|
|
25
|
+
export * from './types';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.RiviumChatError = exports.RiviumChat = void 0;
|
|
18
|
+
const client_1 = require("./client");
|
|
19
|
+
const rooms_1 = require("./modules/rooms");
|
|
20
|
+
const messages_1 = require("./modules/messages");
|
|
21
|
+
const reactions_1 = require("./modules/reactions");
|
|
22
|
+
const pins_1 = require("./modules/pins");
|
|
23
|
+
const webhooks_1 = require("./modules/webhooks");
|
|
24
|
+
const tokens_1 = require("./modules/tokens");
|
|
25
|
+
class RiviumChat {
|
|
26
|
+
constructor(config) {
|
|
27
|
+
this.client = new client_1.HttpClient(config);
|
|
28
|
+
this.rooms = new rooms_1.Rooms(this.client);
|
|
29
|
+
this.messages = new messages_1.Messages(this.client);
|
|
30
|
+
this.reactions = new reactions_1.Reactions(this.client);
|
|
31
|
+
this.pins = new pins_1.Pins(this.client);
|
|
32
|
+
this.webhooks = new webhooks_1.Webhooks(this.client);
|
|
33
|
+
this.tokens = new tokens_1.Tokens(this.client);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.RiviumChat = RiviumChat;
|
|
37
|
+
var client_2 = require("./client");
|
|
38
|
+
Object.defineProperty(exports, "RiviumChatError", { enumerable: true, get: function () { return client_2.RiviumChatError; } });
|
|
39
|
+
__exportStar(require("./types"), exports);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { HttpClient } from '../client';
|
|
2
|
+
import { Message, PaginatedMessages, SendMessageOptions, GetHistoryOptions, SearchResult, SearchMessagesOptions, GetMentionsOptions, Mention } from '../types';
|
|
3
|
+
export declare class Messages {
|
|
4
|
+
private client;
|
|
5
|
+
constructor(client: HttpClient);
|
|
6
|
+
/** Send a message to a room. */
|
|
7
|
+
send(roomId: string, options: SendMessageOptions): Promise<Message>;
|
|
8
|
+
/** Get message history for a room (paginated). */
|
|
9
|
+
getHistory(roomId: string, options: GetHistoryOptions): Promise<PaginatedMessages>;
|
|
10
|
+
/** Mark messages as read in a room for a user. */
|
|
11
|
+
markAsRead(roomId: string, userId: string): Promise<{
|
|
12
|
+
success: boolean;
|
|
13
|
+
}>;
|
|
14
|
+
/** Edit a message. */
|
|
15
|
+
edit(messageId: string, userId: string, content: string): Promise<Message>;
|
|
16
|
+
/** Delete a message. */
|
|
17
|
+
delete(messageId: string, userId: string): Promise<{
|
|
18
|
+
success: boolean;
|
|
19
|
+
}>;
|
|
20
|
+
/** Search messages in a room. */
|
|
21
|
+
search(roomId: string, options: SearchMessagesOptions): Promise<SearchResult>;
|
|
22
|
+
/** Get mentions for a user in a room. */
|
|
23
|
+
getMentions(roomId: string, options: GetMentionsOptions): Promise<Mention[]>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Messages = void 0;
|
|
4
|
+
class Messages {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
/** Send a message to a room. */
|
|
9
|
+
async send(roomId, options) {
|
|
10
|
+
return this.client.post(`/api/v1/rooms/${roomId}/messages`, options);
|
|
11
|
+
}
|
|
12
|
+
/** Get message history for a room (paginated). */
|
|
13
|
+
async getHistory(roomId, options) {
|
|
14
|
+
return this.client.get(`/api/v1/rooms/${roomId}/messages`, {
|
|
15
|
+
userId: options.userId,
|
|
16
|
+
limit: options.limit,
|
|
17
|
+
before: options.before,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/** Mark messages as read in a room for a user. */
|
|
21
|
+
async markAsRead(roomId, userId) {
|
|
22
|
+
return this.client.post(`/api/v1/rooms/${roomId}/read`, { userId });
|
|
23
|
+
}
|
|
24
|
+
/** Edit a message. */
|
|
25
|
+
async edit(messageId, userId, content) {
|
|
26
|
+
return this.client.put(`/api/v1/messages/${messageId}`, { userId, content });
|
|
27
|
+
}
|
|
28
|
+
/** Delete a message. */
|
|
29
|
+
async delete(messageId, userId) {
|
|
30
|
+
return this.client.delete(`/api/v1/messages/${messageId}`, undefined, { userId });
|
|
31
|
+
}
|
|
32
|
+
/** Search messages in a room. */
|
|
33
|
+
async search(roomId, options) {
|
|
34
|
+
return this.client.get(`/api/v1/rooms/${roomId}/messages/search`, {
|
|
35
|
+
q: options.q,
|
|
36
|
+
userId: options.userId,
|
|
37
|
+
limit: options.limit,
|
|
38
|
+
offset: options.offset,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/** Get mentions for a user in a room. */
|
|
42
|
+
async getMentions(roomId, options) {
|
|
43
|
+
return this.client.get(`/api/v1/rooms/${roomId}/mentions`, {
|
|
44
|
+
userId: options.userId,
|
|
45
|
+
limit: options.limit,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.Messages = Messages;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { HttpClient } from '../client';
|
|
2
|
+
import { Message } from '../types';
|
|
3
|
+
export declare class Pins {
|
|
4
|
+
private client;
|
|
5
|
+
constructor(client: HttpClient);
|
|
6
|
+
/** Pin a message. */
|
|
7
|
+
pin(messageId: string, userId: string): Promise<Message>;
|
|
8
|
+
/** Unpin a message. */
|
|
9
|
+
unpin(messageId: string, userId: string): Promise<{
|
|
10
|
+
success: boolean;
|
|
11
|
+
}>;
|
|
12
|
+
/** Get all pinned messages in a room. */
|
|
13
|
+
list(roomId: string): Promise<Message[]>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Pins = void 0;
|
|
4
|
+
class Pins {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
/** Pin a message. */
|
|
9
|
+
async pin(messageId, userId) {
|
|
10
|
+
return this.client.post(`/api/v1/messages/${messageId}/pin`, { userId });
|
|
11
|
+
}
|
|
12
|
+
/** Unpin a message. */
|
|
13
|
+
async unpin(messageId, userId) {
|
|
14
|
+
return this.client.delete(`/api/v1/messages/${messageId}/pin`, { userId });
|
|
15
|
+
}
|
|
16
|
+
/** Get all pinned messages in a room. */
|
|
17
|
+
async list(roomId) {
|
|
18
|
+
return this.client.get(`/api/v1/rooms/${roomId}/pinned`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.Pins = Pins;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { HttpClient } from '../client';
|
|
2
|
+
import { Reaction } from '../types';
|
|
3
|
+
export declare class Reactions {
|
|
4
|
+
private client;
|
|
5
|
+
constructor(client: HttpClient);
|
|
6
|
+
/** Add a reaction to a message. */
|
|
7
|
+
add(messageId: string, userId: string, emoji: string): Promise<Reaction>;
|
|
8
|
+
/** Remove a reaction from a message. */
|
|
9
|
+
remove(messageId: string, userId: string, emoji: string): Promise<{
|
|
10
|
+
success: boolean;
|
|
11
|
+
}>;
|
|
12
|
+
/** Get all reactions for a message. */
|
|
13
|
+
list(messageId: string): Promise<Reaction[]>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Reactions = void 0;
|
|
4
|
+
class Reactions {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
/** Add a reaction to a message. */
|
|
9
|
+
async add(messageId, userId, emoji) {
|
|
10
|
+
return this.client.post(`/api/v1/messages/${messageId}/reactions`, { userId, emoji });
|
|
11
|
+
}
|
|
12
|
+
/** Remove a reaction from a message. */
|
|
13
|
+
async remove(messageId, userId, emoji) {
|
|
14
|
+
return this.client.delete(`/api/v1/messages/${messageId}/reactions`, { userId, emoji });
|
|
15
|
+
}
|
|
16
|
+
/** Get all reactions for a message. */
|
|
17
|
+
async list(messageId) {
|
|
18
|
+
return this.client.get(`/api/v1/messages/${messageId}/reactions`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.Reactions = Reactions;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { HttpClient } from '../client';
|
|
2
|
+
import { Room, CreateRoomOptions, AddParticipantOptions, Participant, UnreadSummary } from '../types';
|
|
3
|
+
export declare class Rooms {
|
|
4
|
+
private client;
|
|
5
|
+
constructor(client: HttpClient);
|
|
6
|
+
/** Create a new chat room. */
|
|
7
|
+
create(options: CreateRoomOptions): Promise<Room>;
|
|
8
|
+
/** Find existing room by externalId or create a new one. */
|
|
9
|
+
findOrCreate(options: CreateRoomOptions): Promise<Room>;
|
|
10
|
+
/** Get room by external ID. */
|
|
11
|
+
getByExternalId(externalId: string): Promise<Room>;
|
|
12
|
+
/** List rooms for a user. */
|
|
13
|
+
list(userId: string): Promise<Room[]>;
|
|
14
|
+
/** Get room by ID. */
|
|
15
|
+
get(id: string): Promise<Room>;
|
|
16
|
+
/** Get unread counts across all rooms for a user. */
|
|
17
|
+
getUnreadSummary(userId: string): Promise<UnreadSummary>;
|
|
18
|
+
/** Add a participant to a room. */
|
|
19
|
+
addParticipant(roomId: string, options: AddParticipantOptions): Promise<Participant>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Rooms = void 0;
|
|
4
|
+
class Rooms {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
/** Create a new chat room. */
|
|
9
|
+
async create(options) {
|
|
10
|
+
return this.client.post('/api/v1/rooms', options);
|
|
11
|
+
}
|
|
12
|
+
/** Find existing room by externalId or create a new one. */
|
|
13
|
+
async findOrCreate(options) {
|
|
14
|
+
return this.client.post('/api/v1/rooms/find-or-create', options);
|
|
15
|
+
}
|
|
16
|
+
/** Get room by external ID. */
|
|
17
|
+
async getByExternalId(externalId) {
|
|
18
|
+
return this.client.get(`/api/v1/rooms/by-external-id/${encodeURIComponent(externalId)}`);
|
|
19
|
+
}
|
|
20
|
+
/** List rooms for a user. */
|
|
21
|
+
async list(userId) {
|
|
22
|
+
return this.client.get('/api/v1/rooms', { userId });
|
|
23
|
+
}
|
|
24
|
+
/** Get room by ID. */
|
|
25
|
+
async get(id) {
|
|
26
|
+
return this.client.get(`/api/v1/rooms/${id}`);
|
|
27
|
+
}
|
|
28
|
+
/** Get unread counts across all rooms for a user. */
|
|
29
|
+
async getUnreadSummary(userId) {
|
|
30
|
+
return this.client.get('/api/v1/rooms/unread-summary', { userId });
|
|
31
|
+
}
|
|
32
|
+
/** Add a participant to a room. */
|
|
33
|
+
async addParticipant(roomId, options) {
|
|
34
|
+
return this.client.post(`/api/v1/rooms/${roomId}/participants`, options);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.Rooms = Rooms;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { HttpClient } from '../client';
|
|
2
|
+
import { GetTokenOptions } from '../types';
|
|
3
|
+
export declare class Tokens {
|
|
4
|
+
private client;
|
|
5
|
+
constructor(client: HttpClient);
|
|
6
|
+
/** Get a Centrifugo connection token for a user. */
|
|
7
|
+
getConnectionToken(options: GetTokenOptions): Promise<{
|
|
8
|
+
token: string;
|
|
9
|
+
}>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Tokens = void 0;
|
|
4
|
+
class Tokens {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
/** Get a Centrifugo connection token for a user. */
|
|
9
|
+
async getConnectionToken(options) {
|
|
10
|
+
return this.client.post('/api/v1/centrifugo/token', options);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.Tokens = Tokens;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { HttpClient } from '../client';
|
|
2
|
+
import { WebhookConfig, SetWebhookOptions, PushTemplates } from '../types';
|
|
3
|
+
export declare class Webhooks {
|
|
4
|
+
private client;
|
|
5
|
+
constructor(client: HttpClient);
|
|
6
|
+
/** Get current webhook and push configuration. */
|
|
7
|
+
get(): Promise<WebhookConfig>;
|
|
8
|
+
/** Set webhook URL (and optional secret for HMAC-SHA256 signature verification). */
|
|
9
|
+
setWebhook(options: SetWebhookOptions): Promise<{
|
|
10
|
+
success: boolean;
|
|
11
|
+
webhookUrl: string;
|
|
12
|
+
}>;
|
|
13
|
+
/** Remove webhook configuration. */
|
|
14
|
+
removeWebhook(): Promise<{
|
|
15
|
+
success: boolean;
|
|
16
|
+
}>;
|
|
17
|
+
/** Set Pushino template ID for offline push notifications. */
|
|
18
|
+
setPushTemplate(pushTemplateId: string): Promise<{
|
|
19
|
+
success: boolean;
|
|
20
|
+
pushTemplateId: string;
|
|
21
|
+
}>;
|
|
22
|
+
/** Remove push notification template configuration. */
|
|
23
|
+
removePushTemplate(): Promise<{
|
|
24
|
+
success: boolean;
|
|
25
|
+
}>;
|
|
26
|
+
/** Set per-event push notification config (template ID, inline title/body, or skip). */
|
|
27
|
+
setPushTemplates(templates: PushTemplates): Promise<{
|
|
28
|
+
success: boolean;
|
|
29
|
+
pushTemplates: PushTemplates;
|
|
30
|
+
}>;
|
|
31
|
+
/** Remove per-event push template configuration. */
|
|
32
|
+
removePushTemplates(): Promise<{
|
|
33
|
+
success: boolean;
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Webhooks = void 0;
|
|
4
|
+
class Webhooks {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
/** Get current webhook and push configuration. */
|
|
9
|
+
async get() {
|
|
10
|
+
return this.client.get('/api/v1/webhook');
|
|
11
|
+
}
|
|
12
|
+
/** Set webhook URL (and optional secret for HMAC-SHA256 signature verification). */
|
|
13
|
+
async setWebhook(options) {
|
|
14
|
+
return this.client.put('/api/v1/webhook', options);
|
|
15
|
+
}
|
|
16
|
+
/** Remove webhook configuration. */
|
|
17
|
+
async removeWebhook() {
|
|
18
|
+
return this.client.delete('/api/v1/webhook');
|
|
19
|
+
}
|
|
20
|
+
/** Set Pushino template ID for offline push notifications. */
|
|
21
|
+
async setPushTemplate(pushTemplateId) {
|
|
22
|
+
return this.client.put('/api/v1/webhook/push', { pushTemplateId });
|
|
23
|
+
}
|
|
24
|
+
/** Remove push notification template configuration. */
|
|
25
|
+
async removePushTemplate() {
|
|
26
|
+
return this.client.delete('/api/v1/webhook/push');
|
|
27
|
+
}
|
|
28
|
+
/** Set per-event push notification config (template ID, inline title/body, or skip). */
|
|
29
|
+
async setPushTemplates(templates) {
|
|
30
|
+
return this.client.put('/api/v1/webhook/push-templates', templates);
|
|
31
|
+
}
|
|
32
|
+
/** Remove per-event push template configuration. */
|
|
33
|
+
async removePushTemplates() {
|
|
34
|
+
return this.client.delete('/api/v1/webhook/push-templates');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.Webhooks = Webhooks;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
export interface RiviumChatConfig {
|
|
2
|
+
/** Your Rivium API key */
|
|
3
|
+
apiKey: string;
|
|
4
|
+
/** Your Rivium server secret — required for server-side operations */
|
|
5
|
+
serverSecret: string;
|
|
6
|
+
}
|
|
7
|
+
export type RoomType = 'direct' | 'group';
|
|
8
|
+
export type ParticipantRole = 'admin' | 'member';
|
|
9
|
+
export type MessageType = 'text' | 'image' | 'file' | 'system';
|
|
10
|
+
export interface Attachment {
|
|
11
|
+
url: string;
|
|
12
|
+
mimeType: string;
|
|
13
|
+
name: string;
|
|
14
|
+
size: number;
|
|
15
|
+
}
|
|
16
|
+
export interface Participant {
|
|
17
|
+
id: string;
|
|
18
|
+
roomId: string;
|
|
19
|
+
externalUserId: string;
|
|
20
|
+
displayName?: string;
|
|
21
|
+
locale?: string;
|
|
22
|
+
role: ParticipantRole;
|
|
23
|
+
lastReadAt?: string;
|
|
24
|
+
joinedAt: string;
|
|
25
|
+
}
|
|
26
|
+
export interface Room {
|
|
27
|
+
id: string;
|
|
28
|
+
appId: string;
|
|
29
|
+
type: RoomType;
|
|
30
|
+
externalId?: string;
|
|
31
|
+
name?: string;
|
|
32
|
+
metadata?: Record<string, any>;
|
|
33
|
+
isActive: boolean;
|
|
34
|
+
createdAt: string;
|
|
35
|
+
updatedAt: string;
|
|
36
|
+
participants?: Participant[];
|
|
37
|
+
}
|
|
38
|
+
export interface Message {
|
|
39
|
+
id: string;
|
|
40
|
+
roomId: string;
|
|
41
|
+
senderUserId: string;
|
|
42
|
+
type: MessageType;
|
|
43
|
+
content: string;
|
|
44
|
+
attachments?: Attachment[];
|
|
45
|
+
metadata?: Record<string, any>;
|
|
46
|
+
replyToId?: string;
|
|
47
|
+
replyTo?: Message;
|
|
48
|
+
isDeleted: boolean;
|
|
49
|
+
isEdited: boolean;
|
|
50
|
+
editedAt?: string;
|
|
51
|
+
editHistory?: {
|
|
52
|
+
content: string;
|
|
53
|
+
editedAt: string;
|
|
54
|
+
}[];
|
|
55
|
+
isPinned: boolean;
|
|
56
|
+
pinnedAt?: string;
|
|
57
|
+
pinnedBy?: string;
|
|
58
|
+
createdAt: string;
|
|
59
|
+
reactions?: Reaction[];
|
|
60
|
+
}
|
|
61
|
+
export interface Reaction {
|
|
62
|
+
id: string;
|
|
63
|
+
messageId: string;
|
|
64
|
+
userId: string;
|
|
65
|
+
emoji: string;
|
|
66
|
+
createdAt: string;
|
|
67
|
+
}
|
|
68
|
+
export interface Mention {
|
|
69
|
+
id: string;
|
|
70
|
+
messageId: string;
|
|
71
|
+
mentionedUserId: string;
|
|
72
|
+
roomId: string;
|
|
73
|
+
createdAt: string;
|
|
74
|
+
message: Message;
|
|
75
|
+
}
|
|
76
|
+
export interface PaginatedMessages {
|
|
77
|
+
messages: Message[];
|
|
78
|
+
hasMore: boolean;
|
|
79
|
+
}
|
|
80
|
+
export interface SearchResult {
|
|
81
|
+
messages: Message[];
|
|
82
|
+
total: number;
|
|
83
|
+
}
|
|
84
|
+
export interface RoomUnread {
|
|
85
|
+
roomId: string;
|
|
86
|
+
unreadCount: number;
|
|
87
|
+
}
|
|
88
|
+
export interface UnreadSummary {
|
|
89
|
+
totalUnread: number;
|
|
90
|
+
rooms: RoomUnread[];
|
|
91
|
+
}
|
|
92
|
+
export interface EventPushConfig {
|
|
93
|
+
templateId?: string;
|
|
94
|
+
title?: string;
|
|
95
|
+
body?: string;
|
|
96
|
+
skip?: boolean;
|
|
97
|
+
}
|
|
98
|
+
export interface PushTemplates {
|
|
99
|
+
new_message?: EventPushConfig;
|
|
100
|
+
mention?: EventPushConfig;
|
|
101
|
+
reaction?: EventPushConfig;
|
|
102
|
+
room_created?: EventPushConfig;
|
|
103
|
+
participant_joined?: EventPushConfig;
|
|
104
|
+
file_shared?: EventPushConfig;
|
|
105
|
+
message_pinned?: EventPushConfig;
|
|
106
|
+
}
|
|
107
|
+
export interface WebhookConfig {
|
|
108
|
+
webhookUrl: string | null;
|
|
109
|
+
hasSecret: boolean;
|
|
110
|
+
pushTemplateId: string | null;
|
|
111
|
+
pushTemplates: PushTemplates | null;
|
|
112
|
+
}
|
|
113
|
+
export interface ParticipantInput {
|
|
114
|
+
externalUserId: string;
|
|
115
|
+
displayName?: string;
|
|
116
|
+
locale?: string;
|
|
117
|
+
role?: ParticipantRole;
|
|
118
|
+
}
|
|
119
|
+
export interface CreateRoomOptions {
|
|
120
|
+
type?: RoomType;
|
|
121
|
+
externalId?: string;
|
|
122
|
+
name?: string;
|
|
123
|
+
participants: ParticipantInput[];
|
|
124
|
+
metadata?: Record<string, any>;
|
|
125
|
+
}
|
|
126
|
+
export interface AddParticipantOptions {
|
|
127
|
+
externalUserId: string;
|
|
128
|
+
displayName?: string;
|
|
129
|
+
locale?: string;
|
|
130
|
+
role?: ParticipantRole;
|
|
131
|
+
}
|
|
132
|
+
export interface SendMessageOptions {
|
|
133
|
+
senderUserId: string;
|
|
134
|
+
content: string;
|
|
135
|
+
type?: MessageType;
|
|
136
|
+
attachments?: Attachment[];
|
|
137
|
+
metadata?: Record<string, any>;
|
|
138
|
+
replyToId?: string;
|
|
139
|
+
}
|
|
140
|
+
export interface GetHistoryOptions {
|
|
141
|
+
userId: string;
|
|
142
|
+
limit?: number;
|
|
143
|
+
before?: string;
|
|
144
|
+
}
|
|
145
|
+
export interface SearchMessagesOptions {
|
|
146
|
+
q: string;
|
|
147
|
+
userId: string;
|
|
148
|
+
limit?: number;
|
|
149
|
+
offset?: number;
|
|
150
|
+
}
|
|
151
|
+
export interface GetMentionsOptions {
|
|
152
|
+
userId: string;
|
|
153
|
+
limit?: number;
|
|
154
|
+
}
|
|
155
|
+
export interface SetWebhookOptions {
|
|
156
|
+
url: string;
|
|
157
|
+
secret?: string;
|
|
158
|
+
}
|
|
159
|
+
export interface GetTokenOptions {
|
|
160
|
+
userId: string;
|
|
161
|
+
info?: Record<string, any>;
|
|
162
|
+
}
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rivium/chat",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "RiviumChat Node.js SDK — server-side chat rooms, messages, reactions, pins, and webhooks",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"prepublishOnly": "npm run build"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"rivium",
|
|
16
|
+
"rivium-chat",
|
|
17
|
+
"chat",
|
|
18
|
+
"messaging",
|
|
19
|
+
"rooms",
|
|
20
|
+
"realtime"
|
|
21
|
+
],
|
|
22
|
+
"author": "Rivium <support@rivium.co>",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "https://github.com/Rivium-co/rivium-chat-nodejs-sdk.git"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://rivium.co/cloud/rivium-chat",
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=16"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^25.2.0",
|
|
34
|
+
"typescript": "^5.9.3"
|
|
35
|
+
}
|
|
36
|
+
}
|