diff --git a/apps/BingBot/.env.example b/apps/BingBot/.env.example
new file mode 100644
index 00000000..341406f7
--- /dev/null
+++ b/apps/BingBot/.env.example
@@ -0,0 +1,4 @@
+DISCORD_BOT_TOKEN=
+MENTION_CHANNEL_ID=
+AUTH_COOKIE=
+AUTH_COOKIE_SRCHHPGUSR=
diff --git a/apps/BingBot/Dockerfile b/apps/BingBot/Dockerfile
new file mode 100644
index 00000000..e276b5c8
--- /dev/null
+++ b/apps/BingBot/Dockerfile
@@ -0,0 +1,6 @@
+FROM python:3.9.16
+WORKDIR /bot
+COPY requirements.txt /bot/
+RUN pip install -r requirements.txt
+COPY . /bot
+CMD python bot.py
diff --git a/apps/BingBot/bing_bot.py b/apps/BingBot/bing_bot.py
new file mode 100644
index 00000000..4a562411
--- /dev/null
+++ b/apps/BingBot/bing_bot.py
@@ -0,0 +1,115 @@
+import discord
+import os
+import src.log
+import sys
+import pkg_resources
+import json
+from discord.ext import commands
+from dotenv import load_dotenv
+
+load_dotenv()
+
+bot = commands.Bot(command_prefix='!', intents = discord.Intents.all())
+
+# init loggger
+logger = src.log.setup_logger(__name__)
+
+def restart_bot():
+    # Replace current process with new instance of bot.py
+    os.execl(sys.executable, sys.executable, "bot.py")
+
+def check_verion() -> None:
+    # Read the requirements.txt file and add each line to a list
+    with open('requirements.txt') as f:
+        required = f.read().splitlines()
+
+    # For each library listed in requirements.txt, check if the corresponding version is installed
+    for package in required:
+        # Use the pkg_resources library to get information about the installed version of the library
+        package_name, package_verion = package.split('==')
+        installed = pkg_resources.get_distribution(package_name)
+        # Extract the library name and version number
+        name, version = installed.project_name, installed.version
+        # Compare the version number to see if it matches the one in requirements.txt
+        if package != f'{name}=={version}':
+            logger.error(f'{name} version {version} is installed but does not match the requirements')
+            sys.exit()
+
+@bot.event
+async def on_ready():
+    bot_status = discord.Status.online
+    bot_activity = discord.Activity(type=discord.ActivityType.playing, name = "bing.com")
+    await bot.change_presence(status = bot_status, activity = bot_activity)
+    for Filename in os.listdir('./cogs'):
+        if Filename.endswith('.py'):
+            await bot.load_extension(f'cogs.{Filename[:-3]}')
+    logger.info(f'{bot.user} is now running!')
+    print("Bot is Up and Ready!")
+    try:
+        synced = await bot.tree.sync()
+        print(f"Synced {len(synced)} commands")
+    except Exception as e:
+        print(e)
+
+# Load command
+@commands.is_owner()   
+@bot.command()
+async def load(ctx, extension):
+    await bot.load_extension(f'cogs.{extension}')
+    await ctx.author.send(f'> **Loaded {extension} done.**')
+
+# Unload command
+@commands.is_owner()
+@bot.command()
+async def unload(ctx, extension):
+    await bot.unload_extension(f'cogs.{extension}')
+    await ctx.author.send(f'> **Un-Loaded {extension} done.**')
+
+# Empty discord_bot.log file
+@commands.is_owner()
+@bot.command()
+async def clean(ctx):
+    open('discord_bot.log', 'w').close()
+    await ctx.author.send(f'> **Successfully emptied the file!**')
+
+# Get discord_bot.log file
+@commands.is_owner()
+@bot.command()
+async def getLog(ctx):
+    try:
+        with open('discord_bot.log', 'rb') as f:
+            file = discord.File(f)
+        await ctx.author.send(file=file)
+        await ctx.author.send("> **Send successfully!**")
+    except:
+        await ctx.author.send("> **Send failed!**")
+
+# Upload new Bing cookies and restart the bot
+@commands.is_owner()
+@bot.command()
+async def upload(ctx):
+    if ctx.message.attachments:
+        for attachment in ctx.message.attachments:
+            if str(attachment)[-4:] == ".txt":
+                content = await attachment.read()
+                with open("cookies.json", "w", encoding = "utf-8") as f:
+                    json.dump(json.loads(content), f, indent = 2)
+                if not isinstance(ctx.channel, discord.abc.PrivateChannel):
+                    await ctx.message.delete()
+                await ctx.author.send(f'> **Upload new cookies successfully!**')
+                logger.warning("\x1b[31mCookies has been setup successfully\x1b[0m")
+                restart_bot()
+            else:
+                await ctx.author.send("> **Didn't get any txt file.**")
+    else:
+        await ctx.author.send("> **Didn't get any file.**")
+
+if __name__ == '__main__':
+    check_verion()
+    bot.run(os.getenv("DISCORD_BOT_TOKEN"))
+
+
+
+
+
+
diff --git a/apps/BingBot/cogs/edgegpt.py b/apps/BingBot/cogs/edgegpt.py
new file mode 100644
index 00000000..683780db
--- /dev/null
+++ b/apps/BingBot/cogs/edgegpt.py
@@ -0,0 +1,148 @@
+import os
+import discord
+import json
+from typing import Optional
+from EdgeGPT.ImageGen import ImageGenAsync, ImageGen
+from EdgeGPT.EdgeGPT import Chatbot
+from discord import app_commands
+from core.classes import Cog_Extension
+from src import log
+from src.imageCreate import create_image, get_using_create, set_using_create
+from src.response import send_message, get_using_send, set_using_send
+from dotenv import load_dotenv
+
+load_dotenv()
+
+logger = log.setup_logger(__name__)
+
+users_chatbot = {}
+users_image_generator = {}
+user_conversation_style = {}
+
+async def init_chatbot(user_id):
+    with open("./cookies.json", encoding="utf-8") as file:
+        cookie_json = json.load(file)
+    for cookie in cookie_json:
+        if cookie.get("name") == "_U":
+            auth_cookie = cookie.get("value")
+            break
+    
+    auth_cookie = os.environ.get("AUTH_COOKIE")
+    auth_cookie_SRCHHPGUSR = os.environ.get("AUTH_COOKIE_SRCHHPGUSR")
+    # auth_cookie_SRCHHPGUSR = os.environ.get("AUTH_COOKIE_SRCHHPGUSR")
+    users_chatbot[user_id] = UserChatbot(cookies=cookie_json)
+    users_image_generator[user_id] = ImageGenAsync(auth_cookie, quiet=True)
+    user_conversation_style[user_id] = "balanced"
+
+class UserChatbot:
+    def __init__(self, cookies):
+        self.chatbot = Chatbot(cookies=cookies)
+
+    async def send_message(self, interaction, message, conversation_style):
+        await send_message(self.chatbot, interaction, message, conversation_style)
+
+    async def create_image(self, interaction, prompt: str, image_generator):
+        await create_image(interaction, prompt, image_generator)
+
+    async def reset(self):
+        await self.chatbot.reset()
+
+class EdgeGPT(Cog_Extension):
+    # Chat with Bing
+    @app_commands.command(name="bing", description="Have a chat with Bing")
+    async def bing(self, interaction: discord.Interaction, *, message: str):
+        try:
+            using = await get_using_send(interaction.user.id)
+        except:
+            await set_using_send(interaction.user.id, False)
+            using = await get_using_send(interaction.user.id)
+        if not using:
+            await interaction.response.defer(ephemeral=False, thinking=True) 
+            username = str(interaction.user)
+            usermessage = message
+            channel = str(interaction.channel)
+            user_id = interaction.user.id
+            if user_id not in users_chatbot:
+                await init_chatbot(interaction.user.id)
+            conversation_style = user_conversation_style[user_id]
+            logger.info(f"\x1b[31m{username}\x1b[0m : '{usermessage}' ({channel}) [Style: {conversation_style}]")
+            await users_chatbot[user_id].send_message(interaction, usermessage, conversation_style)
+        else:
+            await interaction.response.defer(ephemeral=True, thinking=True)
+            await interaction.followup.send("> **Please wait for your last conversation to finish.**")
+
+    # Reset Bing conversation
+    @app_commands.command(name="reset", description="Reset Bing conversation")
+    async def reset(self, interaction: discord.Interaction):
+        await interaction.response.defer(ephemeral=True, thinking=True)
+        user_id = interaction.user.id
+        try:
+            await users_chatbot[user_id].reset()
+            await interaction.followup.send("> **Info: Reset finish.**")
+            logger.warning("\x1b[31mBing has been successfully reset\x1b[0m")
+        except:
+            await interaction.followup.send(f"> **You don't have any conversation yet.**")
+            logger.exception("Bing reset failed.")
+
+    # Switch conversation style
+    @app_commands.command(name="switch_style", description="Switch conversation style")
+    @app_commands.choices(style=[app_commands.Choice(name="Creative", value="creative"), app_commands.Choice(name="Balanced", value="balanced"), app_commands.Choice(name="Precise", value="precise")])
+    async def switch_style(self, interaction: discord.Interaction, style: app_commands.Choice[str]):
+        await interaction.response.defer(ephemeral=True, thinking=True)
+        user_id = interaction.user.id
+        if user_id not in users_chatbot:
+            await init_chatbot(user_id)
+        user_conversation_style[user_id] = style.value
+        await interaction.followup.send(f"> **Info: successfull switch conversation style to {style.value}.**")
+        logger.warning(f"\x1b[31mConversation style has been successfully switch to {style.value}\x1b[0m")
+    
+    # Set and delete personal Bing Cookies
+    @app_commands.command(name="bing_cookies", description="Set or delete Bing Cookies")
+    @app_commands.choices(choice=[app_commands.Choice(name="set", value="set"), app_commands.Choice(name="delete", value="delete")])
+    async def cookies_setting(self, interaction: discord.Interaction, choice: app_commands.Choice[str], cookies_file: Optional[discord.Attachment]=None):
+        await interaction.response.defer(ephemeral=True, thinking=True)
+        user_id = interaction.user.id
+        if choice.value == "set":
+            try:
+                content = json.loads(await cookies_file.read())
+                for cookie in content:
+                    if cookie.get("name") == "_U":
+                        auth_cookie = cookie.get("value")
+                        break
+                users_image_generator[user_id] = ImageGenAsync(auth_cookie, quiet=True)
+                users_chatbot[user_id] = UserChatbot(cookies=content)
+                user_conversation_style[user_id] = "balanced" 
+                await interaction.followup.send("> **Upload successful!**")
+                logger.warning(f"\x1b[31m{interaction.user} set Bing Cookies successful\x1b[0m")
+            except:
+                await interaction.followup.send("> **Please upload your Bing Cookies.**")
+        else:
+            try:
+                del users_chatbot[user_id]
+                del users_image_generator[user_id]
+                del user_conversation_style[user_id]
+                await interaction.followup.send("> **Delete finish.**")
+                logger.warning(f"\x1b[31m{interaction.user} delete Cookies\x1b[0m")
+            except:
+                await interaction.followup.send("> **You don't have any Bing Cookies.**")
+
+    # Create images
+    @app_commands.command(name="create_image", description="generate image by Bing image creator")
+    async def create_image(self, interaction: discord.Interaction, *, prompt: str):
+        user_id = interaction.user.id
+        if interaction.user.id not in users_chatbot:
+            await init_chatbot(user_id)
+        try:
+            using = await get_using_create(user_id)
+        except:
+            await set_using_create(user_id, False)
+            using = await get_using_create(user_id)
+        if not using: 
+            logger.info(f"\x1b[31m{interaction.user}\x1b[0m : '{prompt}' ({interaction.channel}) [BingImageCreator]")
+            await users_chatbot[user_id].create_image(interaction, prompt, users_image_generator[user_id] )
+        else:
+            await interaction.response.defer(ephemeral=True, thinking=True)
+            await interaction.followup.send("> **Please wait for your last image to create finish.**")
+
+async def setup(bot):
+    await bot.add_cog(EdgeGPT(bot))
diff --git a/apps/BingBot/cogs/event.py b/apps/BingBot/cogs/event.py
new file mode 100644
index 00000000..f42b6e5b
--- /dev/null
+++ b/apps/BingBot/cogs/event.py
@@ -0,0 +1,223 @@
+import discord
+import re
+import os
+import json
+import asyncio
+from EdgeGPT.EdgeGPT import Chatbot, ConversationStyle
+from dotenv import load_dotenv
+from discord.ext import commands
+from core.classes import Cog_Extension
+from functools import partial
+from src import log
+
+load_dotenv()
+
+USE_SUGGEST_RESPONSES = True
+try:
+    MENTION_CHANNEL_ID = int(os.getenv("MENTION_CHANNEL_ID"))
+except:
+    MENTION_CHANNEL_ID = None
+logger = log.setup_logger(__name__)
+sem = asyncio.Semaphore(1)
+conversation_style = "balanced"
+
+with open("./cookies.json", encoding="utf-8") as file:
+    cookies = json.load(file)
+chatbot = Chatbot(cookies=cookies)
+
+# To add suggest responses
+class MyView(discord.ui.View):
+    def __init__(self, chatbot: Chatbot, suggest_responses:list):
+        super().__init__(timeout=120)
+        # Add buttons
+        for label in suggest_responses:
+            button = discord.ui.Button(label=label)
+            # Button event
+            async def callback(interaction: discord.Interaction, button: discord.ui.Button):
+                    await interaction.response.defer(ephemeral=False, thinking=True)
+                    # When click the button, all buttons will disable.
+                    for child in self.children:
+                        child.disabled = True
+                    await interaction.followup.edit_message(message_id=interaction.message.id, view=self)
+                    username = str(interaction.user)
+                    usermessage = button.label
+                    channel = str(interaction.channel)
+                    logger.info(f"\x1b[31m{username}\x1b[0m : '{usermessage}' ({channel}) [Style: {conversation_style}] [button]")
+                    task = asyncio.create_task(send_message(chatbot, interaction, usermessage))
+                    await asyncio.gather(task)
+            self.add_item(button)
+            self.children[-1].callback = partial(callback, button=button)
+# Show Dropdown
+class DropdownView(discord.ui.View):
+    def __init__(self):
+        super().__init__(timeout=180)
+
+        options = [
+            discord.SelectOption(label="Creative", description="Switch conversation style to Creative", emoji='🎨'),
+            discord.SelectOption(label="Balanced", description="Switch conversation style to Balanced", emoji='⚖️'),
+            discord.SelectOption(label="Precise", description="Switch conversation style to Precise", emoji='🔎'),
+            discord.SelectOption(label="Reset", description="Reset conversation", emoji="🔄")
+        ]
+
+        dropdown = discord.ui.Select(
+            placeholder="Choose setting",
+            min_values=1,
+            max_values=1,
+            options=options
+        )
+
+        dropdown.callback = self.dropdown_callback
+        self.add_item(dropdown)
+    # Dropdown event
+    async def dropdown_callback(self, interaction: discord.Interaction):
+        await interaction.response.defer(ephemeral=False, thinking=True)
+        if interaction.data['values'][0] == "Creative":
+            await set_conversation_style("creative")
+            await interaction.followup.send(f"> **Info: successfull switch conversation style to *{interaction.data['values'][0]}*.**")
+            logger.warning(f"\x1b[31mConversation style has been successfully switch to {interaction.data['values'][0]}\x1b[0m")
+        elif interaction.data['values'][0] == "Balanced":
+            await set_conversation_style("balanced")
+            await interaction.followup.send(f"> **Info: successfull switch conversation style to *{interaction.data['values'][0]}*.**")
+            logger.warning(f"\x1b[31mConversation style has been successfully switch to {interaction.data['values'][0]}\x1b[0m")
+        elif interaction.data['values'][0] == "Precise":
+            await set_conversation_style("precise")
+            await interaction.followup.send(f"> **Info: successfull switch conversation style to *{interaction.data['values'][0]}*.**")
+            logger.warning(f"\x1b[31mConversation style has been successfully switch to {interaction.data['values'][0]}\x1b[0m")
+        else:
+            await chatbot.reset()
+            await interaction.followup.send(f"> **Info: Reset finish.**")
+            logger.warning("\x1b[31mBing has been successfully reset\x1b[0m")
+        # disable dropdown after select
+        for dropdown in self.children:
+            dropdown.disabled = True
+        await interaction.followup.edit_message(message_id=interaction.message.id, view=self)
+
+# Set conversation style
+async def set_conversation_style(style: str):
+    global conversation_style
+    conversation_style = style
+async def set_chatbot(cookies):
+    global chatbot
+    chatbot = Chatbot(cookies=cookies)
+
+async def send_message(chatbot: Chatbot, message, user_message: str):
+    async with sem:
+        if isinstance(message, discord.message.Message):
+            await message.channel.typing()
+        reply = ''
+        text = ''
+        link_embed = ''
+        images_embed = []
+        all_url = []
+        try:
+             # Change conversation style
+            if conversation_style == "creative":
+                reply = await chatbot.ask(prompt=user_message, conversation_style=ConversationStyle.creative, simplify_response=True)
+            elif conversation_style == "precise":
+                reply = await chatbot.ask(prompt=user_message, conversation_style=ConversationStyle.precise, simplify_response=True)
+            else:
+                reply = await chatbot.ask(prompt=user_message, conversation_style=ConversationStyle.balanced, simplify_response=True)
+
+            # Get reply text
+            text = f"{reply['text']}"
+            text = re.sub(r'\[\^(\d+)\^\]', lambda match: '', text)
+
+            # Get the URL, if available
+            try:
+                if len(reply['sources']) != 0:
+                    for i, url in enumerate(reply['sources'], start=1):
+                        if len(url['providerDisplayName']) == 0:
+                            all_url.append(f"{i}. {url['seeMoreUrl']}")
+                        else:
+                            all_url.append(f"{i}. [{url['providerDisplayName']}]({url['seeMoreUrl']})")
+                link_text = "\n".join(all_url)
+                link_embed = discord.Embed(description=link_text)
+            except:
+                pass
+
+            # Set the final message
+            if isinstance(message, discord.interactions.Interaction):
+                user_message = user_message.replace("\n", "")
+                ask = f"> **{user_message}**\t(***style: {conversation_style}***)\n\n"
+                response = f"{ask}{text}"
+            else:
+                response = f"{text}\t(***style: {conversation_style}***)"
+
+            # Discord limit about 2000 characters for a message
+            while len(response) > 2000:
+                temp = response[:2000]
+                response = response[2000:]
+                if isinstance(message, discord.interactions.Interaction): 
+                    await message.followup.send(temp)
+                else: 
+                    await message.channel.send(temp)
+
+            # Get the image, if available
+            try:
+                if len(link_embed) == 0:
+                    all_image = re.findall("https?://[\w\./]+", str(reply["sources_text"]))
+                    [images_embed.append(discord.Embed(url="https://www.bing.com/").set_image(url=image_link)) for image_link in all_image]
+            except:
+                pass
+            
+            if USE_SUGGEST_RESPONSES:
+                suggest_responses = reply["suggestions"]
+                if images_embed:
+                    if isinstance(message, discord.interactions.Interaction):
+                        await message.followup.send(response, view=MyView(chatbot, suggest_responses), embeds=images_embed, wait=True)                
+                    else:
+                        await message.channel.send(response, view=MyView(chatbot, suggest_responses), embeds=images_embed)
+                elif link_embed:
+                    if isinstance(message, discord.interactions.Interaction):
+                        await message.followup.send(response, view=MyView(chatbot, suggest_responses), embed=link_embed, wait=True)
+                    else:
+                        await message.channel.send(response, view=MyView(chatbot, suggest_responses), embed=link_embed)
+                else:
+                    if isinstance(message, discord.interactions.Interaction):
+                        await message.followup.send(response, view=MyView(chatbot, suggest_responses), wait=True)
+                    else:
+                        await message.channel.send(response, view=MyView(chatbot, suggest_responses))
+            else:
+                if images_embed:
+                    if isinstance(message, discord.interactions.Interaction):
+                        await message.followup.send(response, embeds=images_embed, wait=True)                
+                    else:
+                        await message.channel.send(response, embeds=images_embed)
+                elif link_embed:
+                    if isinstance(message, discord.interactions.Interaction):
+                        await message.followup.send(response, embed=link_embed, wait=True)
+                    else:
+                        await message.channel.send(response, embed=link_embed)
+                else:
+                    if isinstance(message, discord.interactions.Interaction):
+                        await message.followup.send(response, wait=True)
+                    else:
+                        await message.channel.send(response)
+        except Exception as e:
+            if isinstance(message, discord.interactions.Interaction):
+                await message.followup.send(f">>> **Error: {e}**")
+            else:
+                await message.channel.send(f">>> **Error: {e}**")
+            logger.exception(f"Error while sending message: {e}")
+
+class Event(Cog_Extension):
+    @commands.Cog.listener()
+    async def on_message(self, message: discord.Message):
+        if message.author == self.bot.user:
+            return
+        if self.bot.user in message.mentions:
+            if not MENTION_CHANNEL_ID or message.channel.id == MENTION_CHANNEL_ID:
+                content = re.sub(r'<@.*?>', '', message.content).strip()
+                if len(content) > 0:
+                    username = str(message.author)
+                    channel = str(message.channel)
+                    logger.info(f"\x1b[31m{username}\x1b[0m : '{content}' ({channel}) [Style: {conversation_style}]")
+                    task = asyncio.create_task(send_message(chatbot, message, content))
+                    await asyncio.gather(task)
+                else:
+                    await message.channel.send(view=DropdownView())
+            elif MENTION_CHANNEL_ID is not None:
+                await message.channel.send(f"> **Can only be mentioned at <#{self.bot.get_channel(MENTION_CHANNEL_ID).id}>**")
+
+async def setup(bot):
+    await bot.add_cog(Event(bot))
diff --git a/apps/BingBot/cogs/help.py b/apps/BingBot/cogs/help.py
new file mode 100644
index 00000000..16ecff78
--- /dev/null
+++ b/apps/BingBot/cogs/help.py
@@ -0,0 +1,17 @@
+import discord
+from core.classes import Cog_Extension
+from discord import app_commands
+
+class Help(Cog_Extension):
+    @app_commands.command(name = "help", description = "Show how to use")
+    async def help(self, interaction: discord.Interaction):
+        embed=discord.Embed(title="Help", description="[see more](https://github.com/FuseFairy/DiscordBot-EdgeGPT/blob/main/README.md)\n\n**COMMANDS -**")
+        embed.add_field(name="/bing_cookies", value="Set and delete your Bing Cookies.", inline=False)
+        embed.add_field(name="/bing", value="Chat with Bing.", inline=False)
+        embed.add_field(name="/reset", value="Reset your Bing conversation.", inline=False)
+        embed.add_field(name="/switch_style", value="Switch your Bing conversation style.", inline=False)
+        embed.add_field(name="/create_image", value="Generate image by Bing Image Creator.", inline=False)
+        await interaction.response.send_message(embed=embed)
+
+async def setup(bot):
+    await bot.add_cog(Help(bot))
\ No newline at end of file
diff --git a/apps/BingBot/compose.yaml b/apps/BingBot/compose.yaml
new file mode 100644
index 00000000..f574f912
--- /dev/null
+++ b/apps/BingBot/compose.yaml
@@ -0,0 +1,10 @@
+version: '3'
+
+services:
+  discord_edgegpt:
+    build: .
+    environment:
+      - DISCORD_BOT_TOKEN=${DISCORD_BOT_TOKEN}
+    volumes:
+      - ./cookies.json:/bot/cookies.json
+      - ./config.yml:/bot/config.yml
diff --git a/apps/BingBot/cookies.json b/apps/BingBot/cookies.json
new file mode 100644
index 00000000..4d0748fc
--- /dev/null
+++ b/apps/BingBot/cookies.json
@@ -0,0 +1,6 @@
+[
+    {
+        "name": "cookie1",
+        "value": "1lEXeWRSIPUsQ0S3tdAc3v7BexGK2qBlzsXz8j52w_HNBoOsegjiwRySQHmfoWduHVUxSXo6cETPP2qNrYWAz6k7wn43WGO9i7ll9_Wl7M6HA2c9twbKByfAtAB5fr26wPawQ6y1GCdakD_Kr4xdD20fvkytnmOmZu7Ktnb9mUVE605AAbJcIA9SOlRN5410ZPOnZA1cIzr4WtAFWNfQKPG6Sxk_zO5zvXQfYTyMNmOI"
+    }
+]
diff --git a/apps/BingBot/core/classes.py b/apps/BingBot/core/classes.py
new file mode 100644
index 00000000..8dfdb114
--- /dev/null
+++ b/apps/BingBot/core/classes.py
@@ -0,0 +1,5 @@
+from discord.ext import commands
+
+class Cog_Extension(commands.Cog):
+    def __init__(self, bot):
+        self.bot = bot
diff --git a/apps/BingBot/requirements.txt b/apps/BingBot/requirements.txt
new file mode 100644
index 00000000..73773a31
--- /dev/null
+++ b/apps/BingBot/requirements.txt
@@ -0,0 +1,4 @@
+discord.py==2.3.2
+python-dotenv==0.21.1
+PyYAML==6.0
+EdgeGPT==0.13.2
diff --git a/apps/BingBot/src/imageCreate.py b/apps/BingBot/src/imageCreate.py
new file mode 100644
index 00000000..b88d1d4b
--- /dev/null
+++ b/apps/BingBot/src/imageCreate.py
@@ -0,0 +1,31 @@
+import discord
+import asyncio
+from src import log
+
+logger = log.setup_logger(__name__)
+using_func = {}
+
+async def get_using_create(user_id):
+    return using_func[user_id]
+async def set_using_create(user_id, status: bool):
+     using_func[user_id] = status
+
+async def create_image(interaction: discord.Interaction, prompt: str, image_generator):
+    await interaction.response.defer(ephemeral=False, thinking=True)
+    using_func[interaction.user.id] = True
+    try:
+        embeds = []
+        prompts = f"> **{prompt}** - <@{str(interaction.user.id)}> (***BingImageCreator***)\n\n"
+        # Fetches image links 
+        images = await image_generator.get_images(prompt)
+        # Add embed to list of embeds
+        [embeds.append(discord.Embed(url="https://www.bing.com/").set_image(url=image_link)) for image_link in images]
+        await interaction.followup.send(prompts, embeds=embeds, wait=True)
+    except asyncio.TimeoutError:
+        await interaction.followup.send("> **Error: Request timed out.**")
+        logger.exception("Error while create image: Request timed out.")
+    except Exception as e:
+        await interaction.followup.send(f"> **Error: {e}**")
+        logger.exception(f"Error while create image: {e}")
+    finally:
+        using_func[interaction.user.id] = False
\ No newline at end of file
diff --git a/apps/BingBot/src/log.py b/apps/BingBot/src/log.py
new file mode 100644
index 00000000..fba4e94d
--- /dev/null
+++ b/apps/BingBot/src/log.py
@@ -0,0 +1,67 @@
+import os
+import logging
+import logging.handlers
+
+
+class CustomFormatter(logging.Formatter):
+
+    LEVEL_COLORS = [
+        (logging.DEBUG, '\x1b[40;1m'),
+        (logging.INFO, '\x1b[34;1m'),
+        (logging.WARNING, '\x1b[33;1m'),
+        (logging.ERROR, '\x1b[31m'),
+        (logging.CRITICAL, '\x1b[41m'),
+    ]
+    FORMATS = {
+        level: logging.Formatter(
+            f'\x1b[30;1m%(asctime)s\x1b[0m {color}%(levelname)-8s\x1b[0m \x1b[35m%(name)s\x1b[0m -> %(message)s',
+            '%Y-%m-%d %H:%M:%S'
+        )
+        for level, color in LEVEL_COLORS
+    }
+
+    def format(self, record):
+        formatter = self.FORMATS.get(record.levelno)
+        if formatter is None:
+            formatter = self.FORMATS[logging.DEBUG]
+
+        # Override the traceback to always print in red
+        if record.exc_info:
+            text = formatter.formatException(record.exc_info)
+            record.exc_text = f'\x1b[31m{text}\x1b[0m'
+
+        output = formatter.format(record)
+
+        # Remove the cache layer
+        record.exc_text = None
+        return output
+
+
+def setup_logger(module_name:str) -> logging.Logger:
+    # create logger
+    library, _, _ = module_name.partition('.py')
+    logger = logging.getLogger(library)
+    logger.setLevel(logging.INFO)
+
+    if not logger.handlers:
+        # create console handler
+        console_handler = logging.StreamHandler()
+        console_handler.setLevel(logging.INFO)
+        console_handler.setFormatter(CustomFormatter())
+        # specify that the log file path is the same as `main.py` file path
+        grandparent_dir = os.path.abspath(__file__ + "/../../")
+        log_name='discord_bot.log'
+        log_path = os.path.join(grandparent_dir, log_name)
+        # create local log handler
+        log_handler = logging.handlers.RotatingFileHandler(
+            filename=log_path,
+            encoding='utf-8',
+            maxBytes=32 * 1024 * 1024,  # 32 MiB
+            backupCount=2,  # Rotate through 5 files
+        )
+        log_handler.setFormatter(CustomFormatter())
+        # Add handlers to logger
+        logger.addHandler(log_handler)
+        logger.addHandler(console_handler)
+
+    return logger
diff --git a/apps/BingBot/src/response.py b/apps/BingBot/src/response.py
new file mode 100644
index 00000000..371622b8
--- /dev/null
+++ b/apps/BingBot/src/response.py
@@ -0,0 +1,117 @@
+import discord
+import re
+from EdgeGPT.EdgeGPT import Chatbot, ConversationStyle
+from src import log
+from functools import partial
+
+USE_SUGGEST_RESPONSES = True
+logger = log.setup_logger(__name__)
+using_func = {}
+
+# To add suggest responses
+class MyView(discord.ui.View):
+    def __init__(self, interaction: discord.Interaction, chatbot: Chatbot, conversation_style:str, suggest_responses:list):
+        super().__init__(timeout=120)
+        self.button_author =interaction.user.id
+        # Add buttons
+        for label in suggest_responses:
+            button = discord.ui.Button(label=label)
+            # Button event
+            async def callback(interaction: discord.Interaction, button_author: int, button: discord.ui.Button):
+                if interaction.user.id != button_author:
+                    await interaction.response.defer(ephemeral=True, thinking=True)
+                    await interaction.followup.send("You don't have permission to press this button.")
+                elif not using_func[interaction.user.id]:
+                    await interaction.response.defer(ephemeral=False, thinking=True)
+                    # When click the button, all buttons will disable.
+                    for child in self.children:
+                        child.disabled = True
+                    await interaction.followup.edit_message(message_id=interaction.message.id, view=self)
+                    username = str(interaction.user)
+                    usermessage = button.label
+                    channel = str(interaction.channel)
+                    logger.info(f"\x1b[31m{username}\x1b[0m : '{usermessage}' ({channel}) [Style: {conversation_style}] [button]")
+                    await send_message(chatbot, interaction, usermessage, conversation_style)
+                else:
+                    await interaction.response.defer(ephemeral=True, thinking=True)
+                    await interaction.followup.send("Please wait for your last conversation to finish.")
+            self.add_item(button)
+            self.children[-1].callback = partial(callback, button_author=self.button_author, button=button)
+
+async def get_using_send(user_id):
+    return using_func[user_id]
+async def set_using_send(user_id, status: bool):
+    using_func[user_id] = status
+
+async def send_message(chatbot: Chatbot, interaction: discord.Interaction, user_message: str, conversation_style: str):
+    using_func[interaction.user.id] = True
+    reply = ''
+    text = ''
+    link_embed = ''
+    images_embed = []
+    all_url = []
+    try:
+        # Change conversation style
+        if conversation_style == "creative":
+            reply = await chatbot.ask(prompt=user_message, conversation_style=ConversationStyle.creative, simplify_response=True)
+        elif conversation_style == "precise":
+            reply = await chatbot.ask(prompt=user_message, conversation_style=ConversationStyle.precise, simplify_response=True)
+        else:
+            reply = await chatbot.ask(prompt=user_message, conversation_style=ConversationStyle.balanced, simplify_response=True)
+
+        # Get reply text
+        text = f"{reply['text']}"
+        text = re.sub(r'\[\^(\d+)\^\]', lambda match: '', text)
+        
+        # Get the URL, if available
+        try:
+            if len(reply['sources']) != 0:
+                for i, url in enumerate(reply['sources'], start=1):
+                    if len(url['providerDisplayName']) == 0:
+                        all_url.append(f"{i}. {url['seeMoreUrl']}")
+                    else:
+                        all_url.append(f"{i}. [{url['providerDisplayName']}]({url['seeMoreUrl']})")
+            link_text = "\n".join(all_url)
+            link_embed = discord.Embed(description=link_text)
+        except:
+            pass
+        
+        # Set the final message
+        user_message = user_message.replace("\n", "")
+        ask = f"> **{user_message}** - <@{str(interaction.user.id)}> (***style: {conversation_style}***)\n\n"
+        response = f"{ask}{text}"
+        
+        # Discord limit about 2000 characters for a message
+        while len(response) > 2000:
+            temp = response[:2000]
+            response = response[2000:]
+            await interaction.followup.send(temp)
+
+        # Get the image, if available
+        try:
+            if len(link_embed) == 0:
+                all_image = re.findall("https?://[\w\./]+", str(reply["sources_text"]))
+                [images_embed.append(discord.Embed(url="https://www.bing.com/").set_image(url=image_link)) for image_link in all_image]
+        except:
+            pass
+        # Add all suggest responses in list
+        if USE_SUGGEST_RESPONSES:
+            suggest_responses = reply["suggestions"]
+            if images_embed:
+                await interaction.followup.send(response, view=MyView(interaction, chatbot, conversation_style, suggest_responses), embeds=images_embed, wait=True)                
+            elif link_embed:
+                await interaction.followup.send(response, view=MyView(interaction, chatbot, conversation_style, suggest_responses), embed=link_embed, wait=True)
+            else:
+                await interaction.followup.send(response, view=MyView(interaction, chatbot, conversation_style, suggest_responses), wait=True)
+        else:
+            if images_embed:
+                await interaction.followup.send(response, embeds=images_embed, wait=True)
+            elif link_embed:
+                await interaction.followup.send(response, embed=link_embed, wait=True)
+            else:
+                await interaction.followup.send(response, wait=True)
+    except Exception as e:
+            await interaction.followup.send(f">>> **Error: {e}**")
+            logger.exception(f"Error while sending message: {e}")
+    finally:
+        using_func[interaction.user.id] = False
diff --git a/apps/discord.py b/apps/discord.py
index aa07f4e5..eebc48c8 100644
--- a/apps/discord.py
+++ b/apps/discord.py
@@ -1,17 +1,117 @@
-import os
-import asyncio
-import dalle3
 import discord
