Created
June 9, 2025 03:36
-
-
Save flashvnn/b290cac981d7af06980f382f158bd0a1 to your computer and use it in GitHub Desktop.
Mihong SJC price
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Tên script: Widget Giá Vàng Mi Hồng | |
// Tác giả: Gemini | |
// Mô tả: Widget này hiển thị giá vàng SJC mới nhất từ API của mihong.vn. | |
// Phiên bản này bao gồm đầy đủ headers và cookies để giả lập yêu cầu từ trình duyệt. | |
// Hướng dẫn: Đặt widget ở cỡ vừa (Medium) để hiển thị đẹp nhất. | |
// --- CÀI ĐẶT --- | |
const GOLD_CODE = "SJC"; // Có thể đổi thành mã khác nếu API hỗ trợ | |
// URL API để lấy dữ liệu giá vàng từ Mi Hồng | |
const API_URL = `https://mihong.vn/api/v1/gold/prices?gold_code=${GOLD_CODE}&date_type=6`; | |
async function createWidget() { | |
const widget = new ListWidget(); | |
const gradient = new LinearGradient(); | |
gradient.locations = [0, 1]; | |
gradient.colors = [ | |
new Color("#2c3e50"), | |
new Color("#466368") | |
]; | |
widget.backgroundGradient = gradient; | |
widget.setPadding(15, 15, 15, 15); | |
try { | |
// --- TẢI DỮ LIỆU TỪ API --- | |
const request = new Request(API_URL); | |
// --- HEADERS & COOKIES --- | |
// Thêm headers và cookies để giả lập yêu cầu từ trình duyệt, giống với lệnh curl. | |
// LƯU Ý: Các giá trị token này có thể hết hạn sau một thời gian. Nếu widget báo lỗi, | |
// bạn cần lấy giá trị XSRF-TOKEN và laravel_session mới từ trình duyệt và cập nhật lại vào đây. | |
const xsrfToken = "eyJpdiI6Ik5Pb2J2SkJxXC9nTlJmVzhcL0g3MTVxZz09IiwidmFsdWUiOiI2SEs0NXhLY2R1d0NsbmZ2cEozN0FkQ25HZlNGY3JSb0p4TWlmRHBcL0dPc2s3MExoWGdCWFJiMUg4cml5ZGVUVSIsIm1hYyI6IjFiM2U1ZjNmMzdiN2I1MjY1NGZiOTI0OTBiMDVmMGQxMzA1YmY2OTM2ODJiYzU4NzQ1NDA5ZTRlZTJiZWQxYTEifQ%3D%3D"; | |
const laravelSession = "eyJpdiI6IlwvNjNCUlwvZ1VsNUE0TFM3d0xscVkrdz09IiwidmFsdWUiOiJ4dVFVQjhWU0orVE5PemdKbWluVGlLV2srMnhYekFnS1FPSUhCQk1YZHNIakpJYUlmcVRmNzV5MVZnVmNZQ2c4IiwibWFjIjoiZjhmZTVmZjE4NDRiMWFiYTJhY2Y5NzBkODhlNzdhODI2ZjhjOWIyNDJjZTY3NTkxODAzMTA1NWU3ZjM2YWU3OCJ9"; | |
request.headers = { | |
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36", | |
"Referer": "https://mihong.vn/vi/gia-vang-trong-nuoc", | |
"Cookie": `XSRF-TOKEN=${xsrfToken}; laravel_session=${laravelSession}`, | |
"X-Requested-With": "XMLHttpRequest", | |
"accept": "*/*" | |
}; | |
const response = await request.loadJSON(); | |
// Kiểm tra dữ liệu trả về có hợp lệ không | |
if (!response || !response.success || !Array.isArray(response.data) || response.data.length === 0) { | |
return createErrorWidget("Không thể tải dữ liệu. API có thể đã thay đổi hoặc cần xác thực (token hết hạn)."); | |
} | |
// Lấy dữ liệu mới nhất (là phần tử cuối cùng trong mảng) | |
const latestData = response.data[response.data.length - 1]; | |
// --- TIÊU ĐỀ WIDGET --- | |
const titleStack = widget.addStack(); | |
titleStack.layoutHorizontally(); | |
const titleText = titleStack.addText(`Giá Vàng ${GOLD_CODE}`); | |
titleText.font = Font.boldSystemFont(18); | |
titleText.textColor = new Color("#f1c40f"); // Màu vàng | |
titleStack.addSpacer(); | |
const logoImg = titleStack.addImage(SFSymbol.named("dollarsign.circle.fill").image); | |
logoImg.imageSize = new Size(24, 24); | |
logoImg.tintColor = new Color("#f1c40f"); | |
widget.addSpacer(); // Thêm khoảng trống | |
// --- HIỂN THỊ GIÁ MUA VÀ BÁN --- | |
const priceStack = widget.addStack(); | |
priceStack.layoutHorizontally(); | |
// Cột giá mua | |
const buyStack = priceStack.addStack(); | |
buyStack.layoutVertically(); | |
const buyLabel = buyStack.addText("Mua vào"); | |
buyLabel.font = Font.mediumSystemFont(14); | |
buyLabel.textColor = Color.white(); | |
buyStack.addSpacer(4); | |
const buyPriceText = buyStack.addText(formatPrice(latestData.buy)); | |
buyPriceText.font = Font.boldSystemFont(22); | |
buyPriceText.textColor = new Color("#2ecc71"); // Màu xanh lá | |
priceStack.addSpacer(); // Căn giữa 2 cột | |
// Cột giá bán | |
const sellStack = priceStack.addStack(); | |
sellStack.layoutVertically(); | |
sellStack.centerAlignContent(); | |
const sellLabel = sellStack.addText("Bán ra"); | |
sellLabel.font = Font.mediumSystemFont(14); | |
sellLabel.textColor = Color.white(); | |
sellStack.addSpacer(4); | |
const sellPriceText = sellStack.addText(formatPrice(latestData.sell)); | |
sellPriceText.font = Font.boldSystemFont(22); | |
sellPriceText.textColor = new Color("#e74c3c"); // Màu đỏ | |
widget.addSpacer(); // Thêm khoảng trống ở dưới | |
// --- THỜI GIAN CẬP NHẬT TỪ API --- | |
const updateDate = new Date(latestData.date); | |
const dateText = widget.addText(`Cập nhật: ${formatDate(updateDate)}`); | |
dateText.font = Font.regularSystemFont(10); | |
dateText.textColor = new Color("#bdc3c7"); | |
dateText.rightAlignText(); | |
} catch (error) { | |
console.error(error); | |
return createErrorWidget("Có lỗi khi chạy script. Hãy kiểm tra lại kết nối mạng hoặc API."); | |
} | |
return widget; | |
} | |
// Hàm tạo widget hiển thị lỗi | |
function createErrorWidget(errorMessage) { | |
const widget = new ListWidget(); | |
widget.addText("Lỗi Widget Giá Vàng"); | |
widget.addSpacer(5); | |
const errorText = widget.addText(errorMessage); | |
errorText.font = Font.systemFont(12); | |
errorText.textColor = Color.red(); | |
return widget; | |
} | |
// Hàm định dạng giá cho dễ đọc (đơn vị: triệu/lượng) | |
function formatPrice(priceString) { | |
const price = parseFloat(priceString); | |
if (isNaN(price) || price === 0) { | |
return "-"; | |
} | |
return (price / 1000000).toFixed(2); | |
} | |
// Hàm định dạng lại ngày tháng cho dễ nhìn | |
function formatDate(date) { | |
const options = { hour: '2-digit', minute: '2-digit', day: '2-digit', month: '2-digit' }; | |
return date.toLocaleString('vi-VN', options); | |
} | |
// --- CHẠY SCRIPT --- | |
const widget = await createWidget(); | |
if (config.runsInWidget) { | |
Script.setWidget(widget); | |
} else { | |
widget.presentMedium(); | |
} | |
Script.complete(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment