Cafe Bazaar Downloader

Script for extracting app information and downloading from Cafe Bazaar

当前为 2023-09-12 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Cafe Bazaar Downloader
  3. // @namespace http://your-namespace.com
  4. // @version 1.0
  5. // @description Script for extracting app information and downloading from Cafe Bazaar
  6. // @author https://t.me/TheErfon
  7. // @match https://cafebazaar.ir/*
  8. // @grant none
  9. // @license CC BY-NC-ND 4.0
  10. // @licenseURL https://github.com/Rainman69/CafeBazaar-Downloader/blob/main/LICENSE
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. function extractPackageName(url) {
  17. const regex = /https:\/\/cafebazaar\.ir\/app\/(?:\?id=)?([\w.-]+)/;
  18. const match = url.match(regex);
  19. if (match) {
  20. const packageName = match[1];
  21. return packageName;
  22. } else {
  23. console.error("Invalid URL format: " + url);
  24. throw new Error("Invalid URL format");
  25. }
  26. }
  27.  
  28. function callDownloadApi(packageName, sdk, retry = true) {
  29. const payload = {
  30. "properties": {
  31. "language": 2,
  32. "clientVersionCode": 1100301,
  33. "androidClientInfo": {
  34. "sdkVersion": sdk,
  35. "cpu": "x86,armeabi-v7a,armeabi"
  36. },
  37. "clientVersion": "11.3.1",
  38. "isKidsEnabled": false
  39. },
  40. "singleRequest": {
  41. "appDownloadInfoRequest": {
  42. "downloadStatus": 1,
  43. "packageName": packageName,
  44. "referrers": []
  45. }
  46. }
  47. };
  48.  
  49. return fetch("https://api.cafebazaar.ir/rest-v1/process/AppDownloadInfoRequest", {
  50. method: 'POST',
  51. headers: {
  52. 'Content-Type': 'application/json'
  53. },
  54. body: JSON.stringify(payload)
  55. })
  56. .then(response => {
  57. if (response.ok) {
  58. return response.json();
  59. } else {
  60. console.error("API request failed for package: " + packageName);
  61. if (retry && sdk !== 25) {
  62. console.log("Retrying with SDK version 25 for package: " + packageName);
  63. return callDownloadApi(packageName, 25, false);
  64. } else {
  65. console.error("Abnormal API response for package: " + packageName);
  66. throw new Error("Abnormal API response. Check your request and try again.");
  67. }
  68. }
  69. })
  70. .then(data => handleResponse(data));
  71. }
  72.  
  73. function handleResponse(data) {
  74. const appInfo = data.singleReply.appDownloadInfoReply;
  75. if (!appInfo) {
  76. console.error("Response does not include expected data");
  77. throw new Error("Response does not include expected data");
  78. }
  79.  
  80. const downloadUrls = appInfo.fullPathUrls || [];
  81. if (!downloadUrls.length) {
  82. console.error("Download URLs are empty");
  83. throw new Error("Download URLs are empty");
  84. }
  85.  
  86. const fileSize = parseInt(appInfo.packageSize, 10) / 1024 / 1024;
  87. const versionCode = appInfo.versionCode || 0;
  88.  
  89. return {
  90. downloadLink: downloadUrls[downloadUrls.length - 1],
  91. fileSize,
  92. versionCode
  93. };
  94. }
  95.  
  96. function main() {
  97. try {
  98. const currentUrl = window.location.href;
  99. console.log("Current URL: " + currentUrl);
  100.  
  101. const packageName = extractPackageName(currentUrl);
  102. callDownloadApi(packageName, 33)
  103. .then(downloadInfo => {
  104. const { downloadLink, fileSize, versionCode } = downloadInfo;
  105.  
  106. console.log("App information retrieved successfully for package: " + packageName);
  107. console.log("Download link: " + downloadLink);
  108. console.log("File size: " + fileSize.toFixed(2) + " MB");
  109. console.log("Version: " + versionCode);
  110.  
  111. // Perform the download automatically
  112. window.location.href = downloadLink;
  113. })
  114. .catch(error => {
  115. console.error("An error occurred: " + error.message);
  116. });
  117. } catch (error) {
  118. console.error("An error occurred: " + error.message);
  119. }
  120. }
  121.  
  122. main();
  123. })();