Đánh Dấu Thông Báo Đã Đọc
API đánh dấu thông báo đã đọc cho khách hàng.
Hỗ trợ đánh dấu một thông báo, nhiều thông báo, hoặc tất cả thông báo chưa đọc. Có thể lọc theo loại thông báo khi đánh dấu tất cả.
GET/POST https://api.socdo.vn/mini-app/v1/update-notification
Request Headers
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
Content-Type: application/json
Request Parameters (GET) / Request Body (POST)
| Tham số |
Loại |
Bắt buộc |
Mô tả |
Authorization |
header |
✓ |
JWT token từ API login (Bearer token) |
notification_id |
integer |
- |
ID của thông báo cần đánh dấu đã đọc (chỉ đánh dấu 1 thông báo) |
notification_ids |
array |
- |
Mảng ID các thông báo cần đánh dấu đã đọc (đánh dấu nhiều thông báo) |
mark_all |
boolean |
- |
Đánh dấu tất cả thông báo chưa đọc đã đọc (true/false) |
type |
string |
- |
Lọc theo loại thông báo khi mark_all = true (order, voucher_new, etc.) |
Các Cách Sử Dụng
| Cách |
Tham số |
Mô tả |
| Đánh dấu 1 thông báo |
notification_id |
Đánh dấu một thông báo cụ thể đã đọc |
| Đánh dấu nhiều thông báo |
notification_ids (array) |
Đánh dấu nhiều thông báo cùng lúc |
| Đánh dấu tất cả |
mark_all = true |
Đánh dấu tất cả thông báo chưa đọc đã đọc |
| Đánh dấu tất cả theo loại |
mark_all = true + type |
Đánh dấu tất cả thông báo chưa đọc của một loại cụ thể |
Response thành công - Đánh dấu 1 thông báo (200)
{
"success": true,
"message": "Đã đánh dấu thông báo đã đọc",
"data": {
"notification_id": 582,
"read_at": 1762934433
}
}
Response thành công - Đánh dấu nhiều thông báo (200)
{
"success": true,
"message": "Đã đánh dấu 3 thông báo đã đọc",
"data": {
"notification_ids": [582, 581, 580],
"affected_count": 3,
"read_at": 1762934433
}
}
Response thành công - Đánh dấu tất cả (200)
{
"success": true,
"message": "Đã đánh dấu 15 thông báo đã đọc",
"data": {
"affected_count": 15,
"mark_all": true,
"type": null
}
}
Response thành công - Đánh dấu tất cả theo loại (200)
{
"success": true,
"message": "Đã đánh dấu 8 thông báo đã đọc",
"data": {
"affected_count": 8,
"mark_all": true,
"type": "order"
}
}
Response lỗi (400 - Thiếu tham số)
{
"success": false,
"message": "Vui lòng cung cấp notification_id, notification_ids (mảng), hoặc mark_all = true"
}
Response lỗi (400 - Danh sách ID không hợp lệ)
{
"success": false,
"message": "Danh sách ID thông báo không hợp lệ"
}
Response lỗi (401 - Token không hợp lệ)
{
"success": false,
"message": "Token không hợp lệ - không có user_id"
}
Response lỗi (404 - Không tìm thấy)
{
"success": false,
"message": "Không tìm thấy thông báo hoặc không có quyền truy cập"
}
Response lỗi (500 - Lỗi hệ thống)
{
"success": false,
"message": "Lỗi xử lý đánh dấu thông báo đã đọc",
"error": "Error message details"
}
Ví dụ JavaScript
// Đánh dấu một thông báo đã đọc
async function markNotificationAsRead(notificationId) {
try {
const authToken = localStorage.getItem('auth_token');
if (!authToken) {
throw new Error('Chưa đăng nhập');
}
const response = await fetch(`https://api.socdo.vn/mini-app/v1/update-notification?notification_id=${notificationId}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${authToken}`
}
});
const result = await response.json();
if (result.success) {
console.log('Đã đánh dấu thông báo đã đọc:', result.data);
return result;
} else {
console.error('Lỗi:', result.message);
return result;
}
} catch (error) {
console.error('Lỗi kết nối:', error);
return { success: false, message: 'Lỗi kết nối mạng' };
}
}
// Đánh dấu nhiều thông báo đã đọc
async function markMultipleNotificationsAsRead(notificationIds) {
try {
const authToken = localStorage.getItem('auth_token');
const response = await fetch('https://api.socdo.vn/mini-app/v1/update-notification', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${authToken}`
},
body: JSON.stringify({
notification_ids: notificationIds
})
});
const result = await response.json();
if (result.success) {
console.log(`Đã đánh dấu ${result.data.affected_count} thông báo đã đọc`);
return result;
}
} catch (error) {
console.error('Lỗi:', error);
}
}
// Đánh dấu tất cả thông báo chưa đọc đã đọc
async function markAllNotificationsAsRead() {
try {
const authToken = localStorage.getItem('auth_token');
const response = await fetch('https://api.socdo.vn/mini-app/v1/update-notification', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${authToken}`
},
body: JSON.stringify({
mark_all: true
})
});
const result = await response.json();
if (result.success) {
console.log(`Đã đánh dấu ${result.data.affected_count} thông báo đã đọc`);
return result;
}
} catch (error) {
console.error('Lỗi:', error);
}
}
// Đánh dấu tất cả thông báo của một loại cụ thể đã đọc
async function markAllNotificationsByTypeAsRead(type) {
try {
const authToken = localStorage.getItem('auth_token');
const response = await fetch('https://api.socdo.vn/mini-app/v1/update-notification', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${authToken}`
},
body: JSON.stringify({
mark_all: true,
type: type
})
});
const result = await response.json();
if (result.success) {
console.log(`Đã đánh dấu ${result.data.affected_count} thông báo loại ${type} đã đọc`);
return result;
}
} catch (error) {
console.error('Lỗi:', error);
}
}
// Xử lý khi user click vào thông báo
function handleNotificationClick(notification) {
// Đánh dấu thông báo đã đọc khi user click
if (!notification.is_read) {
markNotificationAsRead(notification.id).then(result => {
if (result.success) {
// Cập nhật UI
updateNotificationUI(notification.id, true);
// Giảm số thông báo chưa đọc
updateUnreadCount();
}
});
}
// Xử lý navigation hoặc action khác
if (notification.type === 'order' && notification.data && notification.data.order_id) {
window.location.href = `/order-detail?id=${notification.data.order_id}`;
}
}
// Cập nhật UI sau khi đánh dấu đã đọc
function updateNotificationUI(notificationId, isRead) {
const notificationElement = document.querySelector(`[data-notification-id="${notificationId}"]`);
if (notificationElement) {
if (isRead) {
notificationElement.classList.remove('unread');
notificationElement.classList.add('read');
const badge = notificationElement.querySelector('.unread-badge');
if (badge) {
badge.remove();
}
}
}
}
// Cập nhật số thông báo chưa đọc
async function updateUnreadCount() {
try {
const authToken = localStorage.getItem('auth_token');
const response = await fetch('https://api.socdo.vn/mini-app/v1/get-list-notification?limit=1', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${authToken}`
}
});
const result = await response.json();
if (result.success) {
const unreadBadge = document.getElementById('unread-badge');
if (unreadBadge) {
const count = result.data.unread_count;
unreadBadge.textContent = count;
unreadBadge.style.display = count > 0 ? 'block' : 'none';
}
}
} catch (error) {
console.error('Lỗi cập nhật số thông báo chưa đọc:', error);
}
}
// Đánh dấu tất cả khi click nút "Đánh dấu tất cả đã đọc"
document.getElementById('mark-all-read-btn')?.addEventListener('click', async function() {
const result = await markAllNotificationsAsRead();
if (result && result.success) {
// Reload danh sách thông báo
loadNotifications();
// Cập nhật số thông báo chưa đọc
updateUnreadCount();
// Hiển thị thông báo thành công
showNotification('Đã đánh dấu tất cả thông báo đã đọc', 'success');
}
});
// Ví dụ sử dụng
// Đánh dấu một thông báo
markNotificationAsRead(582);
// Đánh dấu nhiều thông báo
markMultipleNotificationsAsRead([582, 581, 580]);
// Đánh dấu tất cả
markAllNotificationsAsRead();
// Đánh dấu tất cả thông báo loại "order"
markAllNotificationsByTypeAsRead('order');
Lưu ý quan trọng
- User Token Required: API yêu cầu user token từ login (Bearer token trong Authorization header)
- Chỉ cập nhật thông báo của user: API tự động lọc theo user_id từ token, không thể đánh dấu thông báo của user khác
- Ưu tiên tham số: Nếu có nhiều tham số, ưu tiên: mark_all > notification_ids > notification_id
- mark_all: Chỉ đánh dấu các thông báo chưa đọc (is_read = 0), không ảnh hưởng đến thông báo đã đọc
- type filter: Chỉ áp dụng khi mark_all = true, dùng để lọc theo loại thông báo cụ thể
- notification_ids: Có thể là mảng hoặc JSON string, API sẽ tự động parse
- read_at timestamp: API tự động cập nhật read_at và updated_at khi đánh dấu đã đọc
- GET và POST: API hỗ trợ cả GET (query parameters) và POST (request body)
- Affected rows: Response trả về số lượng thông báo đã được cập nhật
Cấu trúc Response Data
| Trường |
Loại |
Mô tả |
notification_id |
integer |
ID thông báo đã đánh dấu (khi đánh dấu 1 thông báo) |
notification_ids |
array |
Danh sách ID thông báo đã đánh dấu (khi đánh dấu nhiều thông báo) |
affected_count |
integer |
Số lượng thông báo đã được cập nhật |
read_at |
integer |
Timestamp khi đánh dấu đã đọc |
mark_all |
boolean |
true nếu đánh dấu tất cả |
type |
string/null |
Loại thông báo đã lọc (nếu có) |
Bảo mật
- JWT Verification: Sử dụng JWT để xác thực token
- User Isolation: API chỉ cho phép cập nhật thông báo của user đang đăng nhập (tự động filter theo user_id từ token)
- SQL Injection Protection: Sử dụng mysqli_real_escape_string và validation để bảo vệ
- CORS Headers: Cấu hình CORS để bảo mật cross-origin requests
- Input Validation: Validate và sanitize tất cả input parameters
- ID Validation: Chỉ chấp nhận ID là số nguyên dương
API Liên Quan