├── LICENSE ├── README.md ├── discord_bot.py ├── reader.py └── requirements.txt /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Anil Chandra Naidu Matcha 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 | # DiscordGPT 2 | Integrate ChatGPT into your own discord bot 3 | 4 | Train it on your knowledgebase content and make it answer customer support questions 5 | 6 | ### Getting Started 7 | 8 | Code is up now, ⭐ (Star) the repo to receive updates 9 | 10 | Follow [Anil Chandra Naidu Matcha](https://twitter.com/matchaman11) on twitter for updates 11 | 12 | Subscribe to https://www.youtube.com/@AnilChandraNaiduMatcha for more such video tutorials 13 | 14 | ### How to run ? (Things might change based on OS) 15 | 16 | 1. Create a virtual environment in python https://docs.python.org/3/library/venv.html 17 | 18 | 2. Run "pip install -r requirements.txt" 19 | 20 | 3. Set OPENAI_API_KEY environment variable with your openai key 21 | 22 | 4. Run "python discord_bot.py" 23 | 24 | 5. Change url with any url of your choice to train it on other content 25 | 26 | ### Official bot link 27 | 28 | https://discord.com/application-directory/1074419354994741350 29 | 30 | ### Also check 31 | 32 | [Chat with PDF code](https://github.com/Anil-matcha/ChatPDF) 33 | 34 | [Chat with Website code](https://github.com/Anil-matcha/Website-to-Chatbot) 35 | 36 | [Chat with CSV code](https://github.com/Anil-matcha/Chat-With-Excel) 37 | 38 | [Chat with Youtube code](https://github.com/Anil-matcha/Chat-Youtube) 39 | -------------------------------------------------------------------------------- /discord_bot.py: -------------------------------------------------------------------------------- 1 | # bot.py 2 | import os 3 | import discord 4 | from reader import WebpageQATool 5 | from langchain.chat_models import ChatOpenAI 6 | from langchain.chains.qa_with_sources.loading import load_qa_with_sources_chain 7 | TOKEN = "OTcwOTMzODc4MDgyNjY2NTE2.GSCSzd.Zr_UVei-ZxnzaxKRJe-oy-h0ms8DbwN9dLEW40" 8 | intents = discord.Intents.default() 9 | intents.message_content = True 10 | client = discord.Client(intents=intents) 11 | 12 | @client.event 13 | async def on_ready(): 14 | print(f'{client.user} has connected to Discord!') 15 | 16 | @client.event 17 | async def on_message(message): 18 | if client.user.mentioned_in(message): 19 | llm = ChatOpenAI(temperature=1.0) 20 | query_website_tool = WebpageQATool(qa_chain=load_qa_with_sources_chain(llm)) 21 | url = "https://uuki.live/" 22 | output = query_website_tool.run(message.clean_content+","+url)["output_text"] 23 | await message.reply(output) 24 | 25 | client.run(TOKEN) -------------------------------------------------------------------------------- /reader.py: -------------------------------------------------------------------------------- 1 | from langchain.tools import BaseTool 2 | from langchain.text_splitter import RecursiveCharacterTextSplitter 3 | from pydantic import Field 4 | from langchain.chains.qa_with_sources.loading import BaseCombineDocumentsChain 5 | import os, asyncio, trafilatura 6 | from langchain.docstore.document import Document 7 | 8 | def _get_text_splitter(): 9 | return RecursiveCharacterTextSplitter( 10 | # Set a really small chunk size, just to show. 11 | chunk_size = 500, 12 | chunk_overlap = 20, 13 | length_function = len, 14 | ) 15 | 16 | class WebpageQATool(BaseTool): 17 | name = "query_webpage" 18 | description = "Browse a webpage and retrieve the information relevant to the question." 19 | text_splitter: RecursiveCharacterTextSplitter = Field(default_factory=_get_text_splitter) 20 | qa_chain: BaseCombineDocumentsChain 21 | 22 | def _run(self, data: str) -> str: 23 | datalist = data.split(",") 24 | question, url = datalist[0], datalist[1] 25 | print("Data", question, url) 26 | result = trafilatura.extract(trafilatura.fetch_url(url)) 27 | docs = [Document(page_content=result, metadata={"source": url})] 28 | web_docs = self.text_splitter.split_documents(docs) 29 | results = [] 30 | for i in range(0, len(web_docs), 4): 31 | input_docs = web_docs[i:i+4] 32 | window_result = self.qa_chain({"input_documents": input_docs, "question": question}, return_only_outputs=True) 33 | results.append(f"Response from window {i} - {window_result}") 34 | results_docs = [Document(page_content="\n".join(results), metadata={"source": url})] 35 | return self.qa_chain({"input_documents": results_docs, "question": question}, return_only_outputs=True) 36 | 37 | async def _arun(self, url: str, question: str) -> str: 38 | raise NotImplementedError -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | aiohttp==3.8.4 2 | aiosignal==1.3.1 3 | async-timeout==4.0.2 4 | attrs==23.1.0 5 | certifi==2023.5.7 6 | charset-normalizer==3.1.0 7 | colorama==0.4.6 8 | courlan==0.9.2 9 | dataclasses-json==0.5.7 10 | dateparser==1.1.8 11 | discord.py==2.2.3 12 | frozenlist==1.3.3 13 | greenlet==2.0.2 14 | htmldate==1.4.3 15 | idna==3.4 16 | jusText==3.0.0 17 | langchain==0.0.175 18 | langcodes==3.3.0 19 | lxml==4.9.2 20 | marshmallow==3.19.0 21 | marshmallow-enum==1.5.1 22 | multidict==6.0.4 23 | mypy-extensions==1.0.0 24 | numexpr==2.8.4 25 | numpy==1.24.3 26 | openai==0.27.7 27 | openapi-schema-pydantic==1.2.4 28 | packaging==23.1 29 | pydantic==1.10.7 30 | python-dateutil==2.8.2 31 | pytz==2023.3 32 | PyYAML==6.0 33 | regex==2023.5.5 34 | requests==2.30.0 35 | six==1.16.0 36 | SQLAlchemy==2.0.15 37 | tenacity==8.2.2 38 | tld==0.13 39 | tqdm==4.65.0 40 | trafilatura==1.6.0 41 | typing-inspect==0.8.0 42 | typing_extensions==4.5.0 43 | tzdata==2023.3 44 | tzlocal==5.0.1 45 | urllib3==2.0.2 46 | yarl==1.9.2 47 | --------------------------------------------------------------------------------