Convert Email Address to Duckduckgo Anonymous email format

Converts an email to duckgo anonymous email format, now with minimize functionality

当前为 2025-03-01 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Convert Email Address to Duckduckgo Anonymous email format
  3. // @namespace http://tampermonkey.net/
  4. // @author aspen138
  5. // @version 1.1.2
  6. // @description Converts an email to duckgo anonymous email format, now with minimize functionality
  7. // @match https://mail.google.com/*
  8. // @match https://gmail.com/*
  9. // @match https://outlook.live.com/*
  10. // @match https://outlook.com/*
  11. // @match https://mail.yahoo.com/*
  12. // @match https://yahoo.com/mail/*
  13. // @match https://mail.qq.com/*
  14. // @match https://exmail.qq.com/*
  15. // @match https://proton.me/*
  16. // @match https://mail.proton.me/*
  17. // @match https://icloud.com/mail/*
  18. // @match https://mail.apple.com/*
  19. // @match https://zoho.com/mail/*
  20. // @match https://mail.zoho.com/*
  21. // @match https://mail.aol.com/*
  22. // @match https://aol.com/mail/*
  23. // @match https://www.mail.com/*
  24. // @match https://email.mail.com/*
  25. // @match https://mail.yandex.com/*
  26. // @match https://yandex.com/mail/*
  27. // @match https://mail.163.com/*
  28. // @match https://www.163.com/mail/*
  29. // @match https://mail.126.com/*
  30. // @match https://www.126.com/*
  31. // @match https://mail.sina.com/*
  32. // @match https://mail.sina.com.cn/*
  33. // @match https://gmx.com/*
  34. // @match https://mail.gmx.com/*
  35. // @match https://fastmail.com/*
  36. // @match https://mail.fastmail.com/*
  37. // @icon data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMTI4IDEyOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8cGF0aCBmaWxsPSIjZGU1ODMzIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik02NCAxMjhjMzUuMzQ2IDAgNjQtMjguNjU0IDY0LTY0IDAtMzUuMzQ2LTI4LjY1NC02NC02NC02NFMwIDI4LjY1NCAwIDY0YzAgMzUuMzQ2IDI4LjY1NCA2NCA2NCA2NHoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPgogIDxwYXRoIGZpbGw9IiNkZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTczIDExMS43NWMwLS41LjEyMy0uNjE0LTEuNDY3LTMuNzgyLTQuMjI0LTguNDU5LTguNDY5LTIwLjM4NC02LjUzOC0yOC4wNzUuMzUyLTEuMzk3LTMuOTc5LTUxLjc0NC03LjA0LTUzLjM2NS0zLjQwMy0xLjgxMy03LjU5LTQuNjktMTEuNDE5LTUuMzMtMS45NDMtLjMxLTQuNDktLjE2NC02LjQ4Mi4xMDUtLjM1NC4wNDctLjM2OC42ODQtLjAzLjc5OCAxLjMwNy40NDMgMi44OTUgMS4yMTIgMy44MyAyLjM3NS4xNzguMjItLjA2LjU2Ni0uMzQyLjU3Ny0uODgyLjAzMi0yLjQ4Mi40MDItNC41OTMgMi4xOTUtLjI0NC4yMDctLjA0Mi41OTIuMjczLjUzIDQuNTM2LS44OTcgOS4xNy0uNDU1IDExLjkgMi4wMjcuMTc3LjE2LjA4NC40NS0uMTQ3LjUxMi0yMy42OTQgNi40NC0xOS4wMDQgMjcuMDUtMTIuNjk2IDUyLjM0NCA1LjYxOSAyMi41MyA3LjczMyAyOS43OTIgOC40IDMyLjAwNGEuNzE4LjcxOCAwIDAgMCAuNDIzLjQ2N0M1NS4yMjggMTE4LjM4IDczIDExOC41MjQgNzMgMTEzeiIgY2xpcC1ydWxlPSJldmVub2RkIi8+CiAgPHBhdGggZmlsbD0iI2ZmZiIgZD0iTTc2LjI1IDExNi41Yy0yLjg3NSAxLjEyNS04LjUgMS42MjUtMTEuNzUgMS42MjUtNC43NjUgMC0xMS42MjUtLjc1LTE0LjEyNS0xLjg3NS0xLjU0NC00Ljc1MS02LjE2NS0xOS40OC0xMC43MjgtMzguMTg1bC0uNDQ3LTEuODI3LS4wMDMtLjAxNWMtNS40MjUtMjIuMTU2LTkuODU1LTQwLjI1MyAxNC40MjctNDUuOTM4LjIyMi0uMDUyLjMzLS4zMTcuMTgzLS40OTItMi43ODYtMy4zMDUtOC4wMDUtNC4zODgtMTQuNjA0LTIuMTExLS4yNy4wOTMtLjUwNi0uMTgtLjMzOC0uNDEyIDEuMjk0LTEuNzgzIDMuODIzLTMuMTU1IDUuMDcyLTMuNzU2LjI1OC0uMTI0LjI0Mi0uNTAyLS4wMzEtLjU4OGEyNy44NzkgMjcuODc5IDAgMCAwLTMuNzcxLS45Yy0uMzctLjA1OS0uNDA0LS42OTMtLjAzMi0uNzQzIDkuMzU2LTEuMjU5IDE5LjEyNSAxLjU1IDI0LjAyOCA3LjcyNmEuMzI2LjMyNiAwIDAgMCAuMTg1LjExNGMxNy45NTMgMy44NTYgMTkuMjM5IDMyLjIzNSAxNy4xNyAzMy41MjgtLjQwNy4yNTUtMS43MTQuMTA4LTMuNDM4LS4wODQtNi45ODUtLjc4Mi0yMC44MTgtMi4zMy05LjQwMSAxOC45NDcuMTEzLjIxLS4wMzcuNDg4LS4yNzIuNTI1LTYuNDM4IDEgMS44MTIgMjEuMTczIDcuODc1IDM0LjQ2MXoiLz4KICA8cGF0aCBmaWxsPSIjM2NhODJiIiBkPSJNODQuMjggOTAuNjk4Yy0xLjM2Ny0uNjMzLTYuNjIyIDMuMTM1LTEwLjExIDYuMDI4LS43MjgtMS4wMzEtMi4xMDMtMS43OC01LjIwMy0xLjI0Mi0yLjcxMy40NzItNC4yMTEgMS4xMjYtNC44OCAyLjI1NC00LjI4My0xLjYyMy0xMS40ODgtNC4xMy0xMy4yMjktMS43MS0xLjkwMiAyLjY0Ni40NzYgMTUuMTYxIDMuMDAzIDE2Ljc4NiAxLjMyLjg0OSA3LjYzLTMuMjA4IDEwLjkyNi02LjAwNS41MzIuNzQ5IDEuMzg4IDEuMTc4IDMuMTQ4IDEuMTM3IDIuNjYyLS4wNjIgNi45NzktLjY4MSA3LjY0OS0xLjkyMS4wNC0uMDc1LjA3NS0uMTY0LjEwNS0uMjY2IDMuMzg4IDEuMjY2IDkuMzUgMi42MDYgMTAuNjgxIDIuNDA2IDMuNDcxLS41MjEtLjQ4My0xNi43MjMtMi4wOS0xNy40Njd6Ii8+CiAgPHBhdGggZmlsbD0iIzRjYmEzYyIgZD0iTTc0LjQ5IDk3LjA5N2MuMTQ0LjI1Ni4yNi41MjYuMzU4LjguNDgzIDEuMzUyIDEuMjcgNS42NDguNjc0IDYuNzA5LS41OTUgMS4wNjItNC40NTkgMS41NzQtNi44NDMgMS42MTVzLTIuOTItLjgzMS0zLjQwMy0yLjE4MWMtLjM4Ny0xLjA4MS0uNTc3LTMuNjIxLS41NzItNS4wNzUtLjA5OC0yLjE1OC42OS0yLjkxNiA0LjMzNC0zLjUwNiAyLjY5Ni0uNDM2IDQuMTIyLjA3MSA0Ljk0NC45NCAzLjgyOC0yLjg1NyAxMC4yMTUtNi44ODkgMTAuODM4LTYuMTUyIDMuMTA2IDMuNjc0IDMuNDk5IDEyLjQyIDIuODI2IDE1LjkzOS0uMjIgMS4xNTEtMTAuNTA1LTEuMTM5LTEwLjUwNS0yLjM4IDAtNS4xNTItMS4zMzctNi41NjUtMi42NS02Ljcxem0tMjIuNTMtMS42MDljLjg0My0xLjMzMyA3LjY3NC4zMjQgMTEuNDI0IDEuOTkzIDAgMC0uNzcgMy40OTEuNDU2IDcuNjA0LjM1OSAxLjIwMy04LjYyNyA2LjU1OC05LjggNS42MzctMS4zNTUtMS4wNjUtMy44NS0xMi40MzItMi4wOC0xNS4yMzR6Ii8+CiAgPHBhdGggZmlsbD0iI2ZjMyIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNTUuMjY5IDY4LjQwN2MuNTUzLTIuNDA0IDMuMTI3LTYuOTMyIDEyLjMyMS02LjgyMiA0LjY0OC0uMDIgMTAuNDIyLS4wMDMgMTQuMjUtLjQzN2E1MS4zMTIgNTEuMzEyIDAgMCAwIDEyLjcyNi0zLjA5NWMzLjk4LTEuNTE5IDUuMzkyLTEuMTggNS44ODctLjI3MS41NDQuOTk4LS4wOTcgMi43MjEtMS40ODggNC4zMDgtMi42NTYgMy4wMzEtNy40MzEgNS4zOC0xNS44NjUgNi4wNzctOC40MzMuNjk3LTE0LjAyLTEuNTY2LTE2LjQyNSAyLjExOC0xLjAzOCAxLjU4OC0uMjM2IDUuMzMyIDcuOTIgNi41MTEgMTEuMDIgMS41OSAyMC4wNzItMS45MTcgMjEuMTkuMjAxcy01LjMyMyA2LjQyOC0xNi4zNjIgNi41MThjLTExLjAzOS4wOS0xNy45MzQtMy44NjUtMjAuMzc5LTUuODMtMy4xMDItMi40OTUtNC40OS02LjEzMy0zLjc3NS05LjI3OHoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPgogIDxnIGZpbGw9IiMxNDMwN2UiIG9wYWNpdHk9Ii44Ij4KICAgIDxwYXRoIGQ9Ik02OS4zMjcgNDIuMTI3Yy42MTYtMS4wMDggMS45ODEtMS43ODYgNC4yMTYtMS43ODYgMi4yMzQgMCAzLjI4NS44ODkgNC4wMTMgMS44OC4xNDguMjAyLS4wNzYuNDQtLjMwNi4zNGE1OS44NjkgNTkuODY5IDAgMCAxLS4xNjgtLjA3M2MtLjgxNy0uMzU3LTEuODItLjc5NS0zLjU0LS44Mi0xLjgzOC0uMDI2LTIuOTk3LjQzNS0zLjcyNy44MzEtLjI0Ni4xMzQtLjYzNC0uMTMzLS40ODgtLjM3MnptLTI1LjE1NyAxLjI5YzIuMTctLjkwNyAzLjg3Ni0uNzkgNS4wODEtLjUwNC4yNTQuMDYuNDMtLjIxMy4yMjgtLjM3Ny0uOTM2LS43NTUtMy4wMy0xLjY5Mi01Ljc2MS0uNjc0LTIuNDM3LjkwOS0zLjU4NSAyLjc5Ni0zLjU5MiA0LjAzOC0uMDAyLjI5Mi42LjMxNy43NTYuMDcuNDItLjY3IDEuMTItMS42NDYgMy4yODktMi41NTN6Ii8+CiAgICA8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03NS40NCA1NS45MmEzLjQ3IDMuNDcgMCAwIDEtMy40NzMtMy40NjIgMy40NyAzLjQ3IDAgMCAxIDMuNDczLTMuNDYgMy40NyAzLjQ3IDAgMCAxIDMuNDc1IDMuNDYgMy40NyAzLjQ3IDAgMCAxLTMuNDc0IDMuNDYyem0yLjQ0Ny00LjYwOGEuODk5Ljg5OSAwIDAgMC0xLjc5OSAwYzAgLjQ5NC40MDUuODk1LjkuODk1LjQ5OSAwIC45LS40LjktLjg5NXptLTI1LjQ2NCAzLjU0MmE0LjA0MiA0LjA0MiAwIDAgMS00LjA0OSA0LjAzNyA0LjA0NSA0LjA0NSAwIDAgMS00LjA1LTQuMDM3IDQuMDQ1IDQuMDQ1IDAgMCAxIDQuMDUtNC4wMzcgNC4wNDUgNC4wNDUgMCAwIDEgNC4wNSA0LjAzN3ptLTEuMTkzLTEuMzM4YTEuMDUgMS4wNSAwIDAgMC0yLjA5NyAwIDEuMDQ3IDEuMDQ3IDAgMCAwIDIuMDk3IDB6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz4KICA8L2c+CiAgPHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNjQgMTE3Ljc1YzI5LjY4NSAwIDUzLjc1LTI0LjA2NSA1My43NS01My43NVM5My42ODUgMTAuMjUgNjQgMTAuMjUgMTAuMjUgMzQuMzE1IDEwLjI1IDY0IDM0LjMxNSAxMTcuNzUgNjQgMTE3Ljc1em0wIDVjMzIuNDQ3IDAgNTguNzUtMjYuMzAzIDU4Ljc1LTU4Ljc1Uzk2LjQ0NyA1LjI1IDY0IDUuMjUgNS4yNSAzMS41NTMgNS4yNSA2NCAzMS41NTMgMTIyLjc1IDY0IDEyMi43NXoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPgo8L3N2Zz4K
  38. // @iconbackup https://ssl.gstatic.com/ui/v1/icons/mail/rfr/gmail.ico
  39. // @license MIT
  40. // @grant GM_getValue
  41. // @grant GM_setValue
  42. // ==/UserScript==
  43.  
  44. (function() {
  45. 'use strict';
  46.  
  47. // Retrieve a stored value for demonstration (not essential for minimizing logic)
  48. const testStoredSendTo = GM_getValue('whatever', '');
  49. console.log("testStoredSendTo", testStoredSendTo);
  50.  
  51. // Create a container for the floating box
  52. const container = document.createElement('div');
  53. container.style.position = 'fixed';
  54. container.style.bottom = '20px';
  55. container.style.left = '20px';
  56. container.style.zIndex = '9999';
  57. container.style.padding = '10px';
  58. container.style.backgroundColor = '#fff';
  59. container.style.border = '1px solid #ccc';
  60. container.style.borderRadius = '5px';
  61. container.style.boxShadow = '0 0 5px rgba(0,0,0,0.3)';
  62. container.style.fontFamily = 'Arial, sans-serif';
  63. container.style.maxWidth = '280px';
  64.  
  65. // Title or heading
  66. const heading = document.createElement('h4');
  67. heading.textContent = 'Email Converter';
  68. heading.style.margin = '0 0 10px 0';
  69. container.appendChild(heading);
  70.  
  71. // Close (minimize) button
  72. const minimizeButton = document.createElement('button');
  73. minimizeButton.textContent = 'X';
  74. minimizeButton.style.position = 'absolute';
  75. minimizeButton.style.top = '5px';
  76. minimizeButton.style.right = '10px';
  77. minimizeButton.style.cursor = 'pointer';
  78. minimizeButton.style.border = 'none';
  79. minimizeButton.style.background = 'none';
  80. minimizeButton.style.fontSize = '16px';
  81. container.appendChild(minimizeButton);
  82.  
  83. // This button will appear when the container is minimized
  84. const restoreButton = document.createElement('button');
  85. restoreButton.textContent = 'Email Converter';
  86. restoreButton.style.position = 'fixed';
  87. restoreButton.style.left = '0';
  88. restoreButton.style.bottom = '20px';
  89. restoreButton.style.zIndex = '9999';
  90. restoreButton.style.padding = '6px 12px';
  91. restoreButton.style.cursor = 'pointer';
  92. restoreButton.style.border = '1px solid #ccc';
  93. restoreButton.style.borderRadius = '5px';
  94. restoreButton.style.fontFamily = 'Arial, sans-serif';
  95. restoreButton.style.backgroundColor = '#fff';
  96. restoreButton.style.boxShadow = '0 0 5px rgba(0,0,0,0.3)';
  97. // Initially hidden
  98. // restoreButton.style.display = 'none';
  99. container.style.display = 'none';
  100. restoreButton.style.display = 'block';
  101. document.body.appendChild(restoreButton);
  102.  
  103. // When the user clicks the "X", hide the container and show the restore button
  104. minimizeButton.addEventListener('click', () => {
  105. container.style.display = 'none';
  106. restoreButton.style.display = 'block';
  107. });
  108.  
  109. // When the user clicks restore, show the container and hide the restore button
  110. restoreButton.addEventListener('click', () => {
  111. container.style.display = 'block';
  112. restoreButton.style.display = 'none';
  113. });
  114.  
  115. // Wrapper to neatly organize form elements
  116. const formWrapper = document.createElement('div');
  117. formWrapper.style.display = 'flex';
  118. formWrapper.style.flexDirection = 'column';
  119. formWrapper.style.gap = '5px';
  120.  
  121. // Retrieve stored values (if any)
  122. const storedSendTo = GM_getValue('converterSendTo', '');
  123. const storedDdgo = GM_getValue('converterDdgo', '');
  124.  
  125. // Label and input for "send email to who?"
  126. const labelSendTo = document.createElement('label');
  127. labelSendTo.textContent = 'Send email to who: ';
  128. labelSendTo.style.marginRight = '10px';
  129.  
  130. const inputSendTo = document.createElement('input');
  131. inputSendTo.type = 'text';
  132. inputSendTo.placeholder = 'e.g. 123@qq.com';
  133. inputSendTo.style.width = '250px';
  134. inputSendTo.value = storedSendTo;
  135.  
  136. const rowSendTo = document.createElement('div');
  137. rowSendTo.appendChild(labelSendTo);
  138. rowSendTo.appendChild(inputSendTo);
  139.  
  140. // Label and input for "your ddgo mail?"
  141. const labelDdgo = document.createElement('label');
  142. labelDdgo.textContent = 'Your DuckduckGo address: ';
  143. labelDdgo.style.marginRight = '10px';
  144.  
  145. const inputDdgo = document.createElement('input');
  146. inputDdgo.type = 'text';
  147. inputDdgo.placeholder = 'e.g. dd@duck.com';
  148. inputDdgo.style.width = '250px';
  149. inputDdgo.value = storedDdgo;
  150.  
  151. const rowDdgo = document.createElement('div');
  152. rowDdgo.appendChild(labelDdgo);
  153. rowDdgo.appendChild(inputDdgo);
  154.  
  155. // Convert button
  156. const buttonConvert = document.createElement('button');
  157. buttonConvert.textContent = 'Convert';
  158. buttonConvert.style.marginRight = '10px';
  159. buttonConvert.style.cursor = 'pointer';
  160. buttonConvert.style.width = '250px';
  161.  
  162. // Output field for converted email
  163. const labelOutput = document.createElement('label');
  164. labelOutput.textContent = 'Converted: ';
  165. labelOutput.style.marginRight = '10px';
  166.  
  167. const outputEmail = document.createElement('input');
  168. outputEmail.type = 'text';
  169. outputEmail.readOnly = true;
  170. outputEmail.style.width = '250px';
  171.  
  172. const rowOutput = document.createElement('div');
  173. rowOutput.appendChild(labelOutput);
  174. rowOutput.appendChild(outputEmail);
  175.  
  176. // Feedback or error message area
  177. const feedback = document.createElement('p');
  178. feedback.style.color = 'red';
  179. feedback.style.fontSize = '14px';
  180. feedback.style.margin = '5px 0 0 0';
  181. feedback.style.minHeight = '18px';
  182. feedback.textContent = '';
  183.  
  184. // Conversion function
  185. buttonConvert.addEventListener('click', () => {
  186. const originalEmail = inputSendTo.value.trim();
  187. const ddgoEmail = inputDdgo.value.trim();
  188. let errorMessage = '';
  189.  
  190. // Simple validations
  191. if (!originalEmail) {
  192. errorMessage = 'Please enter an email address to convert.';
  193. } else if (!ddgoEmail) {
  194. errorMessage = 'Please enter your DDG address.';
  195. }
  196.  
  197. // Handle any errors
  198. if (errorMessage) {
  199. feedback.textContent = errorMessage;
  200. outputEmail.value = '';
  201. return;
  202. }
  203.  
  204. // Replace '@' with '_at_' and append the ddgo email
  205. const converted = originalEmail.replace(/@/g, '_at_') + '_' + ddgoEmail;
  206. outputEmail.value = converted;
  207. feedback.textContent = '';
  208.  
  209. // Save inputs to Tampermonkey storage
  210. GM_setValue('converterSendTo', originalEmail);
  211. GM_setValue('converterDdgo', ddgoEmail);
  212. });
  213.  
  214. // Assemble elements in the container
  215. formWrapper.appendChild(rowSendTo);
  216. formWrapper.appendChild(rowDdgo);
  217. formWrapper.appendChild(buttonConvert);
  218. formWrapper.appendChild(rowOutput);
  219. formWrapper.appendChild(feedback);
  220.  
  221. container.appendChild(formWrapper);
  222.  
  223. // Finally, attach the container to document body
  224. document.body.appendChild(container);
  225. })();