| 133 | const line = msg.text?.trim()?.split(/\r?\n/g)?.[0] || ""; |
| 134 | const args = line.split(/\s+/) || []; |
| 135 | const [, ...rest] = args; |
| 136 | if (rest.length === 0 || /^h(elp)?$/i.test(rest[0])) { |
| 137 | await msg.edit({ text: help_text, parseMode: "html" }); |
| 138 | return; |
| 139 | } |
| 140 | if (rest[1] && /^h(elp)?$/i.test(rest[1])) { |
| 141 | await msg.edit({ text: help_text, parseMode: "html" }); |
| 142 | return; |
| 143 | } |
| 144 | const bin = (rest[0] || "").replace(/\D/g, ""); |
| 145 | if (bin.length < 6 || bin.length > 8) { |
| 146 | await msg.edit({ text: `❌ 无效BIN:<code>${htmlEscape(rest[0] || "")}</code>\n需6-8位数字`, parseMode: "html" }); |
| 147 | return; |
| 148 | } |
| 149 | await msg.edit({ text: `🔍 正在查询 BIN ${bin}...` }); |
| 150 | const axios = (await import("axios")).default; |
| 151 | try { |
| 152 | // 先尝试 Bincheck(抓取概要信息) |
| 153 | const bc = await fetchFromBincheck(bin); |
| 154 | // 再用 Binlist 补全字段 |
| 155 | const r = await axios.get(`https://lookup.binlist.net/${bin}`, { |
| 156 | headers: { "Accept-Version": "3" }, |
| 157 | timeout: 10000, |
| 158 | }); |
| 159 | const d = r.data || {}; |
| 160 | const country = d.country ? `${d.country.emoji || ""} ${d.country.name || ""} (${d.country.alpha2 || ""})` : "N/A"; |
| 161 | const bank = d.bank |
| 162 | ? `${d.bank.name || ""}${d.bank.url ? ` | ${d.bank.url}` : ""}${d.bank.phone ? ` | ${d.bank.phone}` : ""}${d.bank.city ? ` | ${d.bank.city}` : ""}` |
| 163 | : "N/A"; |
| 164 | const scheme = formatScheme(d.scheme); |
| 165 | const brand = toTitleCase(d.brand); |
| 166 | const typeZh = formatType(d.type); |
| 167 | const lenTxt = (d.number && Number.isFinite(d.number.length)) ? `${d.number.length}位` : "未知位数"; |
| 168 | const luhnTxt = (d.number && typeof d.number.luhn === "boolean") ? (d.number.luhn ? "是" : "否") : "未知"; |
| 169 | const num = `${lenTxt} | Luhn:${luhnTxt}`; |
| 170 | // 计算品牌(方案名)优先取 Bincheck,其次 Binlist 的scheme |
| 171 | const schemeDisp = schemeBrandDisplay(bc.scheme || d.scheme); |
| 172 | // 等级:从 brand 中粗略提取(BUSINESS/CORPORATE/PLATINUM/GOLD/...) |
| 173 | const level = (brand || "").toUpperCase().match(/BUSINESS|CORPORATE|PLATINUM|GOLD|CLASSIC|SIGNATURE|INFINITE|WORLD|PREMIUM/); |
| 174 | const levelTxt = level ? level[0] : "—"; |
| 175 | const isBusiness = /BUSINESS|CORPORATE|COMMERCIAL/i.test(brand || ""); |
| 176 | const prepaid = d.prepaid === true ? "✓" : "×"; |
| 177 | const businessMark = isBusiness ? "✓" : "×"; |
| 178 | const countryName = bc.country || d.country?.name || ""; |
| 179 | const cnCountry = countryName.replace(" (Province of China)", "").replace("Taiwan, Province of China", "Taiwan"); |
| 180 | const countryLine = cnCountry === "Taiwan" ? "台湾" : (cnCountry || "未知"); |
| 181 | const currencyLine = currencyCn(d.country?.currency); |
| 182 | const bankLine = normalizeBankName(bc.bank || d.bank?.name || "N/A"); |
| 183 | |
| 184 | const txt = |
| 185 | `卡头检测\n` + |
| 186 | `🔢卡头:${bin}\n` + |
| 187 | `💳品牌:${htmlEscape(schemeDisp)}\n` + |
| 188 | `🔖类型:${htmlEscape(typeZh === "信用" ? "贷记" : typeZh)}\n` + |
| 189 | `💹等级:${levelTxt}\n\n` + |
| 190 | `🗺国家:${htmlEscape(countryLine)}\n` + |
| 191 | `💸货币:${htmlEscape(currencyLine)}\n` + |
| 192 | `🏦银行:${htmlEscape(bankLine)}\n\n` + |
nothing calls this directly
no test coverage detected