-import responses
-from invoke import Executor
-from dotenv import load_dotenv
 from discord.ext import commands
+import asyncio
+import os
+from dotenv import load_dotenv
+from invoke import Executor
+
+class BotCommands(commands.Cog):
+    def __init__(self, bot):
+        self.bot = bot
+
+    @commands.command()
+    async def greet(self, ctx):
+        """greets the user."""
+        await ctx.send(f"hello, {ctx.author.name}!")
+
+    @commands.command()
+    async def help_me(self, ctx):
+        """provides a list of commands and their descriptions."""
+        help_text = """
+        - `!greet`: greets you.
+        - `!run [description]`: generates a video based on the given description.
+        - `!help_me`: provides this list of commands and their descriptions.
+        """
+        await ctx.send(help_text)
+
+    @commands.command()
+    async def join(self, ctx):
+        """joins the voice channel that the user is in."""
+        if ctx.author.voice:
+            channel = ctx.author.voice.channel
+            await channel.connect()
+        else:
+            await ctx.send("you are not in a voice channel!")
+
+    @commands.command()
+    async def leave(self, ctx):
+        """leaves the voice channel that the self.bot is in."""
+        if ctx.voice_client:
+            await ctx.voice_client.disconnect()
+        else:
+            await ctx.send("i am not in a voice channel!")
+
+    @commands.command()
+    async def listen(self, ctx):
+        """starts listening to voice in the voice channel that the bot is in."""
+        if ctx.voice_client:
+            # create a wavesink to record the audio
+            sink = discord.sinks.wavesink('audio.wav')
+            # start recording
+            ctx.voice_client.start_recording(sink)
+            await ctx.send("started listening and recording.")
+        else:
+            await ctx.send("i am not in a voice channel!")
+
+    @commands.command()
+    async def generate_image(self, ctx, *, prompt: str = None, imggen: str = None):
+        """generates images based on the provided prompt"""
+        await ctx.send(f"generating images for prompt: `{prompt}`...")
+        loop = asyncio.get_event_loop()
+
+        # initialize a future object for the dalle instance
+        future = loop.run_in_executor(Executor, imggen, prompt)
+
+        try:
+            # wait for the dalle request to complete, with a timeout of 60 seconds
+            await asyncio.wait_for(future, timeout=300)
+            print("done generating images!")
+
+            # list all files in the save_directory
+            all_files = [os.path.join(root, file) for root, _, files in os.walk(os.environ("SAVE_DIRECTORY")) for file in files]
+
+            # sort files by their creation time (latest first)
+            sorted_files = sorted(all_files, key=os.path.getctime, reverse=True)
+
+            # get the 4 most recent files
+            latest_files = sorted_files[:4]
+            print(f"sending {len(latest_files)} images to discord...")
+
+            # send all the latest images in a single message
+            # storage_service = os.environ("STORAGE_SERVICE") # "https://storage.googleapis.com/your-bucket-name/
+            # await ctx.send(files=[storage_service.upload(filepath) for filepath in latest_files])
+
+        except asyncio.timeouterror:
+            await ctx.send("the request took too long! it might have been censored or you're out of boosts. please try entering the prompt again.")
+        except Exception as e:
+            await ctx.send(f"an error occurred: {e}")
+
+    @commands.command()
+    async def send_text(self, ctx, *, text: str, use_agent: bool = True):
+        """sends the provided text to the worker and returns the response"""
+        if use_agent:
+            response = self.bot.agent.run(text)
+        else:
+            response = self.bot.llm(text)
+        await ctx.send(response)
+
+    @commands.Cog.listener()
+    async def on_ready(self):
+        print(f"we have logged in as {self.bot.user}")
+
+    @commands.Cog.listener()
+    async def on_command_error(self, ctx, error):
+        """handles errors that occur while executing commands."""
+        if isinstance(error, commands.CommandNotFound):
+            await ctx.send("that command does not exist!")
+        else:
+            await ctx.send(f"an error occurred: {error}")
 
 class Bot:
