├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE ├── README.md ├── discord_self_embed ├── __init__.py └── utils │ ├── __init__.py │ ├── embed.py │ └── shortener.py ├── examples ├── embed_cmd.py └── shorten_url.py └── setup.py /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [ghostselfbot] 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.egg-info 2 | *.egg 3 | dist/* 4 | build/* 5 | test.py 6 | discord_self_embed/utils/__pycache__/* 7 | */__pycache__/* -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Ben Tettmar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # discord.py-self_embed 2 | A way for selfbots to send embeds again. 3 | It uses [Benny's Embed Generator](https://benny.fun/embed). 4 | 5 | 6 | ### Install 7 | > ```bash 8 | > $ pip install 'discord.py-self_embed @ git+https://github.com/ghostselfbot/discord.py-self_embed' 9 | > ``` 10 | 11 | ### Example 12 | > ```python 13 | > import discord_self_embed 14 | > 15 | > embed = discord_self_embed.Embed("discord.py-self_embed", 16 | > description="A way for selfbots to send embeds again.", 17 | > colour="FFBB00" 18 | > ) 19 | > embed.set_author("Benny") 20 | > embed.set_image("https://raw.githubusercontent.com/ghostselfbot/ghost/refs/heads/main/ghost.png", big=False) 21 | > 22 | > url = embed.generate_url(hide_url=True) # You can also convert the embed to a string. 23 | > print(url) # The url will be put in your ctx.send() content. 24 | > ``` 25 | 26 | ### Limitations 27 | > Because the embeds are web embeds there are limitations. 28 | > - No footers. 29 | > - Max 350 character description. 30 | -------------------------------------------------------------------------------- /discord_self_embed/__init__.py: -------------------------------------------------------------------------------- 1 | from .utils import Embed -------------------------------------------------------------------------------- /discord_self_embed/utils/__init__.py: -------------------------------------------------------------------------------- 1 | from .embed import * 2 | from .shortener import * -------------------------------------------------------------------------------- /discord_self_embed/utils/embed.py: -------------------------------------------------------------------------------- 1 | import urllib.parse 2 | 3 | class Embed: 4 | def __init__(self, title, **kwargs) -> None: 5 | """ 6 | Initialize the embed object. 7 | 8 | Parameters: 9 | title (str): The title of the embed. 10 | description (str): The description of the embed. (Max 340 characters) 11 | colour (str): The hex colour of the embed. 12 | url (str): The url of the embed. 13 | """ 14 | 15 | description = kwargs.get("description", "") 16 | colour = kwargs.get("colour", "") or kwargs.get("color", "") or "000000" 17 | url = kwargs.get("url", "") 18 | 19 | if isinstance(colour, int): 20 | colour = str(hex(colour)[2:]) 21 | 22 | elif isinstance(colour, str): 23 | if colour.startswith("#"): 24 | colour = colour[1:] 25 | elif colour.startswith("0x"): 26 | colour = colour[2:] 27 | 28 | self.hide_text = "||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||" 29 | self.base_url = "https://benny.fun/api/embed?" 30 | self.params = { 31 | "title": title, 32 | "description": description, 33 | "color": colour, 34 | "url": url 35 | } 36 | 37 | def __str__(self) -> str: 38 | """ 39 | Return the url of the embed. 40 | 41 | Returns: 42 | str: The url of the embed. 43 | """ 44 | 45 | return self.generate_url(hide_url=True) 46 | 47 | def set_title(self, title) -> None: 48 | """ 49 | Set the title of the embed. 50 | 51 | Parameters: 52 | title (str): The title of the embed. 53 | """ 54 | 55 | self.params["title"] = title 56 | 57 | def set_description(self, description) -> None: 58 | """ 59 | Set the description of the embed. 60 | 61 | Parameters: 62 | description (str): The description of the embed. (Max 340 characters) 63 | """ 64 | 65 | self.params["description"] = description 66 | 67 | def set_colour(self, colour) -> None: 68 | """ 69 | Set the colour of the embed. 70 | 71 | Parameters: 72 | colour (str): The hex colour of the embed. 73 | """ 74 | 75 | self.params["colour"] = colour 76 | 77 | def set_author(self, name, *, url="") -> None: 78 | """ 79 | Set the author of the embed. 80 | 81 | Parameters: 82 | name (str): The name of the author. 83 | url (str): The url to redirect to when the author is clicked. 84 | """ 85 | 86 | self.params["author_name"] = name 87 | 88 | if url: 89 | self.params["author_url"] = url 90 | 91 | def set_provider(self, name, *, url="") -> None: 92 | """ 93 | Set the provider of the embed. 94 | 95 | Parameters: 96 | name (str): The name of the provider. 97 | url (str): The url to redirect to when the provider is clicked. 98 | """ 99 | 100 | self.params["provider_name"] = name 101 | 102 | if url: 103 | self.params["provider_url"] = url 104 | 105 | def set_image(self, url, big=False) -> None: 106 | """ 107 | Set the image of the embed. By default you will get a thumbnail in the right corner. For a larger image set big to True. 108 | 109 | Parameters: 110 | url (str): The url of the image. 111 | big (bool): Whether the image should be big. 112 | """ 113 | 114 | self.params["image"] = url 115 | self.params["big_image"] = big 116 | 117 | def set_video(self, url) -> None: 118 | """ 119 | Set the video of the embed. 120 | 121 | Parameters: 122 | url (str): The url of the video. 123 | """ 124 | 125 | self.params["video"] = url 126 | 127 | def generate_url(self, *, hide_url=False, shorten_url=False, shortener=None) -> str: 128 | """ 129 | Generate the url of the embed. 130 | 131 | Returns: 132 | str: The url of the embed. 133 | """ 134 | 135 | for key in list(self.params.keys()): 136 | if self.params[key] == "" or self.params[key] is None: 137 | del self.params[key] 138 | 139 | url = self.base_url + urllib.parse.urlencode(self.params) 140 | 141 | if shorten_url: 142 | url = shortener.shorten(url) 143 | 144 | if hide_url: 145 | return self.hide_text + " " + url 146 | else: 147 | return url 148 | 149 | set_color = set_colour 150 | -------------------------------------------------------------------------------- /discord_self_embed/utils/shortener.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import bs4 3 | import sys 4 | 5 | # TODO: find a shortener that doesnt have cloudflare block and free api 6 | 7 | class Shortener: 8 | def __init__(self, bitly_token): 9 | self.api_url = "https://api-ssl.bitly.com" 10 | self.bitly_token = bitly_token 11 | 12 | def shorten(self, url): 13 | data = {"long_url": url} 14 | headers = { 15 | "Authorization": f"Bearer {self.bitly_token}", 16 | "Content-Type": "application/json", 17 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36" 18 | } 19 | 20 | response = requests.post(self.api_url + "/v4/shorten", json=data, headers=headers) 21 | response.raise_for_status() 22 | 23 | return response.json()["link"] -------------------------------------------------------------------------------- /examples/embed_cmd.py: -------------------------------------------------------------------------------- 1 | import discord_self_embed 2 | from discord.ext import commands 3 | 4 | bot = commands.Bot(command_prefix=".", self_bot=True) 5 | 6 | @bot.event 7 | async def on_ready(): 8 | print("ready") 9 | 10 | @bot.command(name="embed") 11 | async def embed_cmd(ctx): 12 | embed = discord_self_embed.Embed("discord.py-self_embed", description="A way for selfbots to send embeds again.", colour="ff0000", url="https://github.com/bentettmar/discord.py-self_embed") 13 | embed.set_author("Benny") 14 | 15 | await ctx.send(embed.generate_url(hide_url=True)) # You can also send the embed converted to a string which will auto hide the url. 16 | 17 | bot.run("TOKEN_HERE") 18 | -------------------------------------------------------------------------------- /examples/shorten_url.py: -------------------------------------------------------------------------------- 1 | import discord_self_embed 2 | 3 | shortener = discord_self_embed.utils.Shortener("YOUR_BITLY_API_TOKEN") 4 | 5 | embed = discord_self_embed.Embed("discord.py-self_embed", description="A way for selfbots to send embeds again.", colour="ff0000", url="https://github.com/bentettmar/discord.py-self_embed") 6 | embed.set_author("Benny") 7 | 8 | url = embed.generate_url(shorten_url=True, shortener=shortener) 9 | print(url) -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | 3 | readme = """ 4 | # discord.py-self_embed 5 | A way for selfbots to send embeds again. 6 | It uses [Benny's embed generator](https://benny.fun/api/embed). 7 | 8 | ### Install 9 | > ```bash 10 | > $ pip install discord.py-self-embed 11 | > ``` 12 | 13 | ### Example 14 | > ```python 15 | > import discord_self_embed 16 | > 17 | > embed = discord_self_embed.Embed("discord.py-self_embed", 18 | > description="A way for selfbots to send embeds again.", 19 | > colour="FFBB00" 20 | > ) 21 | > embed.set_author("Benny") 22 | > embed.set_image("https://raw.githubusercontent.com/bennyscripts/ghost/refs/heads/main/ghost.png", big=False) 23 | > 24 | > url = embed.generate_url(hide_url=True) # You can also convert the embed to a string. 25 | > print(url) # The url will be put in your ctx.send() content. 26 | > ``` 27 | 28 | ### Limitations 29 | > Because the embeds are web embeds there are limitations. 30 | > - No footers. 31 | > - Max 350 character description. 32 | 33 | """ 34 | 35 | setup( 36 | name='discord.py-self_embed', 37 | packages=['discord_self_embed', 'discord_self_embed.utils'], 38 | version='1.0.9', 39 | license='MIT', 40 | description='A way for selfbots to send embeds again.', 41 | author='Ben Tettmar', 42 | author_email='hello@benny.fun', 43 | url='https://github.com/bentettmar/discord.py-self_embed', 44 | download_url='https://github.com/bennyscripts/discord.py-self_embed/archive/refs/tags/1.0.9.tar.gz', 45 | keywords=['discord', 'embed', 'selfbot', "discord embed", 46 | "embed discord", "discord selfbot embed", "embed selfbot discord"], 47 | install_requires=[], 48 | classifiers=[ 49 | 'Development Status :: 5 - Production/Stable', 50 | 'Intended Audience :: Developers', 51 | 'License :: OSI Approved :: MIT License', 52 | 'Programming Language :: Python :: 3.6', 53 | 'Programming Language :: Python :: 3.7', 54 | 'Programming Language :: Python :: 3.8', 55 | 'Programming Language :: Python :: 3.9', 56 | 'Programming Language :: Python :: 3.10', 57 | ], 58 | long_description=readme, 59 | long_description_content_type='text/markdown' 60 | ) 61 | --------------------------------------------------------------------------------