-
Notifications
You must be signed in to change notification settings - Fork 734
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add Discord OAuth Flow #1129
Conversation
…threads and responding with the chat history features
Thanks @AveryYay , I will review the code and assist you in completing the PR integration |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @AveryYay , good code! left some comments below.
And in terms of functionality, I hope you refer to camel.bots.slack.slack_app.py
and integrate the oauth process into camel.bots.discord.discord_app.py
(you can create camel.bots.discord
to store module content)
Co-authored-by: koch3092 <108793340+koch3092@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks @AveryYay , left some comments below.
camel/bots/discord/discord_app.py
Outdated
|
||
user_data = await self.oauth_client.get_user_info(access_token) | ||
logger.info(f"User data: {user_data}") | ||
await self.shutdown_oauth_server() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
await self.shutdown_oauth_server() |
Server is a long-term service, so it's better to let users manually shut it down
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Example can be combined with the usage of chat_agent
to integrate existing historical records into the memory
of chat_agent
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @AveryYay ! Overall LGTM, left some comments below, It would be better if we could also add docstring for DiscordOAuth
BTW, you can run pre-commit run --all-files
before the push to ensure the code pass pre-commit check
camel/bots/discord/discord_app.py
Outdated
token: Optional[str] = None, | ||
client_id: Optional[str] = None, | ||
client_secret: Optional[str] = None, | ||
redirect_uri: str = "http://localhost:8000/callback", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use REDIRECT_URI
instead?
camel/bots/discord/discord_app.py
Outdated
response = await client.post(TOKEN_URL, data=data, headers=headers) | ||
response_data = response.json() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
before fetch the data, check the status code first like below?
if response.status_code != 200:
logger.error("Failed to exchange code for token)
return None
camel/bots/discord/discord_app.py
Outdated
user_response = await client.get(USER_URL, headers=headers) | ||
return user_response.json() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
camel/bots/discord/discord_app.py
Outdated
self.server.should_exit = True | ||
logger.info("Shutting down the OAuth server.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we add await here to make sure the server is fully stopped?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @AveryYay , left some comments below
camel/bots/discord/discord_app.py
Outdated
@@ -53,6 +62,9 @@ def __init__( | |||
token (Optional[str]): The Discord bot token for authentication. | |||
If not provided, the token will be retrieved from the | |||
environment variable `DISCORD_TOKEN`. | |||
client_id (Optional[str]): The client ID for Discord OAuth. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as other variables
client_id (Optional[str]): The client ID for Discord OAuth. | |
client_id (Optional[str]): The client ID for Discord OAuth. (default: :obj:`None`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
client_id (Optional[str]): The client ID for Discord OAuth. | |
client_id (str, optional): The client ID for Discord OAuth. (default: :obj:`None`) |
camel/bots/discord/discord_app.py
Outdated
if not all([client_id, client_secret]): | ||
raise ValueError( | ||
"DISCORD_CLIENT_ID and DISCORD_CLIENT_SECRET must be set " | ||
"for OAuth." | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from camel.utils import api_keys_required
use @api_keys_required
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These aren't actually api keys, do I still use @api_keys_required
?
camel/bots/discord/discord_app.py
Outdated
r"""Generate an OAuth URL to invite the bot to a Discord server. | ||
|
||
This method returns a link that allows users to invite the bot to | ||
their Discord server with specific permissions. | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
including args and returns in docstring
- Added DiscordAsyncInstallationStore to manage installations (using list right now, need to switch to database or file instead) - Added DiscordInstallation entity class - Implemented relevant functions in DiscordApp
…rdInstallation abd DiscordAsyncInstallationStore to __init__.py
Hi @Wendong-Fan and @AveryYay, the current implementation of What are your thoughts on this approach? 😊 |
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @AveryYay , left some comments below
camel/bots/discord/discord_app.py
Outdated
" here: `https://discord.com/developers/applications`." | ||
) | ||
|
||
intents = discord.Intents.default() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add an intents
parameter so that users can set their own bot permissions
camel/bots/discord/discord_app.py
Outdated
r"""Retrieve user information using the access token. | ||
Args: | ||
access_token (str): The access token received from Discord. | ||
Returns: | ||
dict: The user information retrieved from Discord. | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
r"""Retrieve user information using the access token. | |
Args: | |
access_token (str): The access token received from Discord. | |
Returns: | |
dict: The user information retrieved from Discord. | |
""" | |
r"""Retrieve user information using the access token. | |
Args: | |
access_token (str): The access token received from Discord. | |
Returns: | |
dict: The user information retrieved from Discord. | |
""" |
camel/bots/discord/discord_app.py
Outdated
|
||
Returns: | ||
None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returns: | |
None |
camel/bots/discord/discord_app.py
Outdated
|
||
Returns: | ||
None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returns: | |
None |
We are currently using |
# Conflicts: # poetry.lock
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @AveryYay , left some comments below
camel/bots/__init__.py
Outdated
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please check and clean the license info
camel/bots/discord/__init__.py
Outdated
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. =========== | ||
# Licensed under the Apache License, Version 2.0 (the “License”); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clean
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. =========== | ||
# Licensed under the Apache License, Version 2.0 (the “License”); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an “AS IS” BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. =========== |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clean
camel/bots/discord_app.py
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this file need to be deleted
class DiscordInstallation: | ||
def __init__( | ||
self, | ||
guild_id: str, | ||
access_token: str, | ||
refresh_token: str, | ||
installed_at: datetime, | ||
token_expires_at: Optional[datetime] = None, | ||
): | ||
self.guild_id = guild_id | ||
self.access_token = access_token | ||
self.refresh_token = refresh_token | ||
self.installed_at = installed_at | ||
self.token_expires_at = token_expires_at |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add docstring
camel/bots/discord/discord_app.py
Outdated
logging.basicConfig(level=logging.INFO) | ||
logger = logging.getLogger(__name__) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use our own logger
from camel.logger import get_logger
logger = get_logger(__name__)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @AveryYay LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please resolve the conflict with master branch
# Conflicts: # poetry.lock # pyproject.toml
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but there are a few small points that could be improved.
return None | ||
headers = {"Authorization": f"Bearer {access_token}"} | ||
async with httpx.AsyncClient() as client: | ||
user_response = await client.get(USER_URL, headers=headers) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error handling should be implemented here.
"client_secret, or redirect_uri." | ||
) | ||
return None | ||
assert self.installation_store is not None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to raise an error here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a check before this that already checks self.installation_store is not None, this assertion here is just for it to pass pre commit.
"client_secret, or redirect_uri." | ||
) | ||
return None | ||
assert self.installation_store is not None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to raise an error here.
"client_secret, or redirect_uri." | ||
) | ||
return None | ||
assert self.installation_store is not None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to raise an error here.
hey @AveryYay @liuxukun2000 @koch3092 , I think there's some error in cicd was not fixed but this PR was approved and merged. current error message in master branch:
I will do a hot fix, please pay more attention to the cicd check next time~ |
Sorry about this and thank you for the fix! I thought it was one of the certification issue I encountered since I forked the repo😭 |
No worries~ |
Description
This PR introduces discord OAuth flow: Implements a Discord OAuth flow which allows users to authenticate with Discord, managing the entire OAuth process from generating the authorization URL, handling the authorization code exchange, to retrieving basic user information and an installation store to manage multi server installation.
Motivation and Context
Enables secure user authentication via Discord OAuth, enhancing the bot’s integration with Discord’s authentication system. And supports multi server management.
Types of changes
What types of changes does your code introduce? Put an
x
in all the boxes that apply:Implemented Tasks
Checklist
Go over all the following points, and put an
x
in all the boxes that apply.If you are unsure about any of these, don't hesitate to ask. We are here to help!