-    def __init__(self, agent, llm, command_prefix="!"):
+    def __init__(self, llm, command_prefix="!"):
         load_dotenv()
         
-        intents = discord.intents.default()
+        intents = discord.Intents.default()
         intents.messages = True
         intents.guilds = True
         intents.voice_states = True
@@ -19,119 +119,12 @@ class Bot:
 
         # setup
         self.llm = llm
-        self.agent = agent
-        self. bot = commands.bot(command_prefix="!", intents=intents)
+        self.bot = commands.Bot(command_prefix="!", intents=intents)
         self.discord_token = os.getenv("DISCORD_TOKEN")
         self.storage_service = os.getenv("STORAGE_SERVICE")
 
+        # Load the BotCommands cog
+        self.bot.add_cog(BotCommands(self.bot))
 
-        @self.bot.event
-        async def on_ready():
-            print(f"we have logged in as {self.bot.user}")
-
-
-        @self.bot.command()
-        async def greet(ctx):
-            """greets the user."""
-            await ctx.send(f"hello, {ctx.author.name}!")
-
-
-        @self.bot.command()
-        async def help_me(ctx):
-            """provides a list of commands and their descriptions."""
-            help_text = """
-            - `!greet`: greets you.
-            - `!run [description]`: generates a video based on the given description.
-            - `!help_me`: provides this list of commands and their descriptions.
-            """
-            await ctx.send(help_text)
-
-        @self.bot.event
-        async def on_command_error(ctx, error):
-            """handles errors that occur while executing commands."""
-            if isinstance(error, commands.commandnotfound):
-                await ctx.send("that command does not exist!")
-            else:
-                await ctx.send(f"an error occurred: {error}")
-
-        @self.bot.command()
-        async def join(ctx):
-            """joins the voice channel that the user is in."""
-            if ctx.author.voice:
-                channel = ctx.author.voice.channel
-                await channel.connect()
-            else:
-                await ctx.send("you are not in a voice channel!")
-
-        @self.bot.command()
-        async def leave(ctx):
-            """leaves the voice channel that the self.bot is in."""
-            if ctx.voice_client:
-                await ctx.voice_client.disconnect()
-            else:
-                await ctx.send("i am not in a voice channel!")
-
-        # voice_transcription.py
-        @self.bot.command()
-        async def listen(ctx):
-            """starts listening to voice in the voice channel that the bot is in."""
-            if ctx.voice_client:
-                # create a wavesink to record the audio
-                sink = discord.sinks.wavesink('audio.wav')
-                # start recording
-                ctx.voice_client.start_recording(sink)
-                await ctx.send("started listening and recording.")
-            else:
-                await ctx.send("i am not in a voice channel!")
-            
-        # image_generator.py
-        @self.bot.command()
-        async def generate_image(ctx, *, prompt: str = None, imggen: str = None):
-            """generates images based on the provided prompt"""
-            await ctx.send(f"generating images for prompt: `{prompt}`...")
-            loop = asyncio.get_event_loop()
-
-            # initialize a future object for the dalle instance
-            future = loop.run_in_executor(Executor, imggen, prompt)
-
-            try:
-                # wait for the dalle request to complete, with a timeout of 60 seconds
-                await asyncio.wait_for(future, timeout=300)
-                print("done generating images!")
-
-                # list all files in the save_directory
-                all_files = [os.path.join(root, file) for root, _, files in os.walk(os.environ("SAVE_DIRECTORY")) for file in files]
-
-                # sort files by their creation time (latest first)
-                sorted_files = sorted(all_files, key=os.path.getctime, reverse=True)
-
-                # get the 4 most recent files
-                latest_files = sorted_files[:4]
-                print(f"sending {len(latest_files)} images to discord...")
-
-                # send all the latest images in a single message
-                # storage_service = os.environ("STORAGE_SERVICE") # "https://storage.googleapis.com/your-bucket-name/
-                # await ctx.send(files=[storage_service.upload(filepath) for filepath in latest_files])
-
-            except asyncio.timeouterror:
-                await ctx.send("the request took too long! it might have been censored or you're out of boosts. please try entering the prompt again.")
-            except Exception as e:
-                await ctx.send(f"an error occurred: {e}")
-
-        @self.bot.command()
-        async def send_text(ctx, *, text: str, use_agent: bool = True):
-            """sends the provided text to the worker and returns the response"""
-            if use_agent:
-                response = self.agent.run(text)
-            else:
-                response = self.llm.__call__(text)
-            await ctx.send(response)
-        
-        def add_command(self, name, func):
-            @self.bot.command()
-            async def command(ctx, *args):
-                reponse = func(*args)
-                await ctx.send(responses)
-                
-def run(self) :
-    self.bot.run("DISCORD_TOKEN")
+    def run(self):
+        self.bot.run(self.discord_token)
diff --git a/playground/models/bingchat.py b/bingchat.py
similarity index 64%
rename from playground/models/bingchat.py
rename to bingchat.py
index 6e44cbb5..f4b91cd7 100644
--- a/playground/models/bingchat.py
+++ b/bingchat.py
@@ -10,10 +10,10 @@ cookie = os.environ.get("BING_COOKIE")
 auth = os.environ.get("AUTH_COOKIE")
 
 # Use the worker to process a task
-task = "hi"
-# img_task = "Sunset over mountains"
+# task = "hi"
+img_task = "Sunset over mountains"
 
-response = edgegpt(task)
-# response = edgegpt.create_img(auth_cookie=cookie,auth_cookie_SRCHHPGUSR=auth,prompt=img_task)
+# response = edgegpt(task)
+response = edgegpt.create_img(auth_cookie=cookie,auth_cookie_SRCHHPGUSR=auth,prompt=img_task)
 
 print(response)
diff --git a/playground/apps/bing_discord.py b/playground/apps/bing_discord.py
index fc179d1c..d35253ff 100644
--- a/playground/apps/bing_discord.py
+++ b/playground/apps/bing_discord.py
@@ -3,12 +3,13 @@ from swarms.models.bing_chat import BingChat
 from apps.discord import Bot
 from dotenv import load_dotenv
 
+load_dotenv()
 
 # Initialize the EdgeGPTModel
 cookie = os.environ.get("BING_COOKIE")
 auth = os.environ.get("AUTH_COOKIE")
-bing = BingChat(cookies_path="./cookies.txt", bing_cookie=cookie, auth_cookie=auth)
+bing = BingChat(cookies_path="./cookies.json")
 
-bot = Bot(llm=bing, cookie=cookie, auth=auth)
-bot.generate_image(imggen=bing.create_img())
+bot = Bot(llm=bing)
+bot.generate_image(imggen=bing.create_img(auth_cookie=cookie, auth_cookie_SRCHHPGUSR=auth))
 bot.send_text(use_agent=False)
diff --git a/swarms/models/bing_chat.py b/swarms/models/bing_chat.py
index cb90f97e..3ded87cd 100644
--- a/swarms/models/bing_chat.py
+++ b/swarms/models/bing_chat.py
@@ -58,7 +58,7 @@ class BingChat:
         images = image_generator.get_images(prompt)
         image_generator.save_images(images, output_dir=output_dir)
 
-        return Path(output_dir) / images[0]["path"]
+        return Path(output_dir) / images[0]
 
     @staticmethod
     def set_cookie_dir_path(path: str):