mezon-light-sdk 1.0.2
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 +46 -0
- package/dist/client.d.ts +26 -0
- package/dist/client.js +90 -0
- package/dist/constants.d.ts +4 -0
- package/dist/constants.js +7 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +20 -0
- package/dist/message.d.ts +19 -0
- package/dist/message.js +2 -0
- package/dist/socket.d.ts +13 -0
- package/dist/socket.js +65 -0
- package/package.json +23 -0
package/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# mezon-p2p-chat-sdk
|
|
2
|
+
|
|
3
|
+
SDK chat P2P cho mezon-js.
|
|
4
|
+
|
|
5
|
+
# Version SDK Example using to demo
|
|
6
|
+
` pip install p2p-chat-sdk `
|
|
7
|
+
# Frontend (Client) use SDK
|
|
8
|
+
|
|
9
|
+
## 1: Import
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
import { P2PClient, P2PSocket, P2PMessage } from 'p2p-chat-sdk';
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 2: Create P2PClient:
|
|
16
|
+
```
|
|
17
|
+
const p2p_client = await P2PClient.authenticate({ id_token, user_id, username, serverkey });
|
|
18
|
+
```
|
|
19
|
+
## 3: Connect Socket:
|
|
20
|
+
```
|
|
21
|
+
const p2p_socket = new P2PSocket(p2p_client.getClient(), p2p_client.getSession());
|
|
22
|
+
await p2p_socket.connect();
|
|
23
|
+
```
|
|
24
|
+
## 4: Listen Message:
|
|
25
|
+
```
|
|
26
|
+
p2p_socket.setChannelMessageHandler((msg: P2PMessage) => {
|
|
27
|
+
console.log('New message:', msg);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 5: Start DM
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
const channel = await p2p_client.createDM(peerId);
|
|
36
|
+
await p2p_socket.joinDMChannel(channel.channel_id);
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 6: Send Message:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
await p2p_socket.sendDM(channelId, { t: inputMsg });
|
|
44
|
+
```
|
|
45
|
+
<img width="767" height="775" alt="Screenshot 2025-12-15 132741" src="https://github.com/user-attachments/assets/3019ca86-de5f-49b7-a05a-3895c754029d" />
|
|
46
|
+
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Session, Client } from 'mezon-js';
|
|
2
|
+
export declare class LightClient {
|
|
3
|
+
private session;
|
|
4
|
+
private client;
|
|
5
|
+
user_id: string;
|
|
6
|
+
private constructor();
|
|
7
|
+
static initClient({ token, refresh_token, api_url, user_id, serverkey }: {
|
|
8
|
+
token: string;
|
|
9
|
+
refresh_token: string;
|
|
10
|
+
api_url: string;
|
|
11
|
+
user_id: string;
|
|
12
|
+
serverkey: string;
|
|
13
|
+
}): LightClient;
|
|
14
|
+
static authenticate({ id_token, user_id, username, serverkey }: {
|
|
15
|
+
id_token: string;
|
|
16
|
+
user_id: string;
|
|
17
|
+
username: string;
|
|
18
|
+
serverkey: string;
|
|
19
|
+
}): Promise<LightClient>;
|
|
20
|
+
createDM(peer_id: string): Promise<import("mezon-js/dist/api.gen").ApiChannelDescription>;
|
|
21
|
+
refreshSession(): Promise<void>;
|
|
22
|
+
isSessionExpired(): Promise<boolean>;
|
|
23
|
+
isRefreshSessionExpired(): Promise<boolean>;
|
|
24
|
+
getSession(): Session;
|
|
25
|
+
getClient(): Client;
|
|
26
|
+
}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.LightClient = void 0;
|
|
27
|
+
const mezon_js_1 = require("mezon-js");
|
|
28
|
+
const constants_1 = require("./constants");
|
|
29
|
+
const base64 = __importStar(require("js-base64"));
|
|
30
|
+
class LightClient {
|
|
31
|
+
constructor(session, client, user_id) {
|
|
32
|
+
this.session = session;
|
|
33
|
+
this.client = client;
|
|
34
|
+
this.user_id = user_id;
|
|
35
|
+
}
|
|
36
|
+
static initClient({ token, refresh_token, api_url, user_id, serverkey }) {
|
|
37
|
+
if (!token || !refresh_token || !api_url || !user_id) {
|
|
38
|
+
throw new Error('Missing required fields to restore session from storage');
|
|
39
|
+
}
|
|
40
|
+
const session = mezon_js_1.Session.restore(token, refresh_token, api_url, true);
|
|
41
|
+
const url = new URL(api_url);
|
|
42
|
+
const client = new mezon_js_1.Client(serverkey || 'DefaultServerKey', url.hostname, url.port || '', url.protocol === 'https:');
|
|
43
|
+
return new LightClient(session, client, user_id);
|
|
44
|
+
}
|
|
45
|
+
static async authenticate({ id_token, user_id, username, serverkey }) {
|
|
46
|
+
const res = await fetch(constants_1.MEZON_GW_URL + '/v2/account/authenticate/idtoken', {
|
|
47
|
+
method: 'POST',
|
|
48
|
+
headers: {
|
|
49
|
+
'Content-Type': 'application/json',
|
|
50
|
+
'Authorization': 'Basic ' + base64.encode(serverkey || 'DefaultServerKey')
|
|
51
|
+
},
|
|
52
|
+
body: JSON.stringify({ id_token, user_id, username })
|
|
53
|
+
});
|
|
54
|
+
if (!res.ok) {
|
|
55
|
+
const errData = await res.json().catch(() => ({}));
|
|
56
|
+
throw new Error(errData.message || 'Error during authentication request');
|
|
57
|
+
}
|
|
58
|
+
const data = await res.json();
|
|
59
|
+
if (data && data.token && data.refresh_token && data.api_url && data.user_id) {
|
|
60
|
+
const session = mezon_js_1.Session.restore(data.token, data.refresh_token, data.api_url, true);
|
|
61
|
+
const url = new URL(data.api_url);
|
|
62
|
+
const client = new mezon_js_1.Client(serverkey || 'DefaultServerKey', url.hostname, url.port || '', url.protocol === 'https:');
|
|
63
|
+
return new LightClient(session, client, data.user_id);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
throw new Error('Error during authentication or missing data fields!');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async createDM(peer_id) {
|
|
70
|
+
const req = { type: mezon_js_1.ChannelType.CHANNEL_TYPE_DM, channel_private: 1, user_ids: [peer_id] };
|
|
71
|
+
const channel = await this.client.createChannelDesc(this.session, req);
|
|
72
|
+
return channel;
|
|
73
|
+
}
|
|
74
|
+
async refreshSession() {
|
|
75
|
+
await this.client.sessionRefresh(this.session);
|
|
76
|
+
}
|
|
77
|
+
async isSessionExpired() {
|
|
78
|
+
return this.session.isexpired(Date.now() / 1000);
|
|
79
|
+
}
|
|
80
|
+
async isRefreshSessionExpired() {
|
|
81
|
+
return this.session.isrefreshexpired(Date.now() / 1000);
|
|
82
|
+
}
|
|
83
|
+
getSession() {
|
|
84
|
+
return this.session;
|
|
85
|
+
}
|
|
86
|
+
getClient() {
|
|
87
|
+
return this.client;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
exports.LightClient = LightClient;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CLAN_DM = exports.SOCKET_READY_RETRY_DELAY = exports.SOCKET_READY_MAX_RETRY = exports.MEZON_GW_URL = void 0;
|
|
4
|
+
exports.MEZON_GW_URL = 'https://gw.mezon.ai';
|
|
5
|
+
exports.SOCKET_READY_MAX_RETRY = 20;
|
|
6
|
+
exports.SOCKET_READY_RETRY_DELAY = 100;
|
|
7
|
+
exports.CLAN_DM = '0';
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
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
|
+
__exportStar(require("./constants"), exports);
|
|
18
|
+
__exportStar(require("./message"), exports);
|
|
19
|
+
__exportStar(require("./client"), exports);
|
|
20
|
+
__exportStar(require("./socket"), exports);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface ChannelMessage {
|
|
2
|
+
clan_id: string;
|
|
3
|
+
channel_id: string;
|
|
4
|
+
message_id: string;
|
|
5
|
+
code: number;
|
|
6
|
+
sender_id: string;
|
|
7
|
+
username: string;
|
|
8
|
+
avatar: string;
|
|
9
|
+
content: any;
|
|
10
|
+
create_time: string;
|
|
11
|
+
update_time: string;
|
|
12
|
+
display_name: string;
|
|
13
|
+
mentions: any[];
|
|
14
|
+
attachments: any[];
|
|
15
|
+
references: any[];
|
|
16
|
+
create_time_seconds: number;
|
|
17
|
+
update_time_seconds: number;
|
|
18
|
+
hide_editted: boolean;
|
|
19
|
+
}
|
package/dist/message.js
ADDED
package/dist/socket.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Client, Session } from "mezon-js";
|
|
2
|
+
import { ChannelMessage } from "./message";
|
|
3
|
+
export declare class LightSocket {
|
|
4
|
+
private client;
|
|
5
|
+
private session;
|
|
6
|
+
private socket;
|
|
7
|
+
onError?: (err: any) => void;
|
|
8
|
+
constructor(client: Client, session: Session);
|
|
9
|
+
connect(onError?: (err: any) => void): Promise<void>;
|
|
10
|
+
setChannelMessageHandler(cb: (msg: ChannelMessage) => void): void;
|
|
11
|
+
joinDMChannel(channel_id: string): Promise<void>;
|
|
12
|
+
sendDM(channelId: string, content: any, attachments?: any[]): Promise<void>;
|
|
13
|
+
}
|
package/dist/socket.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LightSocket = void 0;
|
|
4
|
+
const mezon_js_protobuf_1 = require("mezon-js-protobuf");
|
|
5
|
+
const mezon_js_1 = require("mezon-js");
|
|
6
|
+
const constants_1 = require("./constants");
|
|
7
|
+
class LightSocket {
|
|
8
|
+
constructor(client, session) {
|
|
9
|
+
this.client = client;
|
|
10
|
+
this.session = session;
|
|
11
|
+
}
|
|
12
|
+
async connect(onError) {
|
|
13
|
+
this.socket = this.client.createSocket(this.client.useSSL, false, new mezon_js_protobuf_1.WebSocketAdapterPb());
|
|
14
|
+
this.socket.onerror = onError || (() => { });
|
|
15
|
+
await this.socket.connect(this.session, true, "0");
|
|
16
|
+
}
|
|
17
|
+
setChannelMessageHandler(cb) {
|
|
18
|
+
this.socket.onchannelmessage = (msg) => {
|
|
19
|
+
if (msg && msg.error) {
|
|
20
|
+
if (this.onError)
|
|
21
|
+
this.onError(msg.error);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
cb({
|
|
25
|
+
clan_id: msg.clan_id,
|
|
26
|
+
channel_id: msg.channel_id,
|
|
27
|
+
message_id: msg.message_id || msg.id,
|
|
28
|
+
code: msg.code,
|
|
29
|
+
sender_id: msg.sender_id,
|
|
30
|
+
username: msg.username,
|
|
31
|
+
avatar: msg.avatar,
|
|
32
|
+
content: msg.content,
|
|
33
|
+
create_time: msg.create_time,
|
|
34
|
+
update_time: msg.update_time,
|
|
35
|
+
display_name: msg.display_name,
|
|
36
|
+
mentions: msg.mentions || [],
|
|
37
|
+
attachments: msg.attachments || [],
|
|
38
|
+
references: msg.references || [],
|
|
39
|
+
create_time_seconds: msg.create_time_seconds,
|
|
40
|
+
update_time_seconds: msg.update_time_seconds,
|
|
41
|
+
hide_editted: msg.hide_editted,
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
async joinDMChannel(channel_id) {
|
|
46
|
+
await waitForSocketReady(this.socket);
|
|
47
|
+
await this.socket.joinChat(constants_1.CLAN_DM, channel_id, mezon_js_1.ChannelType.CHANNEL_TYPE_DM, false);
|
|
48
|
+
}
|
|
49
|
+
async sendDM(channelId, content, attachments = []) {
|
|
50
|
+
this.socket.writeChatMessage(constants_1.CLAN_DM, channelId, mezon_js_1.ChannelStreamMode.STREAM_MODE_DM, false, content, attachments, [], [], false, false, "", 0);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.LightSocket = LightSocket;
|
|
54
|
+
async function waitForSocketReady(socket) {
|
|
55
|
+
let count = 0;
|
|
56
|
+
let delay = constants_1.SOCKET_READY_RETRY_DELAY;
|
|
57
|
+
while (!(socket.adapter && socket.adapter.isOpen()) &&
|
|
58
|
+
count < constants_1.SOCKET_READY_MAX_RETRY) {
|
|
59
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
60
|
+
delay *= 2;
|
|
61
|
+
count++;
|
|
62
|
+
}
|
|
63
|
+
if (!(socket.adapter && socket.adapter.isOpen()))
|
|
64
|
+
throw new Error("Socket not open");
|
|
65
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mezon-light-sdk",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Lightweigth SDK for mezon chat.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"js-base64": "^3.7.8",
|
|
15
|
+
"mezon-js": "^2.13.58",
|
|
16
|
+
"mezon-js-protobuf": "^1.8.66"
|
|
17
|
+
},
|
|
18
|
+
"author": "mezonai",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"typescript": "^5.4.3"
|
|
22
|
+
}
|
|
23
|
+
}
|