├── .github └── workflows │ └── staging.yml ├── .gitignore ├── LICENSE ├── PRIVACY.md ├── README.md ├── TERMS.md ├── gradio-discord.jpg ├── main.py ├── requirements.txt └── utils.py /.github/workflows/staging.yml: -------------------------------------------------------------------------------- 1 | name: Launch Staging Bot 2 | 3 | on: 4 | workflow_dispatch: 5 | pull_request_target: 6 | types: [opened, synchronize, reopened] 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Cancel Previous Runs 13 | uses: styfle/cancel-workflow-action@0.9.1 14 | - uses: actions/checkout@v2 15 | - name: Set up Python 16 | uses: actions/setup-python@v2 17 | with: 18 | python-version: 3.8 19 | - name: Install dependencies 20 | run: | 21 | python -m pip install -r requirements.txt 22 | - name: Launch Discord server script 23 | run: | 24 | nohup python main.py --token=${{ secrets.staging_token }} < /dev/null & > /dev/null & 25 | - name: Comment PR 26 | uses: thollander/actions-comment-pull-request@v2 27 | with: 28 | message: | 29 | Test this PR here (will be active for 1 hour): https://discord.com/channels/879548962464493619/1057682935832129626 30 | - name: Keepalive 31 | run: | 32 | python -c "import time; time.sleep(60*60)" 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | secrets.json 2 | *.json 3 | *.pkl 4 | 5 | # Byte-compiled / optimized / DLL files 6 | __pycache__/ 7 | *.py[cod] 8 | *$py.class 9 | 10 | # C extensions 11 | *.so 12 | 13 | # Distribution / packaging 14 | .Python 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | .eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | wheels/ 27 | pip-wheel-metadata/ 28 | share/python-wheels/ 29 | *.egg-info/ 30 | .installed.cfg 31 | *.egg 32 | MANIFEST 33 | 34 | # PyInstaller 35 | # Usually these files are written by a python script from a template 36 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 37 | *.manifest 38 | *.spec 39 | 40 | # Installer logs 41 | pip-log.txt 42 | pip-delete-this-directory.txt 43 | 44 | # Unit test / coverage reports 45 | htmlcov/ 46 | .tox/ 47 | .nox/ 48 | .coverage 49 | .coverage.* 50 | .cache 51 | nosetests.xml 52 | coverage.xml 53 | *.cover 54 | *.py,cover 55 | .hypothesis/ 56 | .pytest_cache/ 57 | 58 | # Translations 59 | *.mo 60 | *.pot 61 | 62 | # Django stuff: 63 | *.log 64 | local_settings.py 65 | db.sqlite3 66 | db.sqlite3-journal 67 | 68 | # Flask stuff: 69 | instance/ 70 | .webassets-cache 71 | 72 | # Scrapy stuff: 73 | .scrapy 74 | 75 | # Sphinx documentation 76 | docs/_build/ 77 | 78 | # PyBuilder 79 | target/ 80 | 81 | # Jupyter Notebook 82 | .ipynb_checkpoints 83 | 84 | # IPython 85 | profile_default/ 86 | ipython_config.py 87 | 88 | # pyenv 89 | .python-version 90 | 91 | # pipenv 92 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 93 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 94 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 95 | # install all needed dependencies. 96 | #Pipfile.lock 97 | 98 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 99 | __pypackages__/ 100 | 101 | # Celery stuff 102 | celerybeat-schedule 103 | celerybeat.pid 104 | 105 | # SageMath parsed files 106 | *.sage.py 107 | 108 | # Environments 109 | .env 110 | .venv 111 | env/ 112 | venv/ 113 | ENV/ 114 | env.bak/ 115 | venv.bak/ 116 | 117 | # Spyder project settings 118 | .spyderproject 119 | .spyproject 120 | 121 | # Rope project settings 122 | .ropeproject 123 | 124 | # mkdocs documentation 125 | /site 126 | 127 | # mypy 128 | .mypy_cache/ 129 | .dmypy.json 130 | dmypy.json 131 | 132 | # Pyre type checker 133 | .pyre/ 134 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Gradio 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 | -------------------------------------------------------------------------------- /PRIVACY.md: -------------------------------------------------------------------------------- 1 | Privacy Policy 2 | ============== 3 | 4 | The use of this application ("Bot") in a server requires the collection of some specific user data ("Data"). The Data collected includes, but is not limited to Discord guild ID values and messages sent to the Discord Bot. Use of the Bot is considered an agreement to the terms of this Policy. 5 | 6 | Access to Data 7 | --------------------------------------------------------------------------------------------------------------- 8 | 9 | Access to Data is only permitted to Bot's developers, and only in the scope required for the development, testing, and implementation of features for Bot. Data is not sold, provided to, or shared with any third party, except where required by law or a Terms of Service agreement. 10 | 11 | Storage of Data 12 | ----------------------------------------------------------------------------------------------------------------- 13 | 14 | Data may be stored in a database. The database will be secured to prevent external access, however no guarantee is provided and the Bot owners assume no liability for the unintentional or malicious breach of Data. In the event of an unauthorised Data access, users will be notified through the Discord client application. Users can email team@gradio.app to request deletion of their data. 15 | 16 | 17 | Underage Users 18 | --------------------------------------------------------------------------------------------------------------- 19 | 20 | The use of the Bot is not permitted for minors under the age of 13, or under the age of legal consent for their country. This is in compliance with the [Discord Terms of Service](https://discord.com/terms). No information will be knowingly stored from an underage user. If it is found out that a user is underage we will take all necessary action to delete the stored data. 21 | 22 | Questions 23 | ----------------------------------------------------------------------------------------------------- 24 | 25 | If you have any questions or are concerned about what data might be being stored from your account contact team@gradio.app. For more information check the [Discord Terms Of Service](https://discord.com/terms). 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | # The Gradio Discord BotBETA 6 | 7 | The Gradio Discord Bot is a way to use any [Hugging Face Space](https://hf.space) as a Bot from within your Discord server -- *all without writing any code*. 8 | 9 | Below, we show examples how to use the Bot in your server to: 10 | 11 | - 🌎 Translate between languages 12 | - 🗣️ Convert text to speech 13 | - 🔢 Do math calculations 14 | - 🖼️ Generate images 15 | 16 | All for free and without having to code anything! Installation instructions are below, or you can try it out right now in the [#gradio-bot-playground channel](https://discord.gg/Q7ZSBrZHjx) in the Hugging Face Discord. 17 | 18 | ## Installing in your own Discord Server 19 | 20 | Installing the Gradio Discord Bot is very simple: 21 | 22 | 1. Copy and paste the following link in your browser: https://discord.com/api/oauth2/authorize?client_id=1040198143695933501&permissions=294406716480&scope=bot 23 | 24 | 2. Choose which Discord server you'd like to add it to (you must have permissions to add Bots to that server of course) 25 | 26 |

