agoras-platforms 1.1.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agoras_platforms-1.1.6/PKG-INFO +109 -0
- agoras_platforms-1.1.6/README.rst +63 -0
- agoras_platforms-1.1.6/setup.cfg +4 -0
- agoras_platforms-1.1.6/setup.py +68 -0
- agoras_platforms-1.1.6/src/agoras/__init__.py +3 -0
- agoras_platforms-1.1.6/src/agoras/platforms/__init__.py +50 -0
- agoras_platforms-1.1.6/src/agoras/platforms/discord/__init__.py +3 -0
- agoras_platforms-1.1.6/src/agoras/platforms/discord/api.py +249 -0
- agoras_platforms-1.1.6/src/agoras/platforms/discord/auth.py +358 -0
- agoras_platforms-1.1.6/src/agoras/platforms/discord/client.py +389 -0
- agoras_platforms-1.1.6/src/agoras/platforms/discord/wrapper.py +340 -0
- agoras_platforms-1.1.6/src/agoras/platforms/facebook/__init__.py +27 -0
- agoras_platforms-1.1.6/src/agoras/platforms/facebook/api.py +366 -0
- agoras_platforms-1.1.6/src/agoras/platforms/facebook/auth.py +296 -0
- agoras_platforms-1.1.6/src/agoras/platforms/facebook/client.py +486 -0
- agoras_platforms-1.1.6/src/agoras/platforms/facebook/wrapper.py +583 -0
- agoras_platforms-1.1.6/src/agoras/platforms/instagram/__init__.py +3 -0
- agoras_platforms-1.1.6/src/agoras/platforms/instagram/api.py +276 -0
- agoras_platforms-1.1.6/src/agoras/platforms/instagram/auth.py +307 -0
- agoras_platforms-1.1.6/src/agoras/platforms/instagram/client.py +399 -0
- agoras_platforms-1.1.6/src/agoras/platforms/instagram/wrapper.py +408 -0
- agoras_platforms-1.1.6/src/agoras/platforms/linkedin/__init__.py +3 -0
- agoras_platforms-1.1.6/src/agoras/platforms/linkedin/api.py +314 -0
- agoras_platforms-1.1.6/src/agoras/platforms/linkedin/auth.py +286 -0
- agoras_platforms-1.1.6/src/agoras/platforms/linkedin/client.py +560 -0
- agoras_platforms-1.1.6/src/agoras/platforms/linkedin/wrapper.py +415 -0
- agoras_platforms-1.1.6/src/agoras/platforms/telegram/__init__.py +3 -0
- agoras_platforms-1.1.6/src/agoras/platforms/telegram/api.py +414 -0
- agoras_platforms-1.1.6/src/agoras/platforms/telegram/auth.py +303 -0
- agoras_platforms-1.1.6/src/agoras/platforms/telegram/client.py +298 -0
- agoras_platforms-1.1.6/src/agoras/platforms/telegram/wrapper.py +364 -0
- agoras_platforms-1.1.6/src/agoras/platforms/threads/__init__.py +3 -0
- agoras_platforms-1.1.6/src/agoras/platforms/threads/api.py +465 -0
- agoras_platforms-1.1.6/src/agoras/platforms/threads/auth.py +337 -0
- agoras_platforms-1.1.6/src/agoras/platforms/threads/client.py +316 -0
- agoras_platforms-1.1.6/src/agoras/platforms/threads/wrapper.py +372 -0
- agoras_platforms-1.1.6/src/agoras/platforms/tiktok/__init__.py +3 -0
- agoras_platforms-1.1.6/src/agoras/platforms/tiktok/api.py +339 -0
- agoras_platforms-1.1.6/src/agoras/platforms/tiktok/auth.py +311 -0
- agoras_platforms-1.1.6/src/agoras/platforms/tiktok/client.py +247 -0
- agoras_platforms-1.1.6/src/agoras/platforms/tiktok/wrapper.py +505 -0
- agoras_platforms-1.1.6/src/agoras/platforms/whatsapp/__init__.py +3 -0
- agoras_platforms-1.1.6/src/agoras/platforms/whatsapp/api.py +371 -0
- agoras_platforms-1.1.6/src/agoras/platforms/whatsapp/auth.py +267 -0
- agoras_platforms-1.1.6/src/agoras/platforms/whatsapp/client.py +322 -0
- agoras_platforms-1.1.6/src/agoras/platforms/whatsapp/wrapper.py +460 -0
- agoras_platforms-1.1.6/src/agoras/platforms/x/__init__.py +3 -0
- agoras_platforms-1.1.6/src/agoras/platforms/x/api.py +255 -0
- agoras_platforms-1.1.6/src/agoras/platforms/x/auth.py +261 -0
- agoras_platforms-1.1.6/src/agoras/platforms/x/client.py +324 -0
- agoras_platforms-1.1.6/src/agoras/platforms/x/wrapper.py +403 -0
- agoras_platforms-1.1.6/src/agoras/platforms/youtube/__init__.py +3 -0
- agoras_platforms-1.1.6/src/agoras/platforms/youtube/api.py +230 -0
- agoras_platforms-1.1.6/src/agoras/platforms/youtube/auth.py +248 -0
- agoras_platforms-1.1.6/src/agoras/platforms/youtube/client.py +357 -0
- agoras_platforms-1.1.6/src/agoras/platforms/youtube/wrapper.py +450 -0
- agoras_platforms-1.1.6/src/agoras_platforms.egg-info/PKG-INFO +109 -0
- agoras_platforms-1.1.6/src/agoras_platforms.egg-info/SOURCES.txt +91 -0
- agoras_platforms-1.1.6/src/agoras_platforms.egg-info/dependency_links.txt +1 -0
- agoras_platforms-1.1.6/src/agoras_platforms.egg-info/not-zip-safe +1 -0
- agoras_platforms-1.1.6/src/agoras_platforms.egg-info/requires.txt +15 -0
- agoras_platforms-1.1.6/src/agoras_platforms.egg-info/top_level.txt +1 -0
- agoras_platforms-1.1.6/tests/test_discord.py +539 -0
- agoras_platforms-1.1.6/tests/test_discord_api.py +143 -0
- agoras_platforms-1.1.6/tests/test_discord_client.py +564 -0
- agoras_platforms-1.1.6/tests/test_facebook.py +1306 -0
- agoras_platforms-1.1.6/tests/test_facebook_api.py +177 -0
- agoras_platforms-1.1.6/tests/test_facebook_client.py +483 -0
- agoras_platforms-1.1.6/tests/test_instagram.py +592 -0
- agoras_platforms-1.1.6/tests/test_instagram_api.py +152 -0
- agoras_platforms-1.1.6/tests/test_linkedin.py +267 -0
- agoras_platforms-1.1.6/tests/test_linkedin_api.py +175 -0
- agoras_platforms-1.1.6/tests/test_linkedin_client.py +636 -0
- agoras_platforms-1.1.6/tests/test_platforms.py +95 -0
- agoras_platforms-1.1.6/tests/test_telegram.py +179 -0
- agoras_platforms-1.1.6/tests/test_telegram_api.py +438 -0
- agoras_platforms-1.1.6/tests/test_telegram_client.py +727 -0
- agoras_platforms-1.1.6/tests/test_threads_api.py +276 -0
- agoras_platforms-1.1.6/tests/test_threads_auth.py +630 -0
- agoras_platforms-1.1.6/tests/test_threads_client.py +326 -0
- agoras_platforms-1.1.6/tests/test_threads_platform.py +278 -0
- agoras_platforms-1.1.6/tests/test_tiktok.py +671 -0
- agoras_platforms-1.1.6/tests/test_tiktok_api.py +275 -0
- agoras_platforms-1.1.6/tests/test_whatsapp.py +158 -0
- agoras_platforms-1.1.6/tests/test_whatsapp_api.py +325 -0
- agoras_platforms-1.1.6/tests/test_whatsapp_client.py +466 -0
- agoras_platforms-1.1.6/tests/test_wrapper_media_constraints.py +109 -0
- agoras_platforms-1.1.6/tests/test_x_api.py +176 -0
- agoras_platforms-1.1.6/tests/test_x_client.py +387 -0
- agoras_platforms-1.1.6/tests/test_x_platform.py +743 -0
- agoras_platforms-1.1.6/tests/test_youtube.py +672 -0
- agoras_platforms-1.1.6/tests/test_youtube_api.py +217 -0
- agoras_platforms-1.1.6/tests/test_youtube_client.py +400 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agoras-platforms
|
|
3
|
+
Version: 1.1.6
|
|
4
|
+
Summary: Platform-specific implementations for Agoras social networks
|
|
5
|
+
Home-page: https://github.com/LuisAlejandro/agoras
|
|
6
|
+
Author: Luis Alejandro Martínez Faneyth
|
|
7
|
+
Author-email: luis@luisalejandro.org
|
|
8
|
+
Keywords: social networks,twitter,facebook,instagram,linkedin,discord,youtube,tiktok,telegram,threads,whatsapp,x
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
12
|
+
Classifier: Natural Language :: English
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/x-rst
|
|
21
|
+
Requires-Dist: agoras-core>=2.0.0
|
|
22
|
+
Requires-Dist: tweepy==4.16.0
|
|
23
|
+
Requires-Dist: python-facebook-api==0.24.0
|
|
24
|
+
Requires-Dist: linkedin-api-client==0.3.0
|
|
25
|
+
Requires-Dist: discord.py==2.7.1
|
|
26
|
+
Requires-Dist: google-api-python-client==2.194.0
|
|
27
|
+
Requires-Dist: google-api-core>=2.0.0
|
|
28
|
+
Requires-Dist: google-auth==2.47.0
|
|
29
|
+
Requires-Dist: google-auth-oauthlib>=1.2.0
|
|
30
|
+
Requires-Dist: google-auth-httplib2==0.3.1
|
|
31
|
+
Requires-Dist: oauth2client==4.1.3
|
|
32
|
+
Requires-Dist: platformdirs==4.9.6
|
|
33
|
+
Requires-Dist: authlib==1.7.0
|
|
34
|
+
Requires-Dist: cryptography>=42.0.0
|
|
35
|
+
Requires-Dist: python-telegram-bot>=22.1
|
|
36
|
+
Dynamic: author
|
|
37
|
+
Dynamic: author-email
|
|
38
|
+
Dynamic: classifier
|
|
39
|
+
Dynamic: description
|
|
40
|
+
Dynamic: description-content-type
|
|
41
|
+
Dynamic: home-page
|
|
42
|
+
Dynamic: keywords
|
|
43
|
+
Dynamic: requires-dist
|
|
44
|
+
Dynamic: requires-python
|
|
45
|
+
Dynamic: summary
|
|
46
|
+
|
|
47
|
+
agoras-platforms
|
|
48
|
+
================
|
|
49
|
+
|
|
50
|
+
Platform-specific implementations for social networks.
|
|
51
|
+
|
|
52
|
+
Installation
|
|
53
|
+
------------
|
|
54
|
+
|
|
55
|
+
.. code-block:: bash
|
|
56
|
+
|
|
57
|
+
pip install agoras-platforms
|
|
58
|
+
|
|
59
|
+
Supported Platforms (10)
|
|
60
|
+
-------------------------
|
|
61
|
+
|
|
62
|
+
All platforms are fully extracted and functional:
|
|
63
|
+
|
|
64
|
+
- ✅ **Discord** - Gaming and community platform
|
|
65
|
+
- ✅ **Facebook** - Social network
|
|
66
|
+
- ✅ **Instagram** - Photo and video sharing
|
|
67
|
+
- ✅ **LinkedIn** - Professional network
|
|
68
|
+
- ✅ **Telegram** - Messaging platform
|
|
69
|
+
- ✅ **Threads** - Text-based conversations (Meta)
|
|
70
|
+
- ✅ **TikTok** - Short-form video
|
|
71
|
+
- ✅ **WhatsApp** - Messaging platform
|
|
72
|
+
- ✅ **X** - Social network (formerly Twitter)
|
|
73
|
+
- ✅ **YouTube** - Video platform
|
|
74
|
+
|
|
75
|
+
Usage
|
|
76
|
+
-----
|
|
77
|
+
|
|
78
|
+
.. code-block:: python
|
|
79
|
+
|
|
80
|
+
import asyncio
|
|
81
|
+
from agoras.platforms.facebook import Facebook
|
|
82
|
+
|
|
83
|
+
async def post_to_facebook():
|
|
84
|
+
fb = Facebook(facebook_access_token='...')
|
|
85
|
+
await fb._initialize_client()
|
|
86
|
+
try:
|
|
87
|
+
post_id = await fb.post(
|
|
88
|
+
status_text='Hello World',
|
|
89
|
+
status_link='https://example.com'
|
|
90
|
+
)
|
|
91
|
+
print(f'Posted: {post_id}')
|
|
92
|
+
finally:
|
|
93
|
+
await fb.disconnect()
|
|
94
|
+
|
|
95
|
+
asyncio.run(post_to_facebook())
|
|
96
|
+
|
|
97
|
+
Dependencies
|
|
98
|
+
------------
|
|
99
|
+
|
|
100
|
+
- agoras-core>=2.0.0
|
|
101
|
+
- Platform-specific SDKs:
|
|
102
|
+
|
|
103
|
+
- tweepy (X/Twitter)
|
|
104
|
+
- python-facebook-api (Facebook)
|
|
105
|
+
- linkedin-api-client (LinkedIn)
|
|
106
|
+
- discord.py (Discord)
|
|
107
|
+
- google-api-python-client (YouTube)
|
|
108
|
+
- python-telegram-bot (Telegram)
|
|
109
|
+
- And more...
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
agoras-platforms
|
|
2
|
+
================
|
|
3
|
+
|
|
4
|
+
Platform-specific implementations for social networks.
|
|
5
|
+
|
|
6
|
+
Installation
|
|
7
|
+
------------
|
|
8
|
+
|
|
9
|
+
.. code-block:: bash
|
|
10
|
+
|
|
11
|
+
pip install agoras-platforms
|
|
12
|
+
|
|
13
|
+
Supported Platforms (10)
|
|
14
|
+
-------------------------
|
|
15
|
+
|
|
16
|
+
All platforms are fully extracted and functional:
|
|
17
|
+
|
|
18
|
+
- ✅ **Discord** - Gaming and community platform
|
|
19
|
+
- ✅ **Facebook** - Social network
|
|
20
|
+
- ✅ **Instagram** - Photo and video sharing
|
|
21
|
+
- ✅ **LinkedIn** - Professional network
|
|
22
|
+
- ✅ **Telegram** - Messaging platform
|
|
23
|
+
- ✅ **Threads** - Text-based conversations (Meta)
|
|
24
|
+
- ✅ **TikTok** - Short-form video
|
|
25
|
+
- ✅ **WhatsApp** - Messaging platform
|
|
26
|
+
- ✅ **X** - Social network (formerly Twitter)
|
|
27
|
+
- ✅ **YouTube** - Video platform
|
|
28
|
+
|
|
29
|
+
Usage
|
|
30
|
+
-----
|
|
31
|
+
|
|
32
|
+
.. code-block:: python
|
|
33
|
+
|
|
34
|
+
import asyncio
|
|
35
|
+
from agoras.platforms.facebook import Facebook
|
|
36
|
+
|
|
37
|
+
async def post_to_facebook():
|
|
38
|
+
fb = Facebook(facebook_access_token='...')
|
|
39
|
+
await fb._initialize_client()
|
|
40
|
+
try:
|
|
41
|
+
post_id = await fb.post(
|
|
42
|
+
status_text='Hello World',
|
|
43
|
+
status_link='https://example.com'
|
|
44
|
+
)
|
|
45
|
+
print(f'Posted: {post_id}')
|
|
46
|
+
finally:
|
|
47
|
+
await fb.disconnect()
|
|
48
|
+
|
|
49
|
+
asyncio.run(post_to_facebook())
|
|
50
|
+
|
|
51
|
+
Dependencies
|
|
52
|
+
------------
|
|
53
|
+
|
|
54
|
+
- agoras-core>=2.0.0
|
|
55
|
+
- Platform-specific SDKs:
|
|
56
|
+
|
|
57
|
+
- tweepy (X/Twitter)
|
|
58
|
+
- python-facebook-api (Facebook)
|
|
59
|
+
- linkedin-api-client (LinkedIn)
|
|
60
|
+
- discord.py (Discord)
|
|
61
|
+
- google-api-python-client (YouTube)
|
|
62
|
+
- python-telegram-bot (Telegram)
|
|
63
|
+
- And more...
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
#
|
|
4
|
+
# Please refer to AUTHORS.rst for a complete list of Copyright holders.
|
|
5
|
+
# Copyright (C) 2022-2026, Agoras Developers.
|
|
6
|
+
|
|
7
|
+
# This program is free software: you can redistribute it and/or modify
|
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
# (at your option) any later version.
|
|
11
|
+
|
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
# GNU General Public License for more details.
|
|
16
|
+
|
|
17
|
+
# You should have received a copy of the GNU General Public License
|
|
18
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
19
|
+
|
|
20
|
+
from setuptools import find_namespace_packages, setup
|
|
21
|
+
|
|
22
|
+
setup(
|
|
23
|
+
name='agoras-platforms',
|
|
24
|
+
version='1.1.6',
|
|
25
|
+
author='Luis Alejandro Martínez Faneyth',
|
|
26
|
+
author_email='luis@luisalejandro.org',
|
|
27
|
+
url='https://github.com/LuisAlejandro/agoras',
|
|
28
|
+
description='Platform-specific implementations for Agoras social networks',
|
|
29
|
+
long_description=open('README.rst').read(),
|
|
30
|
+
long_description_content_type='text/x-rst',
|
|
31
|
+
packages=find_namespace_packages(where='src'),
|
|
32
|
+
package_dir={'': 'src'},
|
|
33
|
+
python_requires='>=3.10',
|
|
34
|
+
install_requires=[
|
|
35
|
+
'agoras-core>=2.0.0',
|
|
36
|
+
'tweepy==4.16.0',
|
|
37
|
+
'python-facebook-api==0.24.0',
|
|
38
|
+
'linkedin-api-client==0.3.0',
|
|
39
|
+
'discord.py==2.7.1',
|
|
40
|
+
'google-api-python-client==2.194.0',
|
|
41
|
+
'google-api-core>=2.0.0',
|
|
42
|
+
'google-auth==2.47.0',
|
|
43
|
+
'google-auth-oauthlib>=1.2.0',
|
|
44
|
+
'google-auth-httplib2==0.3.1',
|
|
45
|
+
'oauth2client==4.1.3',
|
|
46
|
+
'platformdirs==4.9.6',
|
|
47
|
+
'authlib==1.7.0',
|
|
48
|
+
'cryptography>=42.0.0',
|
|
49
|
+
'python-telegram-bot>=22.1',
|
|
50
|
+
],
|
|
51
|
+
classifiers=[
|
|
52
|
+
'Development Status :: 5 - Production/Stable',
|
|
53
|
+
'Intended Audience :: Developers',
|
|
54
|
+
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
|
|
55
|
+
'Natural Language :: English',
|
|
56
|
+
'Programming Language :: Python :: 3',
|
|
57
|
+
'Programming Language :: Python :: 3.10',
|
|
58
|
+
'Programming Language :: Python :: 3.11',
|
|
59
|
+
'Programming Language :: Python :: 3.12',
|
|
60
|
+
'Programming Language :: Python :: 3.13',
|
|
61
|
+
'Programming Language :: Python :: 3.14',
|
|
62
|
+
],
|
|
63
|
+
keywords=[
|
|
64
|
+
'social networks', 'twitter', 'facebook', 'instagram', 'linkedin',
|
|
65
|
+
'discord', 'youtube', 'tiktok', 'telegram', 'threads', 'whatsapp', 'x'
|
|
66
|
+
],
|
|
67
|
+
zip_safe=False,
|
|
68
|
+
)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Please refer to AUTHORS.rst for a complete list of Copyright holders.
|
|
4
|
+
# Copyright (C) 2022-2026, Agoras Developers.
|
|
5
|
+
|
|
6
|
+
# This program is free software: you can redistribute it and/or modify
|
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
# (at your option) any later version.
|
|
10
|
+
|
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU General Public License for more details.
|
|
15
|
+
|
|
16
|
+
# You should have received a copy of the GNU General Public License
|
|
17
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
18
|
+
"""
|
|
19
|
+
agoras.platforms
|
|
20
|
+
================
|
|
21
|
+
|
|
22
|
+
Platform-specific implementations for social networks.
|
|
23
|
+
|
|
24
|
+
This package provides concrete implementations of the SocialNetwork interface
|
|
25
|
+
for 10 social media platforms.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from .discord import Discord
|
|
29
|
+
from .facebook import Facebook
|
|
30
|
+
from .instagram import Instagram
|
|
31
|
+
from .linkedin import LinkedIn
|
|
32
|
+
from .telegram import Telegram
|
|
33
|
+
from .threads import Threads
|
|
34
|
+
from .tiktok import TikTok
|
|
35
|
+
from .whatsapp import WhatsApp
|
|
36
|
+
from .x import X
|
|
37
|
+
from .youtube import YouTube
|
|
38
|
+
|
|
39
|
+
__all__ = [
|
|
40
|
+
'Discord',
|
|
41
|
+
'Facebook',
|
|
42
|
+
'Instagram',
|
|
43
|
+
'LinkedIn',
|
|
44
|
+
'Telegram',
|
|
45
|
+
'Threads',
|
|
46
|
+
'TikTok',
|
|
47
|
+
'WhatsApp',
|
|
48
|
+
'X',
|
|
49
|
+
'YouTube',
|
|
50
|
+
]
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Please refer to AUTHORS.md for a complete list of Copyright holders.
|
|
4
|
+
# Copyright (C) 2022-2026, Agoras Developers.
|
|
5
|
+
|
|
6
|
+
# This program is free software: you can redistribute it and/or modify
|
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
# (at your option) any later version.
|
|
10
|
+
|
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU General Public License for more details.
|
|
15
|
+
|
|
16
|
+
# You should have received a copy of the GNU General Public License
|
|
17
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
18
|
+
|
|
19
|
+
from agoras.core.api_base import BaseAPI
|
|
20
|
+
|
|
21
|
+
from .auth import DiscordAuthManager
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class DiscordAPI(BaseAPI):
|
|
25
|
+
"""
|
|
26
|
+
Discord API handler that centralizes Discord operations.
|
|
27
|
+
|
|
28
|
+
Provides methods for Discord authentication, server/channel management,
|
|
29
|
+
message operations, and file uploads.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, bot_token, server_name, channel_name):
|
|
33
|
+
"""
|
|
34
|
+
Initialize Discord API instance.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
bot_token (str): Discord bot token
|
|
38
|
+
server_name (str): Discord server name
|
|
39
|
+
channel_name (str): Discord channel name
|
|
40
|
+
"""
|
|
41
|
+
super().__init__(
|
|
42
|
+
bot_token=bot_token,
|
|
43
|
+
server_name=server_name,
|
|
44
|
+
channel_name=channel_name
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# Initialize the authentication manager
|
|
48
|
+
self.auth_manager = DiscordAuthManager(
|
|
49
|
+
bot_token=bot_token,
|
|
50
|
+
server_name=server_name,
|
|
51
|
+
channel_name=channel_name
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def bot_token(self):
|
|
56
|
+
"""Get the Discord bot token from the auth manager."""
|
|
57
|
+
return self.auth_manager.bot_token if self.auth_manager else None
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def server_name(self):
|
|
61
|
+
"""Get the Discord server name from the auth manager."""
|
|
62
|
+
return self.auth_manager.server_name if self.auth_manager else None
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def channel_name(self):
|
|
66
|
+
"""Get the Discord channel name from the auth manager."""
|
|
67
|
+
return self.auth_manager.channel_name if self.auth_manager else None
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def user_info(self):
|
|
71
|
+
"""Get the Discord user info from the auth manager."""
|
|
72
|
+
return self.auth_manager.user_info if self.auth_manager else None
|
|
73
|
+
|
|
74
|
+
async def authenticate(self):
|
|
75
|
+
"""
|
|
76
|
+
Authenticate with Discord API using the auth manager and client.
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
DiscordAPI: Self for method chaining
|
|
80
|
+
|
|
81
|
+
Raises:
|
|
82
|
+
Exception: If authentication fails
|
|
83
|
+
"""
|
|
84
|
+
if self._authenticated:
|
|
85
|
+
return self
|
|
86
|
+
|
|
87
|
+
# Authenticate with auth manager (this creates and sets up the client)
|
|
88
|
+
auth_success = await self.auth_manager.authenticate()
|
|
89
|
+
if not auth_success:
|
|
90
|
+
error_msg = 'Discord authentication failed'
|
|
91
|
+
if hasattr(self.auth_manager, '_last_error') and self.auth_manager._last_error:
|
|
92
|
+
error_msg += f': {self.auth_manager._last_error}'
|
|
93
|
+
raise Exception(error_msg)
|
|
94
|
+
|
|
95
|
+
# Ensure client was created during authentication
|
|
96
|
+
if not self.auth_manager.client:
|
|
97
|
+
raise Exception('Discord client not available after authentication')
|
|
98
|
+
|
|
99
|
+
self.client = self.auth_manager.client
|
|
100
|
+
self._authenticated = True
|
|
101
|
+
return self
|
|
102
|
+
|
|
103
|
+
async def disconnect(self):
|
|
104
|
+
"""
|
|
105
|
+
Disconnect from Discord API and clean up resources.
|
|
106
|
+
"""
|
|
107
|
+
# Disconnect the client first
|
|
108
|
+
if self.client:
|
|
109
|
+
self.client.disconnect()
|
|
110
|
+
|
|
111
|
+
# Clear auth manager data
|
|
112
|
+
if self.auth_manager:
|
|
113
|
+
self.auth_manager.access_token = None
|
|
114
|
+
|
|
115
|
+
# Clear BaseAPI client
|
|
116
|
+
self.client = None
|
|
117
|
+
self._authenticated = False
|
|
118
|
+
|
|
119
|
+
async def post(self, content=None, embeds=None, file=None):
|
|
120
|
+
"""
|
|
121
|
+
Post a message to the configured Discord channel.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
content (str, optional): Text content of the message
|
|
125
|
+
embeds (list, optional): List of Discord embeds
|
|
126
|
+
file (discord.File, optional): File to attach
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
str: Message ID
|
|
130
|
+
|
|
131
|
+
Raises:
|
|
132
|
+
Exception: If message posting fails
|
|
133
|
+
"""
|
|
134
|
+
if not self._authenticated:
|
|
135
|
+
await self.authenticate()
|
|
136
|
+
|
|
137
|
+
if not self.client:
|
|
138
|
+
raise Exception('Discord client not available')
|
|
139
|
+
|
|
140
|
+
await self._rate_limit_check('post', 1.0)
|
|
141
|
+
return await self.client.send_message(content=content, embeds=embeds, file=file)
|
|
142
|
+
|
|
143
|
+
async def like(self, message_id, emoji='❤️'):
|
|
144
|
+
"""
|
|
145
|
+
Add a reaction (like) to a Discord message.
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
message_id (str): ID of the message to react to
|
|
149
|
+
emoji (str): Emoji to react with
|
|
150
|
+
|
|
151
|
+
Returns:
|
|
152
|
+
str: Message ID
|
|
153
|
+
|
|
154
|
+
Raises:
|
|
155
|
+
Exception: If reaction fails
|
|
156
|
+
"""
|
|
157
|
+
if not self._authenticated:
|
|
158
|
+
await self.authenticate()
|
|
159
|
+
|
|
160
|
+
if not self.client:
|
|
161
|
+
raise Exception('Discord client not available')
|
|
162
|
+
|
|
163
|
+
await self._rate_limit_check('like', 0.5)
|
|
164
|
+
return await self.client.add_reaction(message_id, emoji)
|
|
165
|
+
|
|
166
|
+
async def delete(self, message_id):
|
|
167
|
+
"""
|
|
168
|
+
Delete a Discord message.
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
message_id (str): ID of the message to delete
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
str: Message ID
|
|
175
|
+
|
|
176
|
+
Raises:
|
|
177
|
+
Exception: If deletion fails
|
|
178
|
+
"""
|
|
179
|
+
if not self._authenticated:
|
|
180
|
+
await self.authenticate()
|
|
181
|
+
|
|
182
|
+
if not self.client:
|
|
183
|
+
raise Exception('Discord client not available')
|
|
184
|
+
|
|
185
|
+
await self._rate_limit_check('delete', 0.5)
|
|
186
|
+
return await self.client.delete_message(message_id)
|
|
187
|
+
|
|
188
|
+
async def upload_file(self, file_content, filename, content=None, embeds=None):
|
|
189
|
+
"""
|
|
190
|
+
Upload a file to Discord.
|
|
191
|
+
|
|
192
|
+
Args:
|
|
193
|
+
file_content: File-like object or bytes
|
|
194
|
+
filename (str): Name of the file
|
|
195
|
+
content (str, optional): Message content to accompany file
|
|
196
|
+
embeds (list, optional): Embeds to include with file
|
|
197
|
+
|
|
198
|
+
Returns:
|
|
199
|
+
str: Message ID
|
|
200
|
+
|
|
201
|
+
Raises:
|
|
202
|
+
Exception: If file upload fails
|
|
203
|
+
"""
|
|
204
|
+
if not self._authenticated:
|
|
205
|
+
await self.authenticate()
|
|
206
|
+
|
|
207
|
+
if not self.client:
|
|
208
|
+
raise Exception('Discord client not available')
|
|
209
|
+
|
|
210
|
+
await self._rate_limit_check('upload_file', 1.0)
|
|
211
|
+
return await self.client.upload_file(file_content, filename, content, embeds)
|
|
212
|
+
|
|
213
|
+
async def share(self, message_id):
|
|
214
|
+
"""
|
|
215
|
+
Share is not supported for Discord.
|
|
216
|
+
|
|
217
|
+
Args:
|
|
218
|
+
message_id (str): ID of the message
|
|
219
|
+
|
|
220
|
+
Raises:
|
|
221
|
+
Exception: Share not supported for Discord
|
|
222
|
+
"""
|
|
223
|
+
raise Exception('Share not supported for Discord')
|
|
224
|
+
|
|
225
|
+
def create_embed(self, title=None, description=None, url=None,
|
|
226
|
+
embed_type='rich', image_url=None):
|
|
227
|
+
"""
|
|
228
|
+
Create a Discord embed object.
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
title (str, optional): Embed title
|
|
232
|
+
description (str, optional): Embed description
|
|
233
|
+
url (str, optional): Embed URL
|
|
234
|
+
embed_type (str): Embed type (default: 'rich')
|
|
235
|
+
image_url (str, optional): Image URL for embed
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
discord.Embed: Discord embed object
|
|
239
|
+
"""
|
|
240
|
+
if not self.client:
|
|
241
|
+
raise Exception('Discord client not available')
|
|
242
|
+
|
|
243
|
+
return self.client.create_embed(
|
|
244
|
+
title=title,
|
|
245
|
+
description=description,
|
|
246
|
+
url=url,
|
|
247
|
+
embed_type=embed_type,
|
|
248
|
+
image_url=image_url
|
|
249
|
+
)
|