28.2.26 |
5
nhận xét
|
lượt xem
Giới thiệu
- “Báo lỗi” trong từng bài viết
- Tự động lấy URL và tiêu đề bài viết
- Chuyển sang trang báo lỗi
- Gửi dữ liệu về Telegram
- Có captcha + chống spam
- Free 😁
Phần 1: Tạo API bảo mật bằng Cloudflare Worker
Bước 1: Vào Cloudflare → Compute → Workers & Pages → Create application → Chọn "Start with Hello World!" → Deploy
Bước 2: Edit code và Dán code sau:
export default {
async fetch(request, env) {
const origin = request.headers.get("Origin");
const corsHeaders = {
"Access-Control-Allow-Origin": origin || "*",
"Access-Control-Allow-Methods": "POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type",
"Content-Type": "application/json"
};
if (request.method === "OPTIONS") {
return new Response(null, { headers: corsHeaders });
}
if (
origin &&
!origin.endsWith("vncoding.com")
) {
return new Response(
JSON.stringify({ error: "Forbidden" }),
{ status: 403, headers: corsHeaders }
);
}
if (request.method !== "POST") {
return new Response(
JSON.stringify({ error: "Method Not Allowed" }),
{ status: 405, headers: corsHeaders }
);
}
const body = await request.json();
const {
title,
errorType,
content,
email,
imageUrl,
pageUrl,
userAgent,
secret
} = body;
if (secret !== env.FORM_SECRET) {
return new Response(
JSON.stringify({ error: "Unauthorized" }),
{ status: 401, headers: corsHeaders }
);
}
const botToken = env.TELEGRAM_TOKEN;
const chatId = "-YOUR_CHAT_ID";
const ip = request.headers.get("CF-Connecting-IP") || "Unknown";
const dateTime = new Date().toLocaleString("vi-VN");
const message = `
🚨 BÁO LỖI WEBSITE
Tiêu đề: ${title}
Loại lỗi: ${errorType}
Nội dung:
${content}
Email: ${email}
Trang: ${pageUrl}
Thiết bị: ${userAgent}
Ảnh: ${imageUrl || "Không có"}
IP: ${ip}
Thời gian: ${dateTime}
`;
await fetch(`https://api.telegram.org/bot${botToken}/sendMessage`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
chat_id: chatId,
text: message
})
});
return new Response(
JSON.stringify({ success: true }),
{ headers: corsHeaders }
);
}
};
Thay vncoding.com thành domain của bạnThay -YOUR_CHAT_ID thành chat ID telegram của bạn. Nếu chưa biết có thể tham khảo bài viết này
Bước 3: Thêm Variables trong Worker:
Chọn tab "Settings" → Tại "Variables and Secrets" click button "Add" sau đó nhậpTELEGRAM_TOKEN = Token bot của bạn
FORM_SECRET = chuoi_bi_mat
Phần 2: Thêm nút “Báo lỗi” trong bài viết
<button onclick="vncodingGoToReport()">🚨 Báo lỗi</button>
<script>
function vncodingGoToReport(){
const currentUrl = window.location.href;
let articleTitle = "";
const h1 = document.querySelector("h1");
if(h1){
articleTitle = h1.innerText.trim();
}else{
articleTitle = document.title;
}
const reportPage = "/p/bao-loi.html";
const finalUrl =
reportPage +
"?url=" + encodeURIComponent(currentUrl) +
"&title=" + encodeURIComponent(articleTitle);
window.open(finalUrl, "_blank", "noopener,noreferrer");
}
</script>
/p/bao-loi.html chính là link của trang báo lỗi
Phần 3: Tạo trang báo lỗi /p/bao-loi.html
Thêm phần hiển thị thông tin bài viết:
<h2>🚨 Báo lỗi bài viết</h2>
<div class="vncoding-article-info">
<p><strong>📄 Bài viết đang báo lỗi:</strong></p>
<p id="vncoding_display_title" class="vncoding-title"></p>
<p><strong>🔗 Link bài viết:</strong></p>
<p>
<a id="vncoding_display_url" href="#" target="_blank"></a>
</p>
</div>
<div class="vncoding-report-wrapper">
<select id="vncoding_type">
<option value="Bản quyền nội dung">Bản quyền nội dung</option>
<option value="Nội dung sai sự thật">Nội dung sai sự thật</option>
<option value="Lỗi hiển thị giao diện">Lỗi hiển thị giao diện</option>
<option value="Link hỏng (404)">Link hỏng (404)</option>
<option value="Lỗi trên mobile">Lỗi trên mobile</option>
<option value="Không đăng nhập được">Không đăng nhập được</option>
<option value="Khác">Khác</option>
</select>
<textarea id="vncoding_content" placeholder="Mô tả chi tiết lỗi"></textarea>
<input type="email" id="vncoding_email" placeholder="Email liên hệ">
<input type="url" id="vncoding_image_url" placeholder="Link ảnh minh họa (nếu có)">
<div class="vncoding-captcha-box">
<span id="vncoding_captcha_question"></span>
<input type="text" id="vncoding_captcha_answer" placeholder="Nhập kết quả">
</div>
<button id="vncoding_sendBtn" onclick="vncodingSendReport()">
Gửi báo lỗi
</button>
<p id="vncoding_msg"></p>
</div>
<style>
.vncoding-article-info{
background:#f5f7fa;
padding:15px;
border-radius:8px;
margin-bottom:20px;
border-left:4px solid #007bff;
}
.vncoding-title{
font-size:18px;
font-weight:600;
margin-bottom:15px;
}
.vncoding-report-wrapper input,
.vncoding-report-wrapper select,
.vncoding-report-wrapper textarea{
width:100%;
padding:12px;
margin-bottom:12px;
border:1px solid #ddd;
border-radius:8px;
font-size:14px;
}
.vncoding-report-wrapper textarea{
min-height:120px;
resize:vertical;
}
.vncoding-report-wrapper button{
width:100%;
padding:14px;
border:none;
border-radius:8px;
background:linear-gradient(90deg,#007bff,#0056ff);
color:white;
font-size:15px;
cursor:pointer;
}
.vncoding-captcha-box{
display:flex;
gap:10px;
}
#vncoding_msg{
margin-top:10px;
font-weight:bold;
text-align:center;
}
</style>
<script>
const WORKER_URL = "https://api.ten-worker-cua-ban.workers.dev/";
const FORM_SECRET = "chuoi_bi_mat";
let captchaResult = 0;
let lastSendTime = 0;
function getQueryParam(name){
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get(name);
}
function generateCaptcha(){
const a = Math.floor(Math.random()*10)+1;
const b = Math.floor(Math.random()*10)+1;
captchaResult = a + b;
document.getElementById("vncoding_captcha_question").innerText =
"Mã kiểm tra: " + a + " + " + b + " = ?";
}
window.onload = function(){
const articleUrl = getQueryParam("url");
const articleTitle = getQueryParam("title");
if(articleUrl){
const decodedUrl = decodeURIComponent(articleUrl);
document.getElementById("vncoding_display_url").innerText = decodedUrl;
document.getElementById("vncoding_display_url").href = decodedUrl;
window.currentArticleUrl = decodedUrl;
}
if(articleTitle){
const decodedTitle = decodeURIComponent(articleTitle);
document.getElementById("vncoding_display_title").innerText = decodedTitle;
window.currentArticleTitle = decodedTitle;
}
generateCaptcha();
};
async function vncodingSendReport(){
const now = Date.now();
if(now - lastSendTime < 60000){
document.getElementById("vncoding_msg").innerText =
"Vui lòng chờ 60 giây trước khi gửi lại.";
return;
}
const pageUrl = window.currentArticleUrl || "";
const autoTitle = window.currentArticleTitle || "";
const type = document.getElementById("vncoding_type").value;
const content = document.getElementById("vncoding_content").value.trim();
const email = document.getElementById("vncoding_email").value.trim();
const imageUrl = document.getElementById("vncoding_image_url").value.trim();
const captcha = document.getElementById("vncoding_captcha_answer").value.trim();
if(!content || !email){
document.getElementById("vncoding_msg").innerText =
"Vui lòng nhập đầy đủ thông tin.";
return;
}
if(parseInt(captcha) !== captchaResult){
document.getElementById("vncoding_msg").innerText =
"Mã kiểm tra không đúng.";
generateCaptcha();
return;
}
const btn = document.getElementById("vncoding_sendBtn");
btn.disabled = true;
btn.innerText = "Đang gửi...";
try{
const res = await fetch(WORKER_URL,{
method:"POST",
headers:{ "Content-Type":"application/json" },
body: JSON.stringify({
title: autoTitle,
errorType: type,
content,
email,
imageUrl,
pageUrl,
userAgent: navigator.userAgent,
secret: FORM_SECRET
})
});
if(res.ok){
document.getElementById("vncoding_msg").innerText =
"Gửi thành công!";
document.getElementById("vncoding_content").value="";
document.getElementById("vncoding_email").value="";
document.getElementById("vncoding_image_url").value="";
document.getElementById("vncoding_captcha_answer").value="";
generateCaptcha();
lastSendTime = Date.now();
}else{
document.getElementById("vncoding_msg").innerText =
"Có lỗi xảy ra.";
}
}catch(e){
document.getElementById("vncoding_msg").innerText =
"Không thể kết nối máy chủ.";
}
btn.disabled=false;
btn.innerText="Gửi báo lỗi";
}
</script>
https://api.ten-worker-cua-ban.workers.dev/ thay bằng link Worker của bạn
🎯 Kết quả
- Người dùng đang đọc bài viết
- Click “Báo lỗi”
- URL + Tiêu đề được tự động điền
- Gửi lỗi về Telegram
🔐 Bảo mật
- Không lộ Bot Token
- Chống spam
- Gửi kèm IP + thiết bị
Hãy để lại bình luận bên dưới nếu bạn gặp khó khăn trong quá trình thực hiện 👇







tên miền mới trông tây hẳn nhưng logo chữ V nhìn lạ mắt cảm giác không sịn bằng chữ B như trước
REPLY DELETEHa ha. Không có ý tưởng gì thì cứ lấy chữ cái đầu tiên của tên miền làm logo luôn cho nhanh 🤣
REPLY DELETETưởng anh em blog không lên bài thôi hóa ra là anh em đều off blog hết rồi, chả thèm đọc comment
REPLY DELETEAi hoạt động vẫn hoạt động mà
REPLY DELETECoi như blog để lưu lại kiến thức sau tìm lại cho dễ 😁
Hay quá bro <3
REPLY DELETE