27 | image 28 |

29 | 30 | 3. Accept the permissions for the Gradio Bot 31 | 32 |

33 | image 34 |

35 | 36 | * You can confirm that the Gradio Discord Bot has been successfully installed in your server by going to the server and seeing if there is an account with the name `@GradioBot` in your server: 37 | 38 |

39 | image 40 |

41 | 42 | 4. (Optional) If you would like to use `@GradioBot` in a private channel, then you must add `@GradioBot` to that channel. In Discord, you can do this by right-clicking on the channel name, and then selecting ‘Edit Channel’. Then, go to ‘Permissions’ and select ‘Add a Role’ and find `@GradioBot` 43 | 44 | 45 | ## Usage 46 | 47 | Now that the Gradio Discord bot is installed, here's how to use it in any any channel in your Discord server: 48 | 49 | 1. From the channel, tag `@GradioBot` followed by the name of a Space you'd like to try, 50 | such as `abidlabs/en2fr` ([a Space](https://huggingface.co/spaces/abidlabs/en2fr) that translates from English to French) or `abidlabs/speak` ([a Space](https://huggingface.co/spaces/abidlabs/speak) that converts text to spoken speech), or any of the more than 5,000 Gradio demos on [Hugging Face Spaces](https://hf.space). 51 | 52 |

53 | image 54 |

55 | 56 | 2. Once you press enter, you'll notice that the name of `@GradioBot` will change to reflect the name of the Space that it has loaded: 57 | 58 |

59 | image 60 |

61 | 62 | 3. Now type in the input you'd like to pass into the Space. In this example, we'll pass in an English phrase: "Hello, friends." The input **must be enclosed in double-quotes**. Otherwise, it will be interpreted as the name of a new Space that you are trying to load. Once you 63 | 64 |

65 | image 66 |

67 | 68 | 4. If you'd like to load a new Space, just type in the name of a new Space (without any quotation marks) and `@GradioBot` will load the new Space instead. If you'd like to reset to the initial state of the `@GradioBot`, you can type in `@GradioBot exit`. 69 | 70 | We'll show how to use `@GradioBot` with a few more complex Spaces below: 71 | 72 | ## More examples 73 | 74 | ### 🗣️ Convert text to speech (`abidlabs/speak`) 75 | 76 | The `@GradioBot` can handle media as well as text. For example, [this Space](https://huggingface.co/spaces/abidlabs/speak) converts text to speech recordings. Here's how to use it: 77 | 78 | 1. In a channel, type `@GradioBot abidlabs/speak` 79 | 80 | 2. Then, type in some text *in quotation marks* that you'd like to convert to speech, such as `@GradioBot "Look at this cool demo!"`. You should see an audio file returned by `@GradioBot`: 81 | 82 |

83 | image 84 |

85 | 86 | 87 | *Note*: generation can take a minute or even longer, depending on the length of the input and how many other people are using this Space 88 | 89 | ### 🔢 Do math calculations (`abidlabs/calc`) 90 | 91 | The `@GradioBot` can handle Spaces that take multiple inputs. Each input **must be in quotes and separated by a space**. For example, [this Space](https://huggingface.co/spaces/abidlabs/calc) takes in two numbers and a mathematical operation. Here's how to use it: 92 | 93 | 1. In a channel, type `@GradioBot abidlabs/calc` 94 | 95 | 2. Then, type in `@GradioBot `, followed by the inputs, separated by Spaces. For example: `@GradioBot "4" "divide" "3"` Here's how it looks: 96 | 97 |

98 | image 99 |

100 | 101 | 102 | ### 🖼️ Generate images (`abidlabs/images`) 103 | 104 | Here's another example that shows that `@GradioBot` can handle media. Using [this Space](https://huggingface.co/spaces/abidlabs/speak) converts text to images. Here's how to use it: 105 | 106 | 1. In a channel, type `@GradioBot abidlabs/images` 107 | 108 | 2. Then, type in some text *in quotation marks* that you'd like to convert into an image, such as `@GradioBot "a cartoon astronaut riding a horse"`. You should see an image file returned by `@GradioBot`: 109 | 110 |

