@tencentcloud/web-push 1.0.2 → 1.0.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.0.4] - 2025-01-27
4
+
5
+ ### Added
6
+
7
+ - **Online Push Popup Feature**: Real-time in-app message popup display to enhance user experience
8
+ - **Multiple Message Type Support**: Standard (standard template), HTML (custom HTML), Custom (fully customizable)
9
+ - **Log Level Control**: Added `logLevel` parameter to registerPush, supporting 5 levels of log control
10
+
3
11
  ## [1.0.2] - 2025-01-16
4
12
 
5
13
  - ✨ Added UMD build support for direct `<script>` tag integration
package/README.md CHANGED
@@ -6,6 +6,8 @@ A web-based push notification SDK built on modern Web APIs including Service Wor
6
6
 
7
7
  - 🚀 Built on modern Web standard APIs
8
8
  - 📱 Cross-platform push notification support
9
+ - 💬 **Online Push Popup**: Real-time in-app message popup display
10
+ - 🎨 **Custom Popup Styles**: Full customization support for position, styling, and behavior
9
11
  - 🔧 TypeScript support
10
12
  - 📊 Built-in analytics functionality
11
13
  - 🎯 Event-driven architecture
@@ -52,23 +54,13 @@ Include directly via `<script>` tag:
52
54
 
53
55
  // Usage is the same as ES6 modules
54
56
  webPush.registerPush({
55
- SDKAppID: 1400000000,
56
- appKey: 'your-app-key',
57
- userID: 'test-user-001',
57
+ SDKAppID: 0,
58
+ appKey: '',
59
+ userID: '',
58
60
  });
59
61
  </script>
60
62
  ```
61
63
 
62
- Or download and use locally:
63
-
64
- ```html
65
- <!-- Include Chat SDK -->
66
- <script src="./path/to/chat-sdk.js"></script>
67
-
68
- <!-- Include Web Push SDK -->
69
- <script src="./dist/index.umd.js"></script>
70
- ```
71
-
72
64
  ### Step 2: Configure the Service Worker File
73
65
 
74
66
  After integrating `@tencentcloud/web-push`, copy the **Service Worker (sw.js)** to your project's **root directory**. After website deployment, ensure this file can be accessed through `https://your-domain.com/sw.js`. Otherwise, the browser will be unable to register the **Service Worker**.
@@ -136,22 +128,22 @@ In your homepage (for example: `index.js`), add `@tencentcloud/web-push` and reg
136
128
  </table>
137
129
 
138
130
  ```javascript
139
- import WebPush from '@tencentcloud/web-push';
131
+ import webPush from '@tencentcloud/web-push';
140
132
 
141
133
  const SDKAppID = 0; // Your SDKAppID
142
134
  const appKey = ''; // client key
143
135
  const userID = ''; // user ID
144
136
 
145
- // Register for push service
146
- await WebPush.registerPush({ SDKAppID, appKey, userID });
137
+ // Register push service
138
+ await webPush.registerPush({ SDKAppID, appKey, userID });
147
139
 
148
140
  // Listen to push messages
149
- WebPush.addPushListener(WebPush.EVENT.MESSAGE_RECEIVED, (message) => {
141
+ webPush.addPushListener(webPush.EVENT.MESSAGE_RECEIVED, (message) => {
150
142
  console.log('received push message:', message);
151
143
  });
152
144
 
153
145
  // Listen to notification click
154
- WebPush.addPushListener(WebPush.EVENT.NOTIFICATION_CLICKED, (data) => {
146
+ webPush.addPushListener(webPush.EVENT.NOTIFICATION_CLICKED, (data) => {
155
147
  console.log('notification clicked:', data);
156
148
  });
157
149
  ```
@@ -180,9 +172,9 @@ If you're using UMD integration, here's an example:
180
172
  const webPush = WebPushSDK.webPush;
181
173
 
182
174
  // Configuration parameters
183
- const SDKAppID = 1400000000; // Your SDKAppID
184
- const appKey = 'your-app-key'; // Client key
185
- const userID = 'test-user-001'; // User ID
175
+ const SDKAppID = 0; // Your SDKAppID
176
+ const appKey = ''; // Client key
177
+ const userID = ''; // User ID
186
178
 
187
179
  // Register push service
188
180
  webPush
@@ -226,8 +218,16 @@ interface RegisterPushOptions {
226
218
  SDKAppID: number;
227
219
  appKey: string;
228
220
  userID: string;
229
- serviceWorkerPath?: string;
230
221
  chat?: any;
222
+ /**
223
+ * Log level:
224
+ * 0 - Normal level, more logs, recommended for integration
225
+ * 1 - Release level, SDK outputs key information, recommended for production (default)
226
+ * 2 - Warning level, SDK only outputs warning and error level logs
227
+ * 3 - Error level, SDK only outputs error level logs
228
+ * 4 - No log level, SDK will not print any logs
229
+ */
230
+ logLevel?: LogLevel;
231
231
  }
232
232
 
233
233
  enum EVENT {
@@ -235,76 +235,11 @@ enum EVENT {
235
235
  MESSAGE_REVOKED = 'message_revoked',
236
236
  NOTIFICATION_CLICKED = 'notification_clicked',
237
237
  }
238
-
239
- interface Message {
240
- ID: string;
241
- type:
242
- | 'TIMTextElem'
243
- | 'TIMImageElem'
244
- | 'TIMSoundElem'
245
- | 'TIMVideoFileElem'
246
- | 'TIMFileElem'
247
- | 'TIMCustomElem'
248
- | 'TIMRelayElem'
249
- | 'TIMLocationElem'
250
- | 'TIMFaceElem';
251
- payload: any;
252
- conversationID: string;
253
- conversationType: 'C2C' | 'GROUP';
254
- to: string;
255
- from: string;
256
- flow: string;
257
- time: number;
258
- status: string;
259
- isRevoked: boolean;
260
- nick: string;
261
- avatar: string;
262
- isPeerRead: boolean;
263
- nameCard: string;
264
- atUserList: string[];
265
- cloudCustomData: string;
266
- isDeleted: boolean;
267
- isModified: boolean;
268
- needReadReceipt: boolean;
269
- readReceiptInfo: any;
270
- isBroadcastMessage: boolean;
271
- isSupportExtension: boolean;
272
- receiverList?: string[];
273
- revoker: string;
274
- sequence: number;
275
- progress: number;
276
- revokerInfo: {
277
- userID: string;
278
- nick: string;
279
- avatar: string;
280
- };
281
- revokeReason: string;
282
- hasRiskContent: boolean;
283
- }
284
-
285
- interface MessageReceivedResult {
286
- message: Message;
287
- }
288
-
289
- interface MessageRevokedResult {
290
- messageID: string;
291
- }
292
-
293
- interface MessageNotificationClickedResult {
294
- ext: string;
295
- }
296
-
297
- interface EventResult {
298
- data:
299
- | MessageReceivedResult
300
- | MessageRevokedResult
301
- | MessageNotificationClickedResult;
302
- }
303
238
  ```
304
239
 
305
240
  ### Event Types
306
241
 
307
- - `MESSAGE_RECEIVED`: Received a push message
242
+ - `MESSAGE_RECEIVED`: Received a push message (including all types: standard, html, custom)
308
243
  - `MESSAGE_REVOKED`: Message was revoked
309
244
  - `NOTIFICATION_CLICKED`: Notification was clicked
310
245
 
package/index.d.ts CHANGED
@@ -1,74 +1,201 @@
1
+ export declare interface CustomMessage {
2
+ id: string;
3
+ MsgType: 'custom';
4
+ MsgContent: {
5
+ Data: string | object;
6
+ };
7
+ Ext?: string;
8
+ }
9
+
1
10
  export declare enum EVENT {
2
11
  MESSAGE_RECEIVED = "message_received",
3
12
  MESSAGE_REVOKED = "message_revoked",
4
- NOTIFICATION_CLICKED = "notification_clicked"
13
+ NOTIFICATION_CLICKED = "notification_clicked",
14
+ CUSTOM_MESSAGE_RECEIVED = "custom_message_received"
5
15
  }
6
16
 
7
17
  export declare interface EventResult {
8
18
  data: MessageReceivedResult | MessageRevokedResult | MessageNotificationClickedResult;
9
19
  }
10
20
 
11
- export declare interface Message {
12
- ID: String;
13
- type: 'TIMTextElem' | 'TIMImageElem' | 'TIMSoundElem' | 'TIMVideoFileElem' | 'TIMFileElem' | 'TIMCustomElem' | 'TIMRelayElem' | 'TIMLocationElem' | 'TIMFaceElem';
14
- payload: any;
15
- conversationID: String;
16
- conversationType: 'C2C' | 'GROUP';
17
- to: String;
18
- from: String;
19
- flow: String;
20
- time: Number;
21
- status: String;
22
- isRevoked: Boolean;
23
- nick: String;
24
- avatar: String;
25
- isPeerRead: Boolean;
26
- nameCard: String;
27
- atUserList: String[];
28
- cloudCustomData: String;
29
- isDeleted: Boolean;
30
- isModified: Boolean;
31
- needReadReceipt: Boolean;
32
- readReceiptInfo: any;
33
- isBroadcastMessage: Boolean;
34
- isSupportExtension: Boolean;
35
- receiverList?: String[];
36
- revoker: String;
37
- sequence: Number;
38
- progress: Number;
39
- revokerInfo: {
40
- userID: String;
41
- nick: String;
42
- avatar: String;
21
+ export declare interface HtmlMessage {
22
+ id: string;
23
+ MsgType: 'html';
24
+ MsgContent: {
25
+ Placement?: Placement;
26
+ Duration?: number;
27
+ Html: string;
43
28
  };
44
- revokeReason: String;
45
- hasRiskContent: Boolean;
29
+ Ext?: string;
46
30
  }
47
31
 
32
+ export declare type LogLevel = 0 | 1 | 2 | 3 | 4;
33
+
48
34
  export declare interface MessageNotificationClickedResult {
49
35
  ext: String;
50
36
  }
51
37
 
38
+ export declare class MessagePopup {
39
+ private container;
40
+ private popups;
41
+ private timers;
42
+ private messageHandlers;
43
+ private animationTimers;
44
+ private adjustHeightTimers;
45
+ private config;
46
+ private readonly defaultConfig;
47
+ constructor(config?: PopupConfig);
48
+ private init;
49
+ private createContainer;
50
+ private injectStyles;
51
+ show(message: StandardMessage | HtmlMessage): void;
52
+ private createStandardPopup;
53
+ private createHtmlPopup;
54
+ private addPopup;
55
+ private removeOldestPopup;
56
+ close(messageId: string): void;
57
+ /**
58
+ * 检查指定消息是否正在显示弹窗
59
+ * @param messageId 消息ID
60
+ * @returns 是否正在显示
61
+ */
62
+ hasMessage(messageId: string): boolean;
63
+ closeAll(): void;
64
+ updateConfig(newConfig: Partial<PopupConfig>): void;
65
+ destroy(): void;
66
+ /**
67
+ * 根据 Placement 值应用容器位置
68
+ * 0-中间,1-左上,2-上中,3-右上,4-右中,5-右下,6-下中,7-左下,8-左中
69
+ */
70
+ private applyPlacement;
71
+ /**
72
+ * 调整iframe高度以适应内容
73
+ */
74
+ private adjustIframeHeight;
75
+ /**
76
+ * 创建iframe的完整HTML文档
77
+ */
78
+ private createIframeHtml;
79
+ }
80
+
81
+ export declare interface MessageReceivedData {
82
+ content: string;
83
+ info: WebPushInfo;
84
+ extension: WebPushExt;
85
+ }
86
+
52
87
  export declare interface MessageReceivedResult {
53
- message: Message;
88
+ message: PushMessage | NotificationMessage;
54
89
  }
55
90
 
56
91
  export declare interface MessageRevokedResult {
57
92
  messageID: String;
58
93
  }
59
94
 
95
+ export declare interface NotificationMessage {
96
+ messageID: string;
97
+ title: string;
98
+ body: string;
99
+ icon?: string;
100
+ tag?: string;
101
+ data?: any;
102
+ timestamp: number;
103
+ }
104
+
105
+ export declare enum Placement {
106
+ CENTER = 0,// 中间
107
+ TOP_LEFT = 1,// 左上
108
+ TOP_CENTER = 2,// 上中
109
+ TOP_RIGHT = 3,// 右上
110
+ MIDDLE_RIGHT = 4,// 右中
111
+ BOTTOM_RIGHT = 5,// 右下
112
+ BOTTOM_CENTER = 6,// 下中
113
+ BOTTOM_LEFT = 7,// 左下
114
+ MIDDLE_LEFT = 8
115
+ }
116
+
117
+ declare interface PopupConfig {
118
+ /** 是否启用弹窗 */
119
+ enabled?: boolean;
120
+ /** 弹窗显示时长(毫秒),0 表示不自动关闭 */
121
+ duration?: number;
122
+ /** 弹窗位置 */
123
+ position?: 'center' | 'top-left' | 'top-center' | 'top-right' | 'right-center' | 'bottom-right' | 'bottom-center' | 'bottom-left' | 'left-center';
124
+ /** 最大显示数量 */
125
+ maxCount?: number;
126
+ /** 是否显示关闭按钮 */
127
+ showCloseButton?: boolean;
128
+ /** 是否允许点击弹窗 */
129
+ clickable?: boolean;
130
+ /** 自定义渲染函数 */
131
+ customRender?: (message: any, container: HTMLElement) => HTMLElement;
132
+ /** 点击回调 */
133
+ onClick?: (message: any, popup: HTMLElement) => void;
134
+ /** 关闭回调 */
135
+ onClose?: (message: any, popup: HTMLElement) => void;
136
+ }
137
+
138
+ export declare type PushMessage = StandardMessage | HtmlMessage | CustomMessage;
139
+
60
140
  export declare interface RegisterPushOptions {
61
141
  SDKAppID: number;
62
142
  appKey: string;
63
143
  userID: string;
64
144
  serviceWorkerPath?: string;
65
145
  chat?: any;
146
+ /**
147
+ * 日志级别:
148
+ * 0 - 普通级别,日志量较多,接入时建议使用
149
+ * 1 - release级别,SDK 输出关键信息,生产环境时建议使用(默认)
150
+ * 2 - 告警级别,SDK 只输出告警和错误级别的日志
151
+ * 3 - 错误级别,SDK 只输出错误级别的日志
152
+ * 4 - 无日志级别,SDK 将不打印任何日志
153
+ */
154
+ logLevel?: LogLevel;
155
+ }
156
+
157
+ export declare interface StandardMessage {
158
+ id: string;
159
+ MsgType: 'standard';
160
+ MsgContent: {
161
+ Text: {
162
+ Title: string;
163
+ Desc: string;
164
+ };
165
+ Image?: {
166
+ URL: string;
167
+ LinkURL: string;
168
+ };
169
+ Close: 0 | 1;
170
+ Placement?: Placement;
171
+ Duration?: number;
172
+ Button?: Array<{
173
+ Text: string;
174
+ Icon?: string;
175
+ Url: string;
176
+ }>;
177
+ };
178
+ Ext?: string;
66
179
  }
67
180
 
68
181
  declare const webPush: WebPushSDK_2;
69
182
  export default webPush;
70
183
  export { webPush }
71
184
 
185
+ export declare interface WebPushExt {
186
+ WebpushReportUrl: string;
187
+ OnlineClickExt: string;
188
+ TaskId: string;
189
+ }
190
+
191
+ export declare interface WebPushInfo {
192
+ Title: string;
193
+ Desc: string;
194
+ Icon: string;
195
+ Image: string;
196
+ URL: string;
197
+ }
198
+
72
199
  export declare interface WebPushSDK {
73
200
  registerPush(options?: RegisterPushOptions): Promise<any>;
74
201
  unRegisterPush(): Promise<any>;
@@ -80,12 +207,14 @@ declare class WebPushSDK_2 implements WebPushSDK {
80
207
  static instance: WebPushSDK_2;
81
208
  private eventEmitter;
82
209
  private serviceWorkerManager;
210
+ private messagePopup;
83
211
  private isRegistered;
84
212
  private registrationID;
85
213
  private chat;
86
214
  private SDKAppID;
87
215
  private appKey;
88
216
  private vapidPublicKey;
217
+ private pendingMessages;
89
218
  EVENT: typeof EVENT;
90
219
  VERSION: string;
91
220
  constructor();
@@ -93,18 +222,38 @@ declare class WebPushSDK_2 implements WebPushSDK {
93
222
  registerPush(options?: RegisterPushOptions): Promise<string>;
94
223
  unRegisterPush(): Promise<boolean>;
95
224
  addPushListener(eventName: EVENT, listener: Function): string;
225
+ /**
226
+ * 内部方法:向 Service Worker 发送日志级别配置
227
+ * @param logLevel 日志级别 0-4
228
+ */
229
+ private sendLogLevelToServiceWorker;
96
230
  removePushListener(eventName: EVENT, listener: Function): boolean;
97
231
  private checkBrowserSupport;
98
232
  private requestNotificationPermission;
99
- private chatLogin;
233
+ private pushLogin;
234
+ private onMessageReceived;
235
+ private onMessageRevoked;
236
+ private addChatListener;
237
+ private removeChatListener;
100
238
  private getSystemPermissionMessage;
101
239
  private showSystemPermissionAlert;
102
240
  private getBrowserInstType;
103
241
  private setToken;
104
242
  private initializeBrowserCompatibility;
243
+ private setupVisibilityChangeListener;
105
244
  private setupInternalListeners;
106
245
  private pushStatistics;
107
246
  private clearState;
247
+ /**
248
+ * 向 service-worker 发送通知消息,使用与 push 事件相同的数据格式
249
+ * @param webpushInfo webpush 信息,格式与 SW push 事件接收的数据一致
250
+ */
251
+ private sendNotificationToServiceWorker;
252
+ /**
253
+ * 向 service-worker 发送消息撤回请求
254
+ * @param messageID 要撤回的消息ID
255
+ */
256
+ private sendMessageRevokeToServiceWorker;
108
257
  }
109
258
 
110
259
  export { }