├── README.md ├── DiscordKeepURL.js ├── .github └── workflows │ └── stale.yml └── DiscordEmbed.js /README.md: -------------------------------------------------------------------------------- 1 | ## Using Cloudflare Workers for Discord embed support 2 | 3 | Requirements: Your own image host, on a domain that you control via [Cloudflare](https://www.cloudflare.com). 4 | 5 | Limitations: 100,000 requests per day (where the embed works). 6 | 7 | 1. Create a Cloudflare Worker: https://dash.cloudflare.com/sign-up/workers 8 | 2. Replace the script inside the worker with your desired script from this repo ([DiscordEmbed.js](DiscordEmbed.js) in this case). 9 | 3. Press "Save and Deploy". 10 | 4. Return to your dashboard, press "Workers", and then press "Add route". 11 | 5. Set the route to be where your images are hosted, for example: `i.example.com/*`. 12 | 6. Make sure to click "Request limit failure mode" and change it to "Fail open". This will allow your images to show, even if you exceed 100,000 requests. 13 | 7. Save & try it out. 14 | -------------------------------------------------------------------------------- /DiscordKeepURL.js: -------------------------------------------------------------------------------- 1 | async function handleRequest(request) { 2 | const userAgent = request.headers.get("user-agent"); 3 | if (userAgent && userAgent.includes("Discord")) { 4 | const response = await fetch(request); 5 | if (response.status == 200) { 6 | const contentType = response.headers.get("content-type"); 7 | if (contentType && contentType.startsWith("image/")) { 8 | return new Response(` 9 | 10 | 11 | 12 | 13 | `, { 14 | headers: { 15 | "content-type": "text/html" 16 | } 17 | }); 18 | } 19 | } 20 | return response; 21 | } 22 | return fetch(request); 23 | } 24 | 25 | addEventListener("fetch", event => { 26 | event.respondWith(handleRequest(event.request)); 27 | }); -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: 'Close stale issues and PRs' 2 | on: 3 | schedule: 4 | - cron: '30 1 * * *' 5 | 6 | jobs: 7 | stale: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/stale@v3 11 | with: 12 | repo-token: ${{ secrets.GITHUB_TOKEN }} 13 | stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.' 14 | stale-pr-message: 'This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.' 15 | days-before-issue-stale: 180 16 | days-before-pr-stale: 60 17 | days-before-issue-close: 7 18 | days-before-pr-close: 7 19 | stale-issue-label: 'Stale' 20 | stale-pr-label: 'Stale' 21 | exempt-issue-labels: 'Bug,Enhancement' 22 | exempt-pr-labels: '' 23 | operations-per-run: 100 -------------------------------------------------------------------------------- /DiscordEmbed.js: -------------------------------------------------------------------------------- 1 | async function handleRequest(request) { 2 | const userAgent = request.headers.get("user-agent"); 3 | if (userAgent && userAgent.includes("Discord")) { 4 | const response = await fetch(request); 5 | if (response.status == 200) { 6 | const contentType = response.headers.get("content-type"); 7 | if (contentType && contentType.startsWith("image/")) { 8 | const url = new URL(request.url); 9 | const filename = decodeURIComponent(url.pathname.slice(url.pathname.lastIndexOf("/") + 1)); 10 | const title = "ShareX"; 11 | const description = filename; 12 | const color = "#00aff4"; 13 | return new Response(` 14 | 15 | ${title} 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | `, { 28 | headers: { 29 | "content-type": "text/html; charset=UTF-8" 30 | } 31 | }); 32 | } 33 | } 34 | return response; 35 | } 36 | return fetch(request); 37 | } 38 | 39 | addEventListener("fetch", event => { 40 | event.respondWith(handleRequest(event.request)); 41 | }); 42 | --------------------------------------------------------------------------------