您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Automatically fetch media information from Instagram URLs, with Toastify notifications.
当前为
// ==UserScript== // @name InsCNM // @namespace http://tampermonkey.net/ // @version 5.5 // @description Automatically fetch media information from Instagram URLs, with Toastify notifications. // @author Belugu // @match https://www.instagram.com/p/* // @match https://www.instagram.com/reel/* // @match https://www.instagram.com/* // @grant GM_xmlhttpRequest // @grant GM_getResourceText // @grant GM_addStyle // @require https://code.jquery.com/jquery-3.6.0.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/toastify-js/1.12.0/toastify.min.js // @resource TOASTIFY_CSS https://cdn.jsdelivr.net/npm/toastify-js/src/toastify.min.css // @icon https://iili.io/29TPCR1.jpg // ==/UserScript== (function() { 'use strict'; // 添加 Toastify 的 CSS 样式 GM_addStyle(GM_getResourceText("TOASTIFY_CSS")); // Main logic $(document).ready(async function() { if (window.location.href.match(/^https:\/\/www\.instagram\.com\/(p|reel)\/[a-zA-Z0-9_-]+\/$/)) { const shortcode = extractShortcodeFromURL(window.location.href); if (shortcode) { const mediaInfo = await fetchMediaInfoByShortcode(shortcode); if (mediaInfo) { const { taken_at, comment_count, like_count } = mediaInfo.items[0]; showMediaInfoUI(` <p>发布时间: ${new Date(taken_at * 1000).toLocaleString()} <button class="copy-btn" data-copy="${new Date(taken_at * 1000).toLocaleString()}" style="background:none; border:none; cursor:pointer;">📋</button></p> <p>评论数: ${comment_count} <button class="copy-btn" data-copy="${comment_count}" style="background:none; border:none; cursor:pointer;">📋</button></p> <p>点赞数: ${like_count} <button class="copy-btn" data-copy="${like_count}" style="background:none; border:none; cursor:pointer;">📋</button></p> `); } else { showMediaInfoUI('<p>获取媒体信息失败。</p>'); } } } }); function showMediaInfoUI(mediaInfoHtml) { const container = $( `<div id="instagram-fetcher-ui" style="position:fixed; top:20px; right:-350px; background:white; color:black; border:1px solid #ccc; padding:15px; z-index:10000; width:300px; border-radius:10px;"> <div style="display: flex; justify-content: space-between; align-items: center;"> <h3 style="color:black; margin:0;">输入网址后按 Enter 搜索</h3> <button id="close-ui-button" style="background:none; border:none; font-size:20px; cursor:pointer; color:black;">×</button> </div> <div id="input-area" style="display: flex; align-items: center; margin-top:10px;"> <input type="text" id="instagram-url-input" placeholder="输入网址" style="width:80%; padding:5px; color:black; border:1px solid #ccc; border-radius:5px; box-shadow:none; outline:none;"/> </div> <div id="media-info-output" style="margin-top:15px; font-size:14px;">${mediaInfoHtml}</div> </div>` ); $('body').append(container); $('#instagram-fetcher-ui').animate({ right: '20px' }, 400); $('#instagram-url-input').on('keyup', async function(e) { if (e.which === 13) { // Enter key pressed const url = $('#instagram-url-input').val(); console.log("User entered URL:", url); if (url) { const shortcode = extractShortcodeFromURL(url); if (shortcode) { $('#media-info-output').text('正在获取媒体信息...'); const mediaInfo = await fetchMediaInfoByShortcode(shortcode); if (mediaInfo) { const { taken_at, comment_count, like_count } = mediaInfo.items[0]; $('#media-info-output').html( `<p>发布时间: ${new Date(taken_at * 1000).toLocaleString()} <button class="copy-btn" data-copy="${new Date(taken_at * 1000).toLocaleString()}" style="background:none; border:none; cursor:pointer;">📋</button></p> <p>评论数: ${comment_count} <button class="copy-btn" data-copy="${comment_count}" style="background:none; border:none; cursor:pointer;">📋</button></p> <p>点赞数: ${like_count} <button class="copy-btn" data-copy="${like_count}" style="background:none; border:none; cursor:pointer;">📋</button></p>` ); } else { $('#media-info-output').text('获取媒体信息失败。'); } } else { $('#media-info-output').text('无效的 Instagram URL。'); } } } }); $('#close-ui-button').click(function() { $(this).css({ transform: 'scale(0.95)' }); setTimeout(() => $(this).css({ transform: 'scale(1)' }), 100); $('#instagram-fetcher-ui').animate({ right: '-350px' }, 400, function() { $(this).remove(); }); }); $(document).on('click', '.copy-btn', function() { const textToCopy = $(this).data('copy'); navigator.clipboard.writeText(textToCopy).then(() => { showNotification("已复制到剪贴板"); }).catch(err => { console.error('复制失败:', err); }); }); } function showNotification(message) { Toastify({ text: message, duration: 3000, close: true, gravity: 'top', // `top` 或 `bottom` position: 'center', // `left`, `center` 或 `right` style: { background: getRandomGradientColor(), color: '#FFFFFF', // 可选,设置文字颜色为白色 borderRadius: '10px', }, stopOnFocus: true, // 鼠标悬停时停止关闭 }).showToast(); } // 获取随机的渐变颜色 function getRandomGradientColor() { const gradients = [ 'linear-gradient(to right, #FF512F, #F09819)', 'linear-gradient(to right, #00b09b, #96c93d)', 'linear-gradient(to right, #ff5f6d, #ffc371)', 'linear-gradient(to right, #2193b0, #6dd5ed)', 'linear-gradient(to right, #cc2b5e, #753a88)', 'linear-gradient(to right, #ee9ca7, #ffdde1)', 'linear-gradient(to right, #b92b27, #1565C0)', 'linear-gradient(to right, #373B44, #4286f4)', 'linear-gradient(to right, #ff7e5f, #feb47b)', 'linear-gradient(to right, #8360c3, #2ebf91)' ]; return gradients[Math.floor(Math.random() * gradients.length)]; } // Listen for Alt+N to toggle the input UI document.addEventListener('keydown', function (e) { if (e.altKey && e.key === 'n') { const container = $('#instagram-fetcher-ui'); if (container.length) { container.find('#close-ui-button').click(); } else { showMediaInfoUI('<p>输入网址后按 Enter 搜索。</p>'); } } }); // Function to extract the shortcode from a given URL function extractShortcodeFromURL(url) { try { const urlObj = new URL(url); const pathSegments = urlObj.pathname.split('/'); console.log("URL Object:", urlObj); console.log("Path Segments:", pathSegments); if (pathSegments[1] === 'p' || pathSegments[1] === 'reel') { return pathSegments[2] ? pathSegments[2] : null; } return null; } catch (error) { console.error("Error extracting shortcode from URL:", error); return null; } } // Function to fetch media info by shortcode async function fetchMediaInfoByShortcode(shortcode) { const mediaId = await getMediaID(shortcode); if (!mediaId) { console.error("Failed to fetch media ID."); $('#media-info-output').text('获取媒体 ID 失败,请稍后重试。'); return null; } try { const mediaInfo = await getMediaInfo(mediaId); console.log("Media Info:", mediaInfo); return mediaInfo; } catch (error) { console.error("Error retrieving media info:", error); return null; } } // Function to fetch media ID using shortcode async function getMediaID(shortcode) { try { const response = await fetch(`https://www.instagram.com/p/${shortcode}/`, { headers: { "User-Agent": window.navigator.userAgent, "Accept": "text/html" } }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const html = await response.text(); const mediaIdMatch = html.match(/"media_id":"(\d+)"/); if (mediaIdMatch) { return mediaIdMatch[1]; } else { console.error("Media ID not found in page HTML."); } } catch (error) { console.error("Error fetching media ID:", error); } return null; } // Function to get app ID function getAppID() { let result = null; $('script[type="application/json"]').each(function() { const regexp = /"APP_ID":"([0-9]+)"/ig; const matcher = $(this).text().match(regexp); if (matcher != null && result == null) { result = [...$(this).text().matchAll(regexp)]; } }); return (result) ? result.at(0).at(-1) : null; } // Function to get media info using media ID async function getMediaInfo(mediaId) { return new Promise((resolve, reject) => { let getURL = `https://i.instagram.com/api/v1/media/${mediaId}/info/`; if (mediaId == null) { console.error("Cannot call Media API because the media ID is invalid."); reject("Cannot call Media API because the media ID is invalid."); return; } GM_xmlhttpRequest({ method: "GET", url: getURL, headers: { "User-Agent": window.navigator.userAgent, "Accept": "application/json", 'X-IG-App-ID': getAppID() }, onload: function (response) { try { if (response.finalUrl == getURL) { let obj = JSON.parse(response.responseText); resolve(obj); } else { let finalURL = new URL(response.finalUrl); if (finalURL.pathname.startsWith('/accounts/login')) { console.error("The account must be logged in to access Media API."); } else { console.error('Unable to retrieve content because the API was redirected to "' + response.finalUrl + '"'); } reject(-1); } } catch (error) { console.error("Error parsing JSON response:", error); reject(error); } }, onerror: function (err) { reject(err); } }); }); } })();