111 | image 112 |

113 | 114 | 115 | *Note*: generation can take a minute or even longer, depending on how many other people are using this Space 116 | 117 | ## About 118 | 119 | The first version of the Gradio Discord Bot was built by the [Gradio team](https://www.gradio.dev) at a hackathon in Paris in Nov. 2022. We hope you enjoy it and find it useful! 120 | 121 | ## Contributing 122 | 123 | The Gradio Discord Bot is completely open-source. Feel free to open issues or pull requests in this repo to make it better! 124 | 125 | -------------------------------------------------------------------------------- /TERMS.md: -------------------------------------------------------------------------------- 1 | Agreement to Terms 2 | ------------------ 3 | 4 | These Terms of Use constitute a legally binding agreement made between you, whether personally or on behalf of an entity ("you") and the Gradio Discord Bot ("Gradio Bot", "we", "us", or "our"), concerning your access to and use of the Gradio Discord Bot as well as any other media form, website, media channel, mobile website or mobile application related, linked, or otherwise connected thereto (collectively, the "Bot"). You agree that by accessing the Bot, you have read, understood, and agree to be bound by all of these Terms of Use. IF YOU DO NOT AGREE WITH ALL OF THESE TERMS OF USE, THEN YOU ARE EXPRESSLY PROHIBITED FROM USING THE BOT AND YOU MUST DISCONTINUE USE IMMEDIATELY. 5 | 6 | Supplemental terms and conditions or documents that may be posted on the website from time to time are hereby expressly incorporated herein by reference. We reserve the right, in our sole discretion, to make changes or modifications to these Terms of Use from time to time. You waive any right to receive specific notice of each such change. Please ensure that you check the applicable Terms every time you use our Bot so that you understand which Terms apply. You will be subject to, and will be deemed to have been made aware of and to have accepted, the changes in any revised Terms of Use by your continued use of the Bot after the date such revised Terms of Use are posted. 7 | 8 | The information provided on the Bot is not intended for distribution to or use by any person or entity in any jurisdiction or country where such distribution or use would be contrary to law or regulation or which would subject us to any registration requirement within such jurisdiction or country. Accordingly, those persons who choose to access the Bot from other locations do so on their own initiative and are solely responsible for compliance with local laws, if and to the extent local laws are applicable. 9 | 10 | The Bot is not tailored to comply with industry-specific regulations (Health Insurance Portability and Accountability Act (HIPAA), Federal Information Security Management Act (FISMA), etc.), so if your interactions would be subjected to such laws, you may not use this Bot. You may not use the Bot in a way that would violate the Gramm-Leach-Bliley Act (GLBA). 11 | 12 | The Bot is intended for users who are at least 13 years of age. All users who are minors in the jurisdiction in which they reside (generally under the age of 18) must have the permission of, and be directly supervised by, their parent or guardian to use the Bot. If you are a minor, you must have your parent or guardian read and agree to these Terms of Use prior to you using the Bot. 13 | 14 | Intellectual Property Rights 15 | ---------------------------- 16 | 17 | Please see the license at: [gradio-discord-bot/LICENSE at main - gradio-app/gradio-discord-bot (github.com)](https://github.com/gradio-app/gradio-discord-bot/blob/main/LICENSE) 18 | 19 | User Representations 20 | -------------------- 21 | 22 | By using the Bot, you represent and warrant that: (1) you have the legal capacity and you agree to comply with these Terms of Use; (2) you are not under the age of 13; (3) you are not a minor in the jurisdiction in which you reside, or if a minor, you have received parental permission to use the Bot; (4) you will not access the Discord Bot through automated or non-human means, whether through a bot, script or otherwise; (5) you will not use the Bot for any illegal or unauthorized purpose; and (6) your use of the Bot will not violate any applicable law or regulation. 23 | 24 | If you provide any information that is untrue, inaccurate, not current, or incomplete, we have the right to suspend or terminate your account and refuse any and all current or future use of the Bot (or any portion thereof). 25 | 26 | 27 | Prohibited Activities 28 | --------------------- 29 | 30 | You may not access or use the Bot for any purpose other than that for which we make the Bot available. As a user of the Bot, you agree not to: 31 | 32 | - Systematically retrieve data or other content from the Bot to create or compile, directly or indirectly, a collection, compilation, database, or directory without written permission from us. 33 | - Trick, defraud, or mislead us and other users, especially in any attempt to learn sensitive account information such as user passwords. 34 | - Circumvent, disable, or otherwise interfere with security-related features of the Bot, including features that prevent or restrict the use or copying of any Content or enforce limitations on the use of the Bot and/or the Content contained therein. 35 | - Disparage, tarnish, or otherwise harm, in our opinion, us and/or the Bot 36 | - Use any information obtained from the Bot in order to harass, abuse, or harm another person. 37 | - Make improper use of our support services or submit false reports of abuse or misconduct. 38 | - Use the Bot in a manner inconsistent with any applicable laws or regulations. 39 | - Engage in unauthorized framing of or linking to the website. 40 | - Upload or transmit (or attempt to upload or to transmit) viruses, Trojan horses, or other material, including excessive use of capital letters and spamming (continuous posting of repetitive text), that interferes with any party's uninterrupted use and enjoyment of the Bot or modifies, impairs, disrupts, alters, or interferes with the use, features, functions, operation, or maintenance of the Bot. 41 | - Engage in any automated use of the system, such as using scripts to send comments or messages, or using any data mining, robots, or similar data gathering and extraction tools. 42 | - Delete the copyright or other proprietary rights notice from any Content. 43 | - Attempt to impersonate another user or person or use the username of another user. 44 | - Upload or transmit (or attempt to upload or to transmit) any material that acts as a passive or active information collection or transmission mechanism, including without limitation, clear graphics interchange formats ("gifs"), 1×1 pixels, web bugs, cookies, or other similar devices (sometimes referred to as "spyware" or "passive collection mechanisms" or "pcms"). 45 | - Interfere with, disrupt, or create an undue burden on the Bot or the networks or services connected to the Bot. 46 | - Harass, annoy, intimidate, or threaten any of our employees or agents engaged in providing any portion of the Bot to you. 47 | - Attempt to bypass any measures of the Bot designed to prevent or restrict access to the Bot, or any portion of the Bot. 48 | - Copy or adapt the Bot's software, including but not limited to Flash, PHP, HTML, JavaScript, or other code. 49 | - Except as permitted by applicable law, decipher, decompile, disassemble, or reverse engineer any of the software comprising or in any way making up a part of the Bot. 50 | - Except as may be the result of standard search engine or Internet browser usage, use, launch, develop, or distribute any automated system, including without limitation, any spider, robot, cheat utility, scraper, or offline reader that accesses the website, or using or launching any unauthorized script or other software. 51 | - Use a buying agent or purchasing agent to make purchases on the website. 52 | - Make any unauthorized use of the Bot, including collecting usernames and/or email addresses of users by electronic or other means for the purpose of sending unsolicited email, or creating user accounts by automated means or under false pretenses. 53 | - Use the Bot as part of any effort to compete with us or otherwise use the Bot and/or the Content for any revenue-generating endeavor or commercial enterprise. 54 | - Exchange virtual currency for real value in any way. 55 | - Initiate illegitimate chargebacks. 56 | - Use any type of unauthorized automation within Discord. 57 | - Use the bot for unauthorized advertisements. 58 | 59 | Contribution License 60 | -------------------- 61 | 62 | You and the Bot agree that we may access, store, process, and use any information and personal data that you provide following the terms of the Privacy Policy and your choices (including settings). 63 | 64 | By submitting suggestions or other feedback regarding the Bot, you agree that we can use and share such feedback for any purpose without compensation to you. 65 | 66 | We do not assert any ownership over your Contributions. You retain full ownership of all of your Contributions and any intellectual property rights or other proprietary rights associated with your Contributions. We are not liable for any statements or representations in your Contributions provided by you in any area on the Bot. You are solely responsible for your Contributions to the Bot and you expressly agree to exonerate us from any and all responsibility and to refrain from any legal action against us regarding your Contributions. 67 | 68 | Submissions 69 | ----------- 70 | 71 | You acknowledge and agree that any questions, comments, suggestions, ideas, feedback, or other information regarding the Bot ("Submissions") provided by you to us are non-confidential and shall be governed by the license: [gradio-discord-bot/LICENSE at main - gradio-app/gradio-discord-bot (github.com)](https://github.com/gradio-app/gradio-discord-bot/blob/main/LICENSE) 72 | 73 | Third-Party Websites and Content 74 | -------------------------------- 75 | 76 | The Bot may contain (or you may be sent via the Bot) links to other websites ("Third-Party Websites") as well as articles, photographs, text, graphics, pictures, designs, music, sound, video, information, applications, software, and other content or items belonging to or originating from third parties ("Third-Party Content"). Such Third-Party Websites and Third-Party Content are not investigated, monitored, or checked for accuracy, appropriateness, or completeness by us, and we are not responsible for any Third-Party Websites accessed through the Bot or any Third-Party Content posted on, available through, or installed from the Bot, including the content, accuracy, offensiveness, opinions, reliability, privacy practices, or other policies of or contained in the Third-Party Websites or the Third-Party Content. Inclusion of, linking to, or permitting the use or installation of any Third-Party Websites or any Third-Party Content does not imply approval or endorsement thereof by us. If you decide to leave the Bot and access the Third-Party Websites or to use or install any Third-Party Content, you do so at your own risk, and you should be aware these Terms of Use no longer govern. You should review the applicable terms and policies, including privacy and data gathering practices, of any website to which you navigate from the Bot or relating to any applications you use or install from the Bot. Any purchases you make through Third-Party Websites will be through other websites and from other companies, and we take no responsibility whatsoever in relation to such purchases which are exclusively between you and the applicable third party. You agree and acknowledge that we do not endorse the products or services offered on Third-Party Websites and you shall hold us harmless from any harm caused by your purchase of such products or services. Additionally, you shall hold us harmless from any losses sustained by you or harm caused to you relating to or resulting in any way from any Third-Party Content or any contact with Third-Party Websites. 77 | 78 | Bot Management 79 | -------------- 80 | 81 | We reserve the right, but not the obligation, to: (1) monitor the Bot for violations of these Terms of Use; (2) take appropriate legal action against anyone who, in our sole discretion, violates the law or these Terms of Use, including without limitation, reporting such user to law enforcement authorities; (3) in our sole discretion and without limitation, refuse, restrict access to, limit the availability of, or disable (to the extent technologically feasible) any of your Contributions or any portion thereof; (4) in our sole discretion and without limitation, notice, or liability, to remove from the Bot or otherwise disable all files and content that are excessive in size or are in any way burdensome to our systems; and (5) otherwise manage the Bot in a manner designed to protect our rights and property and to facilitate the proper functioning of the Bot. 82 | 83 | Privacy Policy 84 | -------------- 85 | 86 | We care about data privacy and security. Please review our Privacy Policy: . By using the Bot, you agree to be bound by our Privacy Policy, which is incorporated into these Terms of Use. Please be advised the Bot is hosted in the United States. If you access the Bot from any other region of the world with laws or other requirements governing personal data collection, use, or disclosure that differ from applicable laws in United States, then through your continued use of the Bot, you are transferring your data to United States, and you agree to have your data transferred to and processed in Germany. Further, we do not knowingly accept, request, or solicit information from children or knowingly market to children. Therefore, in accordance with the U.S. Children's Online Privacy Protection Act, if we receive actual knowledge that anyone under the age of 13 has provided personal information to us without the requisite and verifiable parental consent, we will delete that information from the Bot as quickly as is reasonably practical. 87 | 88 | Term and Termination 89 | -------------------- 90 | 91 | These Terms of Use shall remain in full force and effect while you use the Bot. WITHOUT LIMITING ANY OTHER PROVISION OF THESE TERMS OF USE, WE RESERVE THE RIGHT TO, IN OUR SOLE DISCRETION AND WITHOUT NOTICE OR LIABILITY, DENY ACCESS TO AND USE OF THE BOT (INCLUDING BLOCKING CERTAIN IP ADDRESSES), TO ANY PERSON FOR ANY REASON OR FOR NO REASON, INCLUDING WITHOUT LIMITATION FOR BREACH OF ANY REPRESENTATION, WARRANTY, OR COVENANT CONTAINED IN THESE TERMS OF USE OR OF ANY APPLICABLE LAW OR REGULATION. WE MAY TERMINATE YOUR USE OR PARTICIPATION IN THE SITE OR DELETE ANY CONTENT OR INFORMATION THAT YOU POSTED AT ANY TIME, WITHOUT WARNING, IN OUR SOLE DISCRETION. 92 | 93 | If we terminate or suspend your access for any reason, you are prohibited from using a new account under your name, a fake or borrowed name, or the name of any third party, even if you may be acting on behalf of the third party. In addition to terminating or suspending your account, we reserve the right to take appropriate legal action, including without limitation pursuing civil, criminal, and injunctive redress. 94 | 95 | Modifications and Interruptions 96 | ------------------------------- 97 | 98 | We reserve the right to change, modify, or remove the contents of the bot at any time or for any reason at our sole discretion without notice. However, we have no obligation to update any information on our bot. We also reserve the right to modify or discontinue all or part of the bot without notice at any time. We will not be liable to you or any third party for any modification, price change, suspension, or discontinuance of the bot. 99 | 100 | We cannot guarantee the bot will be available at all times. We may experience hardware, software, or other problems or need to perform maintenance related to the bot, resulting in interruptions, delays, or errors. We reserve the right to change, revise, update, suspend, discontinue, or otherwise modify the bot at any time or for any reason without notice to you. You agree that we have no liability whatsoever for any loss, damage, or inconvenience caused by your inability to access or use the bot during any downtime or discontinuance of the bot. Nothing in these Terms of Use will be construed to obligate us to maintain and support the bot or to supply any corrections, updates, or releases in connection therewith. 101 | 102 | Governing Law 103 | ------------- 104 | 105 | These conditions are governed by and interpreted following the laws of United States, and the use of the United Nations Convention of Contracts for the International Sale of Goods is expressly excluded. If your habitual residence is in the EU, and you are a consumer, you additionally possess the protection provided to you by obligatory provisions of the law of your country of residence. Leonard Blechschmidt and yourself both agree to submit to the non-exclusive jurisdiction of the courts of Hesse, which means that you may make a claim to defend your consumer protection rights in regards to these Conditions of Use in Germany, or in the EU country in which you reside. 106 | 107 | Corrections 108 | ----------- 109 | 110 | There may be information on the bot that contains typographical errors, inaccuracies, or omissions, including descriptions, pricing, availability, and various other information. We reserve the right to correct any errors, inaccuracies, or omissions and to change or update the information on the bot at any time, without prior notice. 111 | 112 | Disclaimer 113 | ---------- 114 | 115 | THE BOT IS PROVIDED ON AN AS-IS AND AS-AVAILABLE BASIS. YOU AGREE THAT YOUR USE OF THE SITE AND OUR SERVICES WILL BE AT YOUR SOLE RISK. TO THE FULLEST EXTENT PERMITTED BY LAW, WE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, IN CONNECTION WITH THE BOT AND YOUR USE THEREOF, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. WE MAKE NO WARRANTIES OR REPRESENTATIONS ABOUT THE ACCURACY OR COMPLETENESS OF THE BOT'S CONTENT OR THE CONTENT OF ANY WEBSITES LINKED TO THE BOT AND WE WILL ASSUME NO LIABILITY OR RESPONSIBILITY FOR ANY (1) ERRORS, MISTAKES, OR INACCURACIES OF CONTENT AND MATERIALS, (2) PERSONAL INJURY OR PROPERTY DAMAGE, OF ANY NATURE WHATSOEVER, RESULTING FROM YOUR ACCESS TO AND USE OF THE BOT, (3) ANY UNAUTHORIZED ACCESS TO OR USE OF OUR SECURE SERVERS AND/OR ANY AND ALL PERSONAL INFORMATION AND/OR FINANCIAL INFORMATION STORED THEREIN, (4) ANY INTERRUPTION OR CESSATION OF TRANSMISSION TO OR FROM THE WEBSITE, (5) ANY BUGS, VIRUSES, TROJAN HORSES, OR THE LIKE WHICH MAY BE TRANSMITTED TO OR THROUGH THE BOT BY ANY THIRD PARTY, AND/OR (6) ANY ERRORS OR OMISSIONS IN ANY CONTENT AND MATERIALS OR FOR ANY LOSS OR DAMAGE OF ANY KIND INCURRED AS A RESULT OF THE USE OF ANY CONTENT POSTED, TRANSMITTED, OR OTHERWISE MADE AVAILABLE VIA THE BOT. WE DO NOT WARRANT, ENDORSE, GUARANTEE, OR ASSUME RESPONSIBILITY FOR ANY PRODUCT OR SERVICE ADVERTISED OR OFFERED BY A THIRD PARTY THROUGH THE BOT, ANY HYPERLINKED WEBSITE, OR ANY WEBSITE OR MOBILE APPLICATION FEATURED IN ANY BANNER OR OTHER ADVERTISING, AND WE WILL NOT BE A PARTY TO OR IN ANY WAY BE RESPONSIBLE FOR MONITORING ANY TRANSACTION BETWEEN YOU AND ANY THIRD-PARTY PROVIDERS OF PRODUCTS OR SERVICES. AS WITH THE PURCHASE OF A PRODUCT OR SERVICE THROUGH ANY MEDIUM OR IN ANY ENVIRONMENT, YOU SHOULD USE YOUR BEST JUDGMENT AND EXERCISE CAUTION WHERE APPROPRIATE. 116 | 117 | Limitations of Liability 118 | ------------------------ 119 | 120 | IN NO EVENT WILL WE OR OUR DIRECTORS, EMPLOYEES, OR AGENTS BE LIABLE TO YOU OR ANY THIRD PARTY FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, SPECIAL, OR PUNITIVE DAMAGES, INCLUDING LOST PROFIT, LOST REVENUE, LOSS OF DATA, OR OTHER DAMAGES ARISING FROM YOUR USE OF THE BOT, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. NOTWITHSTANDING ANYTHING TO THE CONTRARY CONTAINED HEREIN, OUR LIABILITY TO YOU FOR ANY CAUSE WHATSOEVER AND REGARDLESS OF THE FORM OF THE ACTION, WILL AT ALL TIMES BE LIMITED TO THE AMOUNT PAID, IF ANY, BY YOU TO US. CERTAIN US STATE LAWS AND INTERNATIONAL LAWS DO NOT ALLOW LIMITATIONS ON IMPLIED WARRANTIES OR THE EXCLUSION OR LIMITATION OF CERTAIN DAMAGES. IF THESE LAWS APPLY TO YOU, SOME OR ALL OF THE ABOVE DISCLAIMERS OR LIMITATIONS MAY NOT APPLY TO YOU, AND YOU MAY HAVE ADDITIONAL RIGHTS. 121 | 122 | Indemnification 123 | --------------- 124 | 125 | You agree to defend, indemnify, and hold us harmless, including our subsidiaries, affiliates, and all of our respective officers, agents, partners, and employees, from and against any loss, damage, liability, claim, or demand, including reasonable attorneys' fees and expenses, made by any third party due to or arising out of: (1) use of the Bot; (2) breach of these Terms of Use; (3) any breach of your representations and warranties set forth in these Terms of Use; (4) your violation of the rights of a third party, including but not limited to intellectual property rights; or (5) any overt harmful act toward any other user of the Bot with whom you connected via the Bot. Notwithstanding the foregoing, we reserve the right, at your expense, to assume the exclusive defense and control of any matter for which you are required to indemnify us, and you agree to cooperate, at your expense, with our defense of such claims. We will use reasonable efforts to notify you of any such claim, action, or proceeding which is subject to this indemnification upon becoming aware of it. 126 | 127 | User Data 128 | --------- 129 | 130 | We will maintain certain data that you transmit to the Bot for the purpose of managing the performance of the Bot, as well as data relating to your use of the Bot. Although we perform regular routine backups of data, you are solely responsible for all data that you transmit or that relates to any activity you have undertaken using the Bot. You agree that we shall have no liability to you for any loss or corruption of any such data, and you hereby waive any right of action against us arising from any such loss or corruption of such data. 131 | 132 | Electric Communications, Transactions and Signatures 133 | ---------------------------------------------------- 134 | 135 | Using the Bot, visiting the website, sending us emails, and completing online forms constitute electronic communications. You consent to receive electronic communications, and you agree that all agreements, notices, disclosures, and other communications we provide to you electronically, via email and on the Bot, satisfy any legal requirement that such communication be in writing. YOU HEREBY AGREE TO THE USE OF ELECTRONIC SIGNATURES, CONTRACTS, ORDERS, AND OTHER RECORDS, AND TO ELECTRONIC DELIVERY OF NOTICES, POLICIES, AND RECORDS OF TRANSACTIONS INITIATED OR COMPLETED BY US OR VIA THE BOT. You hereby waive any rights or requirements under any statutes, regulations, rules, ordinances, or other laws in any jurisdiction which require an original signature or delivery or retention of non-electronic records, or to payments or the granting of credits by any means other than electronic means. 136 | 137 | California Users and Residents 138 | ------------------------------ 139 | 140 | If any complaint with us is not satisfactorily resolved, you can contact the Complaint Assistance Unit of the Division of Consumer Services of the California Department of Consumer Affairs in writing at 1625 North Market Blvd., Suite N 112, Sacramento, California 95834 or by telephone at (800) 952-5210 or (916) 445-1254. 141 | 142 | Miscellaneous 143 | ------------- 144 | 145 | These Terms of Use and any policies or operating rules posted by us on the website or in respect to the Bot constitute the entire agreement and understanding between you and us. Our failure to exercise or enforce any right or provision of these Terms of Use shall not operate as a waiver of such right or provision. These Terms of Use operate to the fullest extent permissible by law. We may assign any or all of our rights and obligations to others at any time. We shall not be responsible or liable for any loss, damage, delay, or failure to act caused by any cause beyond our reasonable control. If any provision or part of a provision of these Terms of Use is determined to be unlawful, void, or unenforceable, that provision or part of the provision is deemed severable from these Terms of Use and does not affect the validity and enforceability of any remaining provisions. There is no joint venture, partnership, employment or agency relationship created between you and us as a result of these Terms of Use or use of the Bot. You agree that these Terms of Use will not be construed against us by virtue of having drafted them. You hereby waive any and all defenses you may have based on the electronic form of these Terms of Use and the lack of signing by the parties hereto to execute these Terms of Use. 146 | 147 | Contact Us 148 | ---------- 149 | 150 | In order to resolve a complaint regarding the Bot or to receive further information regarding use of the Bot, please contact us at: 151 | 152 | Email: team@gradio.app 153 | 154 | These terms of use were created using [Termly's Terms and Conditions Generator](https://termly.io/products/terms-and-conditions-generator). 155 | -------------------------------------------------------------------------------- /gradio-discord.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gradio-app/gradio-discord-bot/0edde4fdd2fa06a2792e37f4d425f8adfb2290da/gradio-discord.jpg -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import argparse 3 | from collections import Counter 4 | import json 5 | import pathlib 6 | import re 7 | 8 | 9 | import discord 10 | from discord.ext import commands 11 | import gradio as gr 12 | from gradio import utils 13 | import requests 14 | 15 | from typing import Dict, List 16 | 17 | from utils import * 18 | 19 | 20 | lock = asyncio.Lock() 21 | 22 | bot = commands.Bot("", intents=discord.Intents(messages=True, guilds=True)) 23 | 24 | 25 | GUILD_SPACES_FILE = "guild_spaces.pkl" 26 | 27 | 28 | if pathlib.Path(GUILD_SPACES_FILE).exists(): 29 | guild_spaces = read_pickle_file(GUILD_SPACES_FILE) 30 | assert isinstance(guild_spaces, dict), f"{GUILD_SPACES_FILE} in invalid format." 31 | guild_blocks = {} 32 | delete_keys = [] 33 | for k, v in guild_spaces.items(): 34 | try: 35 | guild_blocks[k] = gr.Interface.load(v, src="spaces") 36 | except ValueError: 37 | delete_keys.append(k) 38 | for k in delete_keys: 39 | del guild_spaces[k] 40 | else: 41 | guild_spaces: Dict[int, str] = {} 42 | guild_blocks: Dict[int, gr.Blocks] = {} 43 | 44 | 45 | HASHED_USERS_FILE = "users.pkl" 46 | 47 | if pathlib.Path(HASHED_USERS_FILE).exists(): 48 | hashed_users = read_pickle_file(HASHED_USERS_FILE) 49 | assert isinstance(hashed_users, list), f"{HASHED_USERS_FILE} in invalid format." 50 | else: 51 | hashed_users: List[str] = [] 52 | 53 | 54 | @bot.event 55 | async def on_ready(): 56 | print(f"Logged in as {bot.user}") 57 | print(f"Running in {len(bot.guilds)} servers...") 58 | 59 | 60 | async def run_prediction(space: gr.Blocks, *inputs): 61 | inputs = list(inputs) 62 | fn_index = 0 63 | processed_inputs = space.serialize_data(fn_index=fn_index, inputs=inputs) 64 | batch = space.dependencies[fn_index]["batch"] 65 | 66 | if batch: 67 | processed_inputs = [[inp] for inp in processed_inputs] 68 | 69 | outputs = await space.process_api( 70 | fn_index=fn_index, inputs=processed_inputs, request=None, state={} 71 | ) 72 | outputs = outputs["data"] 73 | 74 | if batch: 75 | outputs = [out[0] for out in outputs] 76 | 77 | processed_outputs = space.deserialize_data(fn_index, outputs) 78 | processed_outputs = utils.resolve_singleton(processed_outputs) 79 | 80 | return processed_outputs 81 | 82 | 83 | async def display_stats(message: discord.Message): 84 | await message.channel.send( 85 | f"Running in {len(bot.guilds)} servers\n" 86 | f"Total # of users: {len(hashed_users)}\n" 87 | f"------------------" 88 | ) 89 | await message.channel.send(f"Most popular spaces:") 90 | # display the top 10 most frequently occurring strings and their counts 91 | spaces = guild_spaces.values() 92 | counts = Counter(spaces) 93 | for space, count in counts.most_common(10): 94 | await message.channel.send(f"- {space}: {count}") 95 | 96 | 97 | async def load_space(guild: discord.Guild, message: discord.Message, content: str): 98 | iframe_url = ( 99 | requests.get(f"https://huggingface.co/api/spaces/{content}/host") 100 | .json() 101 | .get("host") 102 | ) 103 | if iframe_url is None: 104 | return await message.channel.send( 105 | f"Space: {content} not found. If you'd like to make a prediction, enclose the inputs in quotation marks." 106 | ) 107 | else: 108 | await message.channel.send( 109 | f"Loading Space: https://huggingface.co/spaces/{content}..." 110 | ) 111 | interface = gr.Interface.load(content, src="spaces") 112 | guild_spaces[guild.id] = content 113 | guild_blocks[guild.id] = interface 114 | asyncio.create_task(update_pickle_file(guild_spaces, GUILD_SPACES_FILE)) 115 | if len(content) > 32 - len(f"{bot.name} []"): # type: ignore 116 | nickname = content[: 32 - len(f"{bot.name} []") - 3] + "..." # type: ignore 117 | else: 118 | nickname = content 119 | nickname = f"{bot.name} [{nickname}]" # type: ignore 120 | await guild.me.edit(nick=nickname) 121 | await message.channel.send( 122 | "Ready to make predictions! Type in your inputs and enclose them in quotation marks." 123 | ) 124 | 125 | 126 | async def disconnect_space(bot: commands.Bot, guild: discord.Guild): 127 | guild_spaces.pop(guild.id, None) 128 | guild_blocks.pop(guild.id, None) 129 | asyncio.create_task(update_pickle_file(guild_spaces, GUILD_SPACES_FILE)) 130 | await guild.me.edit(nick=bot.name) # type: ignore 131 | 132 | 133 | async def make_prediction(guild: discord.Guild, message: discord.Message, content: str): 134 | if guild.id in guild_spaces: 135 | params = re.split(r' (?=")', content) 136 | params = [p.strip("'\"") for p in params] 137 | space = guild_blocks[guild.id] 138 | predictions = await run_prediction(space, *params) 139 | if isinstance(predictions, (tuple, list)): 140 | for p in predictions: 141 | await send_file_or_text(message.channel, p) 142 | else: 143 | await send_file_or_text(message.channel, predictions) 144 | return 145 | else: 146 | await message.channel.send( 147 | "No Space is currently running. Please type in the name of a Hugging Face Space name first, e.g. abidlabs/en2fr" 148 | ) 149 | await guild.me.edit(nick=bot.name) # type: ignore 150 | 151 | 152 | @bot.event 153 | async def on_message(message: discord.Message): 154 | if message.author == bot.user: 155 | return 156 | h = hash_user_id(message.author.id) 157 | if h not in hashed_users: 158 | hashed_users.append(h) 159 | asyncio.create_task(update_pickle_file(hashed_users, HASHED_USERS_FILE)) 160 | else: 161 | if message.content: 162 | content = remove_tags(message.content) 163 | guild = message.channel.guild 164 | assert guild, "Message not sent in a guild." 165 | 166 | if content.strip() == "exit": 167 | await disconnect_space(bot, guild) 168 | elif content.strip() == "stats": 169 | await display_stats(message) 170 | elif content.startswith('"') or content.startswith("'"): 171 | await make_prediction(guild, message, content) 172 | else: 173 | await load_space(guild, message, content) 174 | 175 | 176 | if __name__ == "__main__": 177 | parser = argparse.ArgumentParser() 178 | parser.add_argument( 179 | "--token", 180 | type=str, 181 | help="API key for the Discord bot. You can set this to your Discord token if you'd like to make your own clone of the Gradio Bot.", 182 | required=False, 183 | default="", 184 | ) 185 | args = parser.parse_args() 186 | 187 | if args.token.strip(): 188 | discord_token = args.token 189 | bot.env = "staging" # type: ignore 190 | bot.name = "StagingBot" # type: ignore 191 | else: 192 | with open("secrets.json") as fp: 193 | discord_token = json.load(fp)["discord_token"] 194 | bot.env = "prod" # type: ignore 195 | bot.name = "GradioBot" # type: ignore 196 | 197 | bot.run(discord_token) 198 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | discord.py 2 | gradio 3 | requests 4 | -------------------------------------------------------------------------------- /utils.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import asyncio 4 | import pickle 5 | import hashlib 6 | import pathlib 7 | from typing import Dict, List 8 | 9 | import discord 10 | 11 | lock = asyncio.Lock() 12 | 13 | 14 | async def update_pickle_file(data: Dict | List, file_path: str): 15 | async with lock: 16 | with open(file_path, "wb") as fp: 17 | pickle.dump(data, fp) 18 | 19 | 20 | def read_pickle_file(file_path: str): 21 | with open(file_path, "rb") as fp: 22 | return pickle.load(fp) 23 | 24 | 25 | async def send_file_or_text(channel, file_or_text: str): 26 | # if the file exists, send as a file 27 | if pathlib.Path(str(file_or_text)).exists(): 28 | with open(file_or_text, "rb") as f: 29 | return await channel.send(file=discord.File(f)) 30 | else: 31 | return await channel.send(file_or_text) 32 | 33 | 34 | def remove_tags(content: str) -> str: 35 | content = content.replace("<@1040198143695933501>", "") 36 | content = content.replace("<@1057338428938788884>", "") 37 | return content.strip() 38 | 39 | 40 | def hash_user_id(user_id: int) -> str: 41 | return hashlib.sha256(str(user_id).encode("utf-8")).hexdigest() 42 | --------------------------------------------------------------------------------