Latest commit

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

CommunityOne SDK

PyPI versionPython versions

Official Python SDK for interacting with the CommunityOne API. This SDK provides both synchronous and asynchronous methods to interact with CommunityOne's API endpoints.

About CommunityOne

CommunityOne is a platform that helps Discord communities grow and engage their members through quests, rewards, and gamification.

Installation

You can install the package using pip:

pip install communityone

Quick Start

fromcommunityoneimportCommunityOneSDK# Initialize the SDK with your server ID and API keysdk=CommunityOneSDK(server_id=YOUR_SERVER_ID, api_key="YOUR_API_KEY")
# Get all custom questscustom_quests=sdk.get_custom_quests()
# Get player informationplayer_info=sdk.get_player_info(discord_user_id="DISCORD_USER_ID")
# Complete a custom questresult=sdk.complete_custom_quest(custom_quest_id="CUSTOM_QUEST_ID", discord_user_id="DISCORD_USER_ID")
# Get completed members for a questcompleted_members=sdk.get_completed_members(custom_quest_id="CUSTOM_QUEST_ID")
# Get global leaderboardleaderboard=sdk.get_global_leaderboard()
# Check whether members were flagged as suspicious accountssuspicious=sdk.check_suspicious_accounts(user_ids=["DISCORD_USER_ID"])
# Get activity insights for membersinsights=sdk.get_member_insights(user_ids=["DISCORD_USER_ID"])
# Get the outcomes recorded for an invite codeoutcomes=sdk.get_invite_outcomes(invite_code="INVITE_CODE")

Async Support

The SDK also provides async methods for all operations:

importasynciofromcommunityoneimportCommunityOneSDKasyncdefmain():
sdk=CommunityOneSDK(server_id=YOUR_SERVER_ID, api_key="YOUR_API_KEY")
# Get custom quests asynchronouslycustom_quests=awaitsdk.get_custom_quests_async()
# Get player information asynchronouslyplayer_info=awaitsdk.get_player_info_async("DISCORD_USER_ID")
# Complete a custom quest asynchronouslyresult=awaitsdk.complete_custom_quest_async(custom_quest_id="CUSTOM_QUEST_ID", discord_user_id="DISCORD_USER_ID")
# Get completed members asynchronouslycompleted_members=awaitsdk.get_completed_members_async(custom_quest_id="CUSTOM_QUEST_ID")
# Get global leaderboard asynchronouslyleaderboard=awaitsdk.get_global_leaderboard_async()
# Check suspicious accounts asynchronouslysuspicious=awaitsdk.check_suspicious_accounts_async(user_ids=["DISCORD_USER_ID"])
# Get member insights asynchronouslyinsights=awaitsdk.get_member_insights_async(user_ids=["DISCORD_USER_ID"])
# Get invite outcomes asynchronouslyoutcomes=awaitsdk.get_invite_outcomes_async(invite_code="INVITE_CODE")
# Run the async codeasyncio.run(main())

Available Methods

Synchronous Methods

  • get_custom_quests(): Get all custom quests for the server
  • get_player_info(discord_user_id): Get information about a player
  • complete_custom_quest(custom_quest_id, discord_user_id): Mark a custom quest as completed
  • get_completed_members(custom_quest_id): Get all members who completed a quest
  • get_global_leaderboard(): Get global leaderboard for the server
  • check_suspicious_accounts(user_ids): Check whether members were flagged as suspicious accounts
  • get_member_insights(user_ids): Get activity insights for members
  • get_invite_outcomes(invite_code): Get the outcomes recorded for an invite code

Asynchronous Methods

  • get_custom_quests_async(): Get all custom quests for the server asynchronously
  • get_player_info_async(discord_user_id): Get player information asynchronously
  • complete_custom_quest_async(custom_quest_id, discord_user_id): Complete a quest asynchronously
  • get_completed_members_async(custom_quest_id): Get completed members asynchronously
  • get_global_leaderboard_async(): Get global leaderboard asynchronously
  • check_suspicious_accounts_async(user_ids): Check suspicious accounts asynchronously
  • get_member_insights_async(user_ids): Get member insights asynchronously
  • get_invite_outcomes_async(invite_code): Get invite outcomes asynchronously

Analytics

The analytics methods return point-in-time data and require the server to be on the Analytics Premium Level 3 tier. Servers on any other tier get a 403.

Suspicious accounts

check_suspicious_accounts(user_ids) accepts between 1 and 100 Discord user IDs and returns one result per requested ID, in the same order as the request. Requesting more or fewer IDs raises a ValueError before the request is sent.

suspicious=sdk.check_suspicious_accounts(user_ids=["1273073873503522888", "851179040428654623"])
forresultinsuspicious["results"]:
ifresult["flagged"]:
print(result["user_id"], result["flagged_reason"], result["join_date"])

A user ID with no suspicious activity is clean, not unknown: it comes back with flagged set to False and every other field set to None. flagged_reason is an open string (currently GROUP_JOIN, JOIN_RIGHT_AFTER_CREATION, RANDOM_USERNAME or SCAMLIKE_CHAT) that may gain new values, and it can be None even when flagged is True.

Member insights

get_member_insights(user_ids) takes the same 1-100 user IDs and returns per-member activity data such as msg_count, days_present, wpm and most_active_channel_name.

insights=sdk.get_member_insights(user_ids=["1273073873503522888"])
forresultininsights["results"]:
ifresult["found"]:
print(result["username"], result["msg_count"], result["most_active_channel_name"])

Here absence genuinely means "no data available", so check found rather than assuming a member is inactive. Requesting unknown IDs is not an error. member_type (MODERATOR or REGULAR_MEMBER) is also an open string.

Invite outcomes

get_invite_outcomes(invite_code) returns the outcomes for a single invite code as a flat object. The invite code is URL-encoded for you.

outcomes=sdk.get_invite_outcomes(invite_code="abcd1234")
print(outcomes["total_users"], outcomes["total_suspicious_users"])

An invite code with no recorded outcomes returns a 404, which surfaces as the usual requests.HTTPError (or aiohttp.ClientResponseError for the async method). This is an expected outcome rather than a fault, so handle it explicitly if you may query codes that were never used:

importrequeststry:
outcomes=sdk.get_invite_outcomes(invite_code="abcd1234")
exceptrequests.HTTPErroraserror:
iferror.response.status_code==404:
outcomes=Noneelse:
raise

Invite codes are only unique within a server, since a released vanity code can later be claimed by a different server, so scope any cached results by server ID.

Discord IDs

Discord IDs are sent and returned as strings to avoid precision loss. int values are accepted and coerced with str(). The user_id echoed back in a response is numerically normalized, so an input of "0007" returns as "7" — match results to inputs by array position, or normalize your inputs first.

Testing Mode

CommunityOne allows you to test the full quest completion workflow in your application without affecting production quests data, helping you verify quest functionality before releasing it to your community. When a quest is in testing mode:

  • The quest won't be visible to regular Discord server members
  • No code changes needed! - use the same SDK methods for testing and production quests (the API automatically routes to our internal test environment)

How to enable:

  1. Go to your server's CommunityOne dashboard
  2. Navigate to Hype Engine > Custom Quests
  3. Click the Edit button on your quest
  4. Enable testing mode

Rate Limiting

All API endpoints are subject to rate limiting:

  • 60 requests per minute per server for the quest and leaderboard endpoints
  • 120 requests per minute per server for the analytics endpoints
  • Rate limits are applied separately for each endpoint
  • Exceeding the rate limit will result in a 429 Too Many Requests response

Requirements

  • Python 3.7 or higher
  • requests>=2.25.0
  • aiohttp>=3.8.0

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

CommunityOne SDK

PyPI versionPython versions

Official Python SDK for interacting with the CommunityOne API. This SDK provides both synchronous and asynchronous methods to interact with CommunityOne's API endpoints.

About CommunityOne

CommunityOne is a platform that helps Discord communities grow and engage their members through quests, rewards, and gamification.

Installation

You can install the package using pip:

pip install communityone

Quick Start

fromcommunityoneimportCommunityOneSDK# Initialize the SDK with your server ID and API keysdk=CommunityOneSDK(server_id=YOUR_SERVER_ID, api_key="YOUR_API_KEY")
# Get all custom questscustom_quests=sdk.get_custom_quests()
# Get player informationplayer_info=sdk.get_player_info(discord_user_id="DISCORD_USER_ID")
# Complete a custom questresult=sdk.complete_custom_quest(custom_quest_id="CUSTOM_QUEST_ID", discord_user_id="DISCORD_USER_ID")
# Get completed members for a questcompleted_members=sdk.get_completed_members(custom_quest_id="CUSTOM_QUEST_ID")
# Get global leaderboardleaderboard=sdk.get_global_leaderboard()
# Check whether members were flagged as suspicious accountssuspicious=sdk.check_suspicious_accounts(user_ids=["DISCORD_USER_ID"])
# Get activity insights for membersinsights=sdk.get_member_insights(user_ids=["DISCORD_USER_ID"])
# Get the outcomes recorded for an invite codeoutcomes=sdk.get_invite_outcomes(invite_code="INVITE_CODE")

Async Support

The SDK also provides async methods for all operations:

importasynciofromcommunityoneimportCommunityOneSDKasyncdefmain():
sdk=CommunityOneSDK(server_id=YOUR_SERVER_ID, api_key="YOUR_API_KEY")
# Get custom quests asynchronouslycustom_quests=awaitsdk.get_custom_quests_async()
# Get player information asynchronouslyplayer_info=awaitsdk.get_player_info_async("DISCORD_USER_ID")
# Complete a custom quest asynchronouslyresult=awaitsdk.complete_custom_quest_async(custom_quest_id="CUSTOM_QUEST_ID", discord_user_id="DISCORD_USER_ID")
# Get completed members asynchronouslycompleted_members=awaitsdk.get_completed_members_async(custom_quest_id="CUSTOM_QUEST_ID")
# Get global leaderboard asynchronouslyleaderboard=awaitsdk.get_global_leaderboard_async()
# Check suspicious accounts asynchronouslysuspicious=awaitsdk.check_suspicious_accounts_async(user_ids=["DISCORD_USER_ID"])
# Get member insights asynchronouslyinsights=awaitsdk.get_member_insights_async(user_ids=["DISCORD_USER_ID"])
# Get invite outcomes asynchronouslyoutcomes=awaitsdk.get_invite_outcomes_async(invite_code="INVITE_CODE")
# Run the async codeasyncio.run(main())

Available Methods

Synchronous Methods

  • get_custom_quests(): Get all custom quests for the server
  • get_player_info(discord_user_id): Get information about a player
  • complete_custom_quest(custom_quest_id, discord_user_id): Mark a custom quest as completed
  • get_completed_members(custom_quest_id): Get all members who completed a quest
  • get_global_leaderboard(): Get global leaderboard for the server
  • check_suspicious_accounts(user_ids): Check whether members were flagged as suspicious accounts
  • get_member_insights(user_ids): Get activity insights for members
  • get_invite_outcomes(invite_code): Get the outcomes recorded for an invite code

Asynchronous Methods

  • get_custom_quests_async(): Get all custom quests for the server asynchronously
  • get_player_info_async(discord_user_id): Get player information asynchronously
  • complete_custom_quest_async(custom_quest_id, discord_user_id): Complete a quest asynchronously
  • get_completed_members_async(custom_quest_id): Get completed members asynchronously
  • get_global_leaderboard_async(): Get global leaderboard asynchronously
  • check_suspicious_accounts_async(user_ids): Check suspicious accounts asynchronously
  • get_member_insights_async(user_ids): Get member insights asynchronously
  • get_invite_outcomes_async(invite_code): Get invite outcomes asynchronously

Analytics

The analytics methods return point-in-time data and require the server to be on the Analytics Premium Level 3 tier. Servers on any other tier get a 403.

Suspicious accounts

check_suspicious_accounts(user_ids) accepts between 1 and 100 Discord user IDs and returns one result per requested ID, in the same order as the request. Requesting more or fewer IDs raises a ValueError before the request is sent.

suspicious=sdk.check_suspicious_accounts(user_ids=["1273073873503522888", "851179040428654623"])
forresultinsuspicious["results"]:
ifresult["flagged"]:
print(result["user_id"], result["flagged_reason"], result["join_date"])

A user ID with no suspicious activity is clean, not unknown: it comes back with flagged set to False and every other field set to None. flagged_reason is an open string (currently GROUP_JOIN, JOIN_RIGHT_AFTER_CREATION, RANDOM_USERNAME or SCAMLIKE_CHAT) that may gain new values, and it can be None even when flagged is True.

Member insights

get_member_insights(user_ids) takes the same 1-100 user IDs and returns per-member activity data such as msg_count, days_present, wpm and most_active_channel_name.

insights=sdk.get_member_insights(user_ids=["1273073873503522888"])
forresultininsights["results"]:
ifresult["found"]:
print(result["username"], result["msg_count"], result["most_active_channel_name"])

Here absence genuinely means "no data available", so check found rather than assuming a member is inactive. Requesting unknown IDs is not an error. member_type (MODERATOR or REGULAR_MEMBER) is also an open string.

Invite outcomes

get_invite_outcomes(invite_code) returns the outcomes for a single invite code as a flat object. The invite code is URL-encoded for you.

outcomes=sdk.get_invite_outcomes(invite_code="abcd1234")
print(outcomes["total_users"], outcomes["total_suspicious_users"])

An invite code with no recorded outcomes returns a 404, which surfaces as the usual requests.HTTPError (or aiohttp.ClientResponseError for the async method). This is an expected outcome rather than a fault, so handle it explicitly if you may query codes that were never used:

importrequeststry:
outcomes=sdk.get_invite_outcomes(invite_code="abcd1234")
exceptrequests.HTTPErroraserror:
iferror.response.status_code==404:
outcomes=Noneelse:
raise

Invite codes are only unique within a server, since a released vanity code can later be claimed by a different server, so scope any cached results by server ID.

Discord IDs

Discord IDs are sent and returned as strings to avoid precision loss. int values are accepted and coerced with str(). The user_id echoed back in a response is numerically normalized, so an input of "0007" returns as "7" — match results to inputs by array position, or normalize your inputs first.

Testing Mode

CommunityOne allows you to test the full quest completion workflow in your application without affecting production quests data, helping you verify quest functionality before releasing it to your community. When a quest is in testing mode:

  • The quest won't be visible to regular Discord server members
  • No code changes needed! - use the same SDK methods for testing and production quests (the API automatically routes to our internal test environment)

How to enable:

  1. Go to your server's CommunityOne dashboard
  2. Navigate to Hype Engine > Custom Quests
  3. Click the Edit button on your quest
  4. Enable testing mode

Rate Limiting

All API endpoints are subject to rate limiting:

  • 60 requests per minute per server for the quest and leaderboard endpoints
  • 120 requests per minute per server for the analytics endpoints
  • Rate limits are applied separately for each endpoint
  • Exceeding the rate limit will result in a 429 Too Many Requests response

Requirements

  • Python 3.7 or higher
  • requests>=2.25.0
  • aiohttp>=3.8.0

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

CommunityOne SDK

PyPI versionPython versions

Official Python SDK for interacting with the CommunityOne API. This SDK provides both synchronous and asynchronous methods to interact with CommunityOne's API endpoints.

About CommunityOne

CommunityOne is a platform that helps Discord communities grow and engage their members through quests, rewards, and gamification.

Installation

You can install the package using pip:

pip install communityone

Quick Start

fromcommunityoneimportCommunityOneSDK# Initialize the SDK with your server ID and API keysdk=CommunityOneSDK(server_id=YOUR_SERVER_ID, api_key="YOUR_API_KEY")
# Get all custom questscustom_quests=sdk.get_custom_quests()
# Get player informationplayer_info=sdk.get_player_info(discord_user_id="DISCORD_USER_ID")
# Complete a custom questresult=sdk.complete_custom_quest(custom_quest_id="CUSTOM_QUEST_ID", discord_user_id="DISCORD_USER_ID")
# Get completed members for a questcompleted_members=sdk.get_completed_members(custom_quest_id="CUSTOM_QUEST_ID")
# Get global leaderboardleaderboard=sdk.get_global_leaderboard()
# Check whether members were flagged as suspicious accountssuspicious=sdk.check_suspicious_accounts(user_ids=["DISCORD_USER_ID"])
# Get activity insights for membersinsights=sdk.get_member_insights(user_ids=["DISCORD_USER_ID"])
# Get the outcomes recorded for an invite codeoutcomes=sdk.get_invite_outcomes(invite_code="INVITE_CODE")

Async Support

The SDK also provides async methods for all operations:

importasynciofromcommunityoneimportCommunityOneSDKasyncdefmain():
sdk=CommunityOneSDK(server_id=YOUR_SERVER_ID, api_key="YOUR_API_KEY")
# Get custom quests asynchronouslycustom_quests=awaitsdk.get_custom_quests_async()
# Get player information asynchronouslyplayer_info=awaitsdk.get_player_info_async("DISCORD_USER_ID")
# Complete a custom quest asynchronouslyresult=awaitsdk.complete_custom_quest_async(custom_quest_id="CUSTOM_QUEST_ID", discord_user_id="DISCORD_USER_ID")
# Get completed members asynchronouslycompleted_members=awaitsdk.get_completed_members_async(custom_quest_id="CUSTOM_QUEST_ID")
# Get global leaderboard asynchronouslyleaderboard=awaitsdk.get_global_leaderboard_async()
# Check suspicious accounts asynchronouslysuspicious=awaitsdk.check_suspicious_accounts_async(user_ids=["DISCORD_USER_ID"])
# Get member insights asynchronouslyinsights=awaitsdk.get_member_insights_async(user_ids=["DISCORD_USER_ID"])
# Get invite outcomes asynchronouslyoutcomes=awaitsdk.get_invite_outcomes_async(invite_code="INVITE_CODE")
# Run the async codeasyncio.run(main())

Available Methods

Synchronous Methods

  • get_custom_quests(): Get all custom quests for the server
  • get_player_info(discord_user_id): Get information about a player
  • complete_custom_quest(custom_quest_id, discord_user_id): Mark a custom quest as completed
  • get_completed_members(custom_quest_id): Get all members who completed a quest
  • get_global_leaderboard(): Get global leaderboard for the server
  • check_suspicious_accounts(user_ids): Check whether members were flagged as suspicious accounts
  • get_member_insights(user_ids): Get activity insights for members
  • get_invite_outcomes(invite_code): Get the outcomes recorded for an invite code

Asynchronous Methods

  • get_custom_quests_async(): Get all custom quests for the server asynchronously
  • get_player_info_async(discord_user_id): Get player information asynchronously
  • complete_custom_quest_async(custom_quest_id, discord_user_id): Complete a quest asynchronously
  • get_completed_members_async(custom_quest_id): Get completed members asynchronously
  • get_global_leaderboard_async(): Get global leaderboard asynchronously
  • check_suspicious_accounts_async(user_ids): Check suspicious accounts asynchronously
  • get_member_insights_async(user_ids): Get member insights asynchronously
  • get_invite_outcomes_async(invite_code): Get invite outcomes asynchronously

Analytics

The analytics methods return point-in-time data and require the server to be on the Analytics Premium Level 3 tier. Servers on any other tier get a 403.

Suspicious accounts

check_suspicious_accounts(user_ids) accepts between 1 and 100 Discord user IDs and returns one result per requested ID, in the same order as the request. Requesting more or fewer IDs raises a ValueError before the request is sent.

suspicious=sdk.check_suspicious_accounts(user_ids=["1273073873503522888", "851179040428654623"])
forresultinsuspicious["results"]:
ifresult["flagged"]:
print(result["user_id"], result["flagged_reason"], result["join_date"])

A user ID with no suspicious activity is clean, not unknown: it comes back with flagged set to False and every other field set to None. flagged_reason is an open string (currently GROUP_JOIN, JOIN_RIGHT_AFTER_CREATION, RANDOM_USERNAME or SCAMLIKE_CHAT) that may gain new values, and it can be None even when flagged is True.

Member insights

get_member_insights(user_ids) takes the same 1-100 user IDs and returns per-member activity data such as msg_count, days_present, wpm and most_active_channel_name.

insights=sdk.get_member_insights(user_ids=["1273073873503522888"])
forresultininsights["results"]:
ifresult["found"]:
print(result["username"], result["msg_count"], result["most_active_channel_name"])

Here absence genuinely means "no data available", so check found rather than assuming a member is inactive. Requesting unknown IDs is not an error. member_type (MODERATOR or REGULAR_MEMBER) is also an open string.

Invite outcomes

get_invite_outcomes(invite_code) returns the outcomes for a single invite code as a flat object. The invite code is URL-encoded for you.

outcomes=sdk.get_invite_outcomes(invite_code="abcd1234")
print(outcomes["total_users"], outcomes["total_suspicious_users"])

An invite code with no recorded outcomes returns a 404, which surfaces as the usual requests.HTTPError (or aiohttp.ClientResponseError for the async method). This is an expected outcome rather than a fault, so handle it explicitly if you may query codes that were never used:

importrequeststry:
outcomes=sdk.get_invite_outcomes(invite_code="abcd1234")
exceptrequests.HTTPErroraserror:
iferror.response.status_code==404:
outcomes=Noneelse:
raise

Invite codes are only unique within a server, since a released vanity code can later be claimed by a different server, so scope any cached results by server ID.

Discord IDs

Discord IDs are sent and returned as strings to avoid precision loss. int values are accepted and coerced with str(). The user_id echoed back in a response is numerically normalized, so an input of "0007" returns as "7" — match results to inputs by array position, or normalize your inputs first.

Testing Mode

CommunityOne allows you to test the full quest completion workflow in your application without affecting production quests data, helping you verify quest functionality before releasing it to your community. When a quest is in testing mode:

  • The quest won't be visible to regular Discord server members
  • No code changes needed! - use the same SDK methods for testing and production quests (the API automatically routes to our internal test environment)

How to enable:

  1. Go to your server's CommunityOne dashboard
  2. Navigate to Hype Engine > Custom Quests
  3. Click the Edit button on your quest
  4. Enable testing mode

Rate Limiting

All API endpoints are subject to rate limiting:

  • 60 requests per minute per server for the quest and leaderboard endpoints
  • 120 requests per minute per server for the analytics endpoints
  • Rate limits are applied separately for each endpoint
  • Exceeding the rate limit will result in a 429 Too Many Requests response

Requirements

  • Python 3.7 or higher
  • requests>=2.25.0
  • aiohttp>=3.8.0

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

CommunityOne SDK

PyPI versionPython versions

Official Python SDK for interacting with the CommunityOne API. This SDK provides both synchronous and asynchronous methods to interact with CommunityOne's API endpoints.

About CommunityOne

CommunityOne is a platform that helps Discord communities grow and engage their members through quests, rewards, and gamification.

Installation

You can install the package using pip:

pip install communityone

Quick Start

fromcommunityoneimportCommunityOneSDK# Initialize the SDK with your server ID and API keysdk=CommunityOneSDK(server_id=YOUR_SERVER_ID, api_key="YOUR_API_KEY")
# Get all custom questscustom_quests=sdk.get_custom_quests()
# Get player informationplayer_info=sdk.get_player_info(discord_user_id="DISCORD_USER_ID")
# Complete a custom questresult=sdk.complete_custom_quest(custom_quest_id="CUSTOM_QUEST_ID", discord_user_id="DISCORD_USER_ID")
# Get completed members for a questcompleted_members=sdk.get_completed_members(custom_quest_id="CUSTOM_QUEST_ID")
# Get global leaderboardleaderboard=sdk.get_global_leaderboard()
# Check whether members were flagged as suspicious accountssuspicious=sdk.check_suspicious_accounts(user_ids=["DISCORD_USER_ID"])
# Get activity insights for membersinsights=sdk.get_member_insights(user_ids=["DISCORD_USER_ID"])
# Get the outcomes recorded for an invite codeoutcomes=sdk.get_invite_outcomes(invite_code="INVITE_CODE")

Async Support

The SDK also provides async methods for all operations:

importasynciofromcommunityoneimportCommunityOneSDKasyncdefmain():
sdk=CommunityOneSDK(server_id=YOUR_SERVER_ID, api_key="YOUR_API_KEY")
# Get custom quests asynchronouslycustom_quests=awaitsdk.get_custom_quests_async()
# Get player information asynchronouslyplayer_info=awaitsdk.get_player_info_async("DISCORD_USER_ID")
# Complete a custom quest asynchronouslyresult=awaitsdk.complete_custom_quest_async(custom_quest_id="CUSTOM_QUEST_ID", discord_user_id="DISCORD_USER_ID")
# Get completed members asynchronouslycompleted_members=awaitsdk.get_completed_members_async(custom_quest_id="CUSTOM_QUEST_ID")
# Get global leaderboard asynchronouslyleaderboard=awaitsdk.get_global_leaderboard_async()
# Check suspicious accounts asynchronouslysuspicious=awaitsdk.check_suspicious_accounts_async(user_ids=["DISCORD_USER_ID"])
# Get member insights asynchronouslyinsights=awaitsdk.get_member_insights_async(user_ids=["DISCORD_USER_ID"])
# Get invite outcomes asynchronouslyoutcomes=awaitsdk.get_invite_outcomes_async(invite_code="INVITE_CODE")
# Run the async codeasyncio.run(main())

Available Methods

Synchronous Methods

  • get_custom_quests(): Get all custom quests for the server
  • get_player_info(discord_user_id): Get information about a player
  • complete_custom_quest(custom_quest_id, discord_user_id): Mark a custom quest as completed
  • get_completed_members(custom_quest_id): Get all members who completed a quest
  • get_global_leaderboard(): Get global leaderboard for the server
  • check_suspicious_accounts(user_ids): Check whether members were flagged as suspicious accounts
  • get_member_insights(user_ids): Get activity insights for members
  • get_invite_outcomes(invite_code): Get the outcomes recorded for an invite code

Asynchronous Methods

  • get_custom_quests_async(): Get all custom quests for the server asynchronously
  • get_player_info_async(discord_user_id): Get player information asynchronously
  • complete_custom_quest_async(custom_quest_id, discord_user_id): Complete a quest asynchronously
  • get_completed_members_async(custom_quest_id): Get completed members asynchronously
  • get_global_leaderboard_async(): Get global leaderboard asynchronously
  • check_suspicious_accounts_async(user_ids): Check suspicious accounts asynchronously
  • get_member_insights_async(user_ids): Get member insights asynchronously
  • get_invite_outcomes_async(invite_code): Get invite outcomes asynchronously

Analytics

The analytics methods return point-in-time data and require the server to be on the Analytics Premium Level 3 tier. Servers on any other tier get a 403.

Suspicious accounts

check_suspicious_accounts(user_ids) accepts between 1 and 100 Discord user IDs and returns one result per requested ID, in the same order as the request. Requesting more or fewer IDs raises a ValueError before the request is sent.

suspicious=sdk.check_suspicious_accounts(user_ids=["1273073873503522888", "851179040428654623"])
forresultinsuspicious["results"]:
ifresult["flagged"]:
print(result["user_id"], result["flagged_reason"], result["join_date"])

A user ID with no suspicious activity is clean, not unknown: it comes back with flagged set to False and every other field set to None. flagged_reason is an open string (currently GROUP_JOIN, JOIN_RIGHT_AFTER_CREATION, RANDOM_USERNAME or SCAMLIKE_CHAT) that may gain new values, and it can be None even when flagged is True.

Member insights

get_member_insights(user_ids) takes the same 1-100 user IDs and returns per-member activity data such as msg_count, days_present, wpm and most_active_channel_name.

insights=sdk.get_member_insights(user_ids=["1273073873503522888"])
forresultininsights["results"]:
ifresult["found"]:
print(result["username"], result["msg_count"], result["most_active_channel_name"])

Here absence genuinely means "no data available", so check found rather than assuming a member is inactive. Requesting unknown IDs is not an error. member_type (MODERATOR or REGULAR_MEMBER) is also an open string.

Invite outcomes

get_invite_outcomes(invite_code) returns the outcomes for a single invite code as a flat object. The invite code is URL-encoded for you.

outcomes=sdk.get_invite_outcomes(invite_code="abcd1234")
print(outcomes["total_users"], outcomes["total_suspicious_users"])

An invite code with no recorded outcomes returns a 404, which surfaces as the usual requests.HTTPError (or aiohttp.ClientResponseError for the async method). This is an expected outcome rather than a fault, so handle it explicitly if you may query codes that were never used:

importrequeststry:
outcomes=sdk.get_invite_outcomes(invite_code="abcd1234")
exceptrequests.HTTPErroraserror:
iferror.response.status_code==404:
outcomes=Noneelse:
raise

Invite codes are only unique within a server, since a released vanity code can later be claimed by a different server, so scope any cached results by server ID.

Discord IDs

Discord IDs are sent and returned as strings to avoid precision loss. int values are accepted and coerced with str(). The user_id echoed back in a response is numerically normalized, so an input of "0007" returns as "7" — match results to inputs by array position, or normalize your inputs first.

Testing Mode

CommunityOne allows you to test the full quest completion workflow in your application without affecting production quests data, helping you verify quest functionality before releasing it to your community. When a quest is in testing mode:

  • The quest won't be visible to regular Discord server members
  • No code changes needed! - use the same SDK methods for testing and production quests (the API automatically routes to our internal test environment)

How to enable:

  1. Go to your server's CommunityOne dashboard
  2. Navigate to Hype Engine > Custom Quests
  3. Click the Edit button on your quest
  4. Enable testing mode

Rate Limiting

All API endpoints are subject to rate limiting:

  • 60 requests per minute per server for the quest and leaderboard endpoints
  • 120 requests per minute per server for the analytics endpoints
  • Rate limits are applied separately for each endpoint
  • Exceeding the rate limit will result in a 429 Too Many Requests response

Requirements

  • Python 3.7 or higher
  • requests>=2.25.0
  • aiohttp>=3.8.0

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

CommunityOne SDK

PyPI versionPython versions

Official Python SDK for interacting with the CommunityOne API. This SDK provides both synchronous and asynchronous methods to interact with CommunityOne's API endpoints.

About CommunityOne

CommunityOne is a platform that helps Discord communities grow and engage their members through quests, rewards, and gamification.

Installation

You can install the package using pip:

pip install communityone

Quick Start

fromcommunityoneimportCommunityOneSDK# Initialize the SDK with your server ID and API keysdk=CommunityOneSDK(server_id=YOUR_SERVER_ID, api_key="YOUR_API_KEY")
# Get all custom questscustom_quests=sdk.get_custom_quests()
# Get player informationplayer_info=sdk.get_player_info(discord_user_id="DISCORD_USER_ID")
# Complete a custom questresult=sdk.complete_custom_quest(custom_quest_id="CUSTOM_QUEST_ID", discord_user_id="DISCORD_USER_ID")
# Get completed members for a questcompleted_members=sdk.get_completed_members(custom_quest_id="CUSTOM_QUEST_ID")
# Get global leaderboardleaderboard=sdk.get_global_leaderboard()
# Check whether members were flagged as suspicious accountssuspicious=sdk.check_suspicious_accounts(user_ids=["DISCORD_USER_ID"])
# Get activity insights for membersinsights=sdk.get_member_insights(user_ids=["DISCORD_USER_ID"])
# Get the outcomes recorded for an invite codeoutcomes=sdk.get_invite_outcomes(invite_code="INVITE_CODE")

Async Support

The SDK also provides async methods for all operations:

importasynciofromcommunityoneimportCommunityOneSDKasyncdefmain():
sdk=CommunityOneSDK(server_id=YOUR_SERVER_ID, api_key="YOUR_API_KEY")
# Get custom quests asynchronouslycustom_quests=awaitsdk.get_custom_quests_async()
# Get player information asynchronouslyplayer_info=awaitsdk.get_player_info_async("DISCORD_USER_ID")
# Complete a custom quest asynchronouslyresult=awaitsdk.complete_custom_quest_async(custom_quest_id="CUSTOM_QUEST_ID", discord_user_id="DISCORD_USER_ID")
# Get completed members asynchronouslycompleted_members=awaitsdk.get_completed_members_async(custom_quest_id="CUSTOM_QUEST_ID")
# Get global leaderboard asynchronouslyleaderboard=awaitsdk.get_global_leaderboard_async()
# Check suspicious accounts asynchronouslysuspicious=awaitsdk.check_suspicious_accounts_async(user_ids=["DISCORD_USER_ID"])
# Get member insights asynchronouslyinsights=awaitsdk.get_member_insights_async(user_ids=["DISCORD_USER_ID"])
# Get invite outcomes asynchronouslyoutcomes=awaitsdk.get_invite_outcomes_async(invite_code="INVITE_CODE")
# Run the async codeasyncio.run(main())

Available Methods

Synchronous Methods

  • get_custom_quests(): Get all custom quests for the server
  • get_player_info(discord_user_id): Get information about a player
  • complete_custom_quest(custom_quest_id, discord_user_id): Mark a custom quest as completed
  • get_completed_members(custom_quest_id): Get all members who completed a quest
  • get_global_leaderboard(): Get global leaderboard for the server
  • check_suspicious_accounts(user_ids): Check whether members were flagged as suspicious accounts
  • get_member_insights(user_ids): Get activity insights for members
  • get_invite_outcomes(invite_code): Get the outcomes recorded for an invite code

Asynchronous Methods

  • get_custom_quests_async(): Get all custom quests for the server asynchronously
  • get_player_info_async(discord_user_id): Get player information asynchronously
  • complete_custom_quest_async(custom_quest_id, discord_user_id): Complete a quest asynchronously
  • get_completed_members_async(custom_quest_id): Get completed members asynchronously
  • get_global_leaderboard_async(): Get global leaderboard asynchronously
  • check_suspicious_accounts_async(user_ids): Check suspicious accounts asynchronously
  • get_member_insights_async(user_ids): Get member insights asynchronously
  • get_invite_outcomes_async(invite_code): Get invite outcomes asynchronously

Analytics

The analytics methods return point-in-time data and require the server to be on the Analytics Premium Level 3 tier. Servers on any other tier get a 403.

Suspicious accounts

check_suspicious_accounts(user_ids) accepts between 1 and 100 Discord user IDs and returns one result per requested ID, in the same order as the request. Requesting more or fewer IDs raises a ValueError before the request is sent.

suspicious=sdk.check_suspicious_accounts(user_ids=["1273073873503522888", "851179040428654623"])
forresultinsuspicious["results"]:
ifresult["flagged"]:
print(result["user_id"], result["flagged_reason"], result["join_date"])

A user ID with no suspicious activity is clean, not unknown: it comes back with flagged set to False and every other field set to None. flagged_reason is an open string (currently GROUP_JOIN, JOIN_RIGHT_AFTER_CREATION, RANDOM_USERNAME or SCAMLIKE_CHAT) that may gain new values, and it can be None even when flagged is True.

Member insights

get_member_insights(user_ids) takes the same 1-100 user IDs and returns per-member activity data such as msg_count, days_present, wpm and most_active_channel_name.

insights=sdk.get_member_insights(user_ids=["1273073873503522888"])
forresultininsights["results"]:
ifresult["found"]:
print(result["username"], result["msg_count"], result["most_active_channel_name"])

Here absence genuinely means "no data available", so check found rather than assuming a member is inactive. Requesting unknown IDs is not an error. member_type (MODERATOR or REGULAR_MEMBER) is also an open string.

Invite outcomes

get_invite_outcomes(invite_code) returns the outcomes for a single invite code as a flat object. The invite code is URL-encoded for you.

outcomes=sdk.get_invite_outcomes(invite_code="abcd1234")
print(outcomes["total_users"], outcomes["total_suspicious_users"])

An invite code with no recorded outcomes returns a 404, which surfaces as the usual requests.HTTPError (or aiohttp.ClientResponseError for the async method). This is an expected outcome rather than a fault, so handle it explicitly if you may query codes that were never used:

importrequeststry:
outcomes=sdk.get_invite_outcomes(invite_code="abcd1234")
exceptrequests.HTTPErroraserror:
iferror.response.status_code==404:
outcomes=Noneelse:
raise

Invite codes are only unique within a server, since a released vanity code can later be claimed by a different server, so scope any cached results by server ID.

Discord IDs

Discord IDs are sent and returned as strings to avoid precision loss. int values are accepted and coerced with str(). The user_id echoed back in a response is numerically normalized, so an input of "0007" returns as "7" — match results to inputs by array position, or normalize your inputs first.

Testing Mode

CommunityOne allows you to test the full quest completion workflow in your application without affecting production quests data, helping you verify quest functionality before releasing it to your community. When a quest is in testing mode:

  • The quest won't be visible to regular Discord server members
  • No code changes needed! - use the same SDK methods for testing and production quests (the API automatically routes to our internal test environment)

How to enable:

  1. Go to your server's CommunityOne dashboard
  2. Navigate to Hype Engine > Custom Quests
  3. Click the Edit button on your quest
  4. Enable testing mode

Rate Limiting

All API endpoints are subject to rate limiting:

  • 60 requests per minute per server for the quest and leaderboard endpoints
  • 120 requests per minute per server for the analytics endpoints
  • Rate limits are applied separately for each endpoint
  • Exceeding the rate limit will result in a 429 Too Many Requests response

Requirements

  • Python 3.7 or higher
  • requests>=2.25.0
  • aiohttp>=3.8.0

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

CommunityOne SDK

PyPI versionPython versions

Official Python SDK for interacting with the CommunityOne API. This SDK provides both synchronous and asynchronous methods to interact with CommunityOne's API endpoints.

About CommunityOne

CommunityOne is a platform that helps Discord communities grow and engage their members through quests, rewards, and gamification.

Installation

You can install the package using pip:

pip install communityone

Quick Start

fromcommunityoneimportCommunityOneSDK# Initialize the SDK with your server ID and API keysdk=CommunityOneSDK(server_id=YOUR_SERVER_ID, api_key="YOUR_API_KEY")
# Get all custom questscustom_quests=sdk.get_custom_quests()
# Get player informationplayer_info=sdk.get_player_info(discord_user_id="DISCORD_USER_ID")
# Complete a custom questresult=sdk.complete_custom_quest(custom_quest_id="CUSTOM_QUEST_ID", discord_user_id="DISCORD_USER_ID")
# Get completed members for a questcompleted_members=sdk.get_completed_members(custom_quest_id="CUSTOM_QUEST_ID")
# Get global leaderboardleaderboard=sdk.get_global_leaderboard()
# Check whether members were flagged as suspicious accountssuspicious=sdk.check_suspicious_accounts(user_ids=["DISCORD_USER_ID"])
# Get activity insights for membersinsights=sdk.get_member_insights(user_ids=["DISCORD_USER_ID"])
# Get the outcomes recorded for an invite codeoutcomes=sdk.get_invite_outcomes(invite_code="INVITE_CODE")

Async Support

The SDK also provides async methods for all operations:

importasynciofromcommunityoneimportCommunityOneSDKasyncdefmain():
sdk=CommunityOneSDK(server_id=YOUR_SERVER_ID, api_key="YOUR_API_KEY")
# Get custom quests asynchronouslycustom_quests=awaitsdk.get_custom_quests_async()
# Get player information asynchronouslyplayer_info=awaitsdk.get_player_info_async("DISCORD_USER_ID")
# Complete a custom quest asynchronouslyresult=awaitsdk.complete_custom_quest_async(custom_quest_id="CUSTOM_QUEST_ID", discord_user_id="DISCORD_USER_ID")
# Get completed members asynchronouslycompleted_members=awaitsdk.get_completed_members_async(custom_quest_id="CUSTOM_QUEST_ID")
# Get global leaderboard asynchronouslyleaderboard=awaitsdk.get_global_leaderboard_async()
# Check suspicious accounts asynchronouslysuspicious=awaitsdk.check_suspicious_accounts_async(user_ids=["DISCORD_USER_ID"])
# Get member insights asynchronouslyinsights=awaitsdk.get_member_insights_async(user_ids=["DISCORD_USER_ID"])
# Get invite outcomes asynchronouslyoutcomes=awaitsdk.get_invite_outcomes_async(invite_code="INVITE_CODE")
# Run the async codeasyncio.run(main())

Available Methods

Synchronous Methods

  • get_custom_quests(): Get all custom quests for the server
  • get_player_info(discord_user_id): Get information about a player
  • complete_custom_quest(custom_quest_id, discord_user_id): Mark a custom quest as completed
  • get_completed_members(custom_quest_id): Get all members who completed a quest
  • get_global_leaderboard(): Get global leaderboard for the server
  • check_suspicious_accounts(user_ids): Check whether members were flagged as suspicious accounts
  • get_member_insights(user_ids): Get activity insights for members
  • get_invite_outcomes(invite_code): Get the outcomes recorded for an invite code

Asynchronous Methods

  • get_custom_quests_async(): Get all custom quests for the server asynchronously
  • get_player_info_async(discord_user_id): Get player information asynchronously
  • complete_custom_quest_async(custom_quest_id, discord_user_id): Complete a quest asynchronously
  • get_completed_members_async(custom_quest_id): Get completed members asynchronously
  • get_global_leaderboard_async(): Get global leaderboard asynchronously
  • check_suspicious_accounts_async(user_ids): Check suspicious accounts asynchronously
  • get_member_insights_async(user_ids): Get member insights asynchronously
  • get_invite_outcomes_async(invite_code): Get invite outcomes asynchronously

Analytics

The analytics methods return point-in-time data and require the server to be on the Analytics Premium Level 3 tier. Servers on any other tier get a 403.

Suspicious accounts

check_suspicious_accounts(user_ids) accepts between 1 and 100 Discord user IDs and returns one result per requested ID, in the same order as the request. Requesting more or fewer IDs raises a ValueError before the request is sent.

suspicious=sdk.check_suspicious_accounts(user_ids=["1273073873503522888", "851179040428654623"])
forresultinsuspicious["results"]:
ifresult["flagged"]:
print(result["user_id"], result["flagged_reason"], result["join_date"])

A user ID with no suspicious activity is clean, not unknown: it comes back with flagged set to False and every other field set to None. flagged_reason is an open string (currently GROUP_JOIN, JOIN_RIGHT_AFTER_CREATION, RANDOM_USERNAME or SCAMLIKE_CHAT) that may gain new values, and it can be None even when flagged is True.

Member insights

get_member_insights(user_ids) takes the same 1-100 user IDs and returns per-member activity data such as msg_count, days_present, wpm and most_active_channel_name.

insights=sdk.get_member_insights(user_ids=["1273073873503522888"])
forresultininsights["results"]:
ifresult["found"]:
print(result["username"], result["msg_count"], result["most_active_channel_name"])

Here absence genuinely means "no data available", so check found rather than assuming a member is inactive. Requesting unknown IDs is not an error. member_type (MODERATOR or REGULAR_MEMBER) is also an open string.

Invite outcomes

get_invite_outcomes(invite_code) returns the outcomes for a single invite code as a flat object. The invite code is URL-encoded for you.

outcomes=sdk.get_invite_outcomes(invite_code="abcd1234")
print(outcomes["total_users"], outcomes["total_suspicious_users"])

An invite code with no recorded outcomes returns a 404, which surfaces as the usual requests.HTTPError (or aiohttp.ClientResponseError for the async method). This is an expected outcome rather than a fault, so handle it explicitly if you may query codes that were never used:

importrequeststry:
outcomes=sdk.get_invite_outcomes(invite_code="abcd1234")
exceptrequests.HTTPErroraserror:
iferror.response.status_code==404:
outcomes=Noneelse:
raise

Invite codes are only unique within a server, since a released vanity code can later be claimed by a different server, so scope any cached results by server ID.

Discord IDs

Discord IDs are sent and returned as strings to avoid precision loss. int values are accepted and coerced with str(). The user_id echoed back in a response is numerically normalized, so an input of "0007" returns as "7" — match results to inputs by array position, or normalize your inputs first.

Testing Mode

CommunityOne allows you to test the full quest completion workflow in your application without affecting production quests data, helping you verify quest functionality before releasing it to your community. When a quest is in testing mode:

  • The quest won't be visible to regular Discord server members
  • No code changes needed! - use the same SDK methods for testing and production quests (the API automatically routes to our internal test environment)

How to enable:

  1. Go to your server's CommunityOne dashboard
  2. Navigate to Hype Engine > Custom Quests
  3. Click the Edit button on your quest
  4. Enable testing mode

Rate Limiting

All API endpoints are subject to rate limiting:

  • 60 requests per minute per server for the quest and leaderboard endpoints
  • 120 requests per minute per server for the analytics endpoints
  • Rate limits are applied separately for each endpoint
  • Exceeding the rate limit will result in a 429 Too Many Requests response

Requirements

  • Python 3.7 or higher
  • requests>=2.25.0
  • aiohttp>=3.8.0

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

CommunityOne SDK

PyPI versionPython versions

Official Python SDK for interacting with the CommunityOne API. This SDK provides both synchronous and asynchronous methods to interact with CommunityOne's API endpoints.

About CommunityOne

CommunityOne is a platform that helps Discord communities grow and engage their members through quests, rewards, and gamification.

Installation

You can install the package using pip:

pip install communityone

Quick Start

fromcommunityoneimportCommunityOneSDK# Initialize the SDK with your server ID and API keysdk=CommunityOneSDK(server_id=YOUR_SERVER_ID, api_key="YOUR_API_KEY")
# Get all custom questscustom_quests=sdk.get_custom_quests()
# Get player informationplayer_info=sdk.get_player_info(discord_user_id="DISCORD_USER_ID")
# Complete a custom questresult=sdk.complete_custom_quest(custom_quest_id="CUSTOM_QUEST_ID", discord_user_id="DISCORD_USER_ID")
# Get completed members for a questcompleted_members=sdk.get_completed_members(custom_quest_id="CUSTOM_QUEST_ID")
# Get global leaderboardleaderboard=sdk.get_global_leaderboard()
# Check whether members were flagged as suspicious accountssuspicious=sdk.check_suspicious_accounts(user_ids=["DISCORD_USER_ID"])
# Get activity insights for membersinsights=sdk.get_member_insights(user_ids=["DISCORD_USER_ID"])
# Get the outcomes recorded for an invite codeoutcomes=sdk.get_invite_outcomes(invite_code="INVITE_CODE")

Async Support

The SDK also provides async methods for all operations:

importasynciofromcommunityoneimportCommunityOneSDKasyncdefmain():
sdk=CommunityOneSDK(server_id=YOUR_SERVER_ID, api_key="YOUR_API_KEY")
# Get custom quests asynchronouslycustom_quests=awaitsdk.get_custom_quests_async()
# Get player information asynchronouslyplayer_info=awaitsdk.get_player_info_async("DISCORD_USER_ID")
# Complete a custom quest asynchronouslyresult=awaitsdk.complete_custom_quest_async(custom_quest_id="CUSTOM_QUEST_ID", discord_user_id="DISCORD_USER_ID")
# Get completed members asynchronouslycompleted_members=awaitsdk.get_completed_members_async(custom_quest_id="CUSTOM_QUEST_ID")
# Get global leaderboard asynchronouslyleaderboard=awaitsdk.get_global_leaderboard_async()
# Check suspicious accounts asynchronouslysuspicious=awaitsdk.check_suspicious_accounts_async(user_ids=["DISCORD_USER_ID"])
# Get member insights asynchronouslyinsights=awaitsdk.get_member_insights_async(user_ids=["DISCORD_USER_ID"])
# Get invite outcomes asynchronouslyoutcomes=awaitsdk.get_invite_outcomes_async(invite_code="INVITE_CODE")
# Run the async codeasyncio.run(main())

Available Methods

Synchronous Methods

  • get_custom_quests(): Get all custom quests for the server
  • get_player_info(discord_user_id): Get information about a player
  • complete_custom_quest(custom_quest_id, discord_user_id): Mark a custom quest as completed
  • get_completed_members(custom_quest_id): Get all members who completed a quest
  • get_global_leaderboard(): Get global leaderboard for the server
  • check_suspicious_accounts(user_ids): Check whether members were flagged as suspicious accounts
  • get_member_insights(user_ids): Get activity insights for members
  • get_invite_outcomes(invite_code): Get the outcomes recorded for an invite code

Asynchronous Methods

  • get_custom_quests_async(): Get all custom quests for the server asynchronously
  • get_player_info_async(discord_user_id): Get player information asynchronously
  • complete_custom_quest_async(custom_quest_id, discord_user_id): Complete a quest asynchronously
  • get_completed_members_async(custom_quest_id): Get completed members asynchronously
  • get_global_leaderboard_async(): Get global leaderboard asynchronously
  • check_suspicious_accounts_async(user_ids): Check suspicious accounts asynchronously
  • get_member_insights_async(user_ids): Get member insights asynchronously
  • get_invite_outcomes_async(invite_code): Get invite outcomes asynchronously

Analytics

The analytics methods return point-in-time data and require the server to be on the Analytics Premium Level 3 tier. Servers on any other tier get a 403.

Suspicious accounts

check_suspicious_accounts(user_ids) accepts between 1 and 100 Discord user IDs and returns one result per requested ID, in the same order as the request. Requesting more or fewer IDs raises a ValueError before the request is sent.

suspicious=sdk.check_suspicious_accounts(user_ids=["1273073873503522888", "851179040428654623"])
forresultinsuspicious["results"]:
ifresult["flagged"]:
print(result["user_id"], result["flagged_reason"], result["join_date"])

A user ID with no suspicious activity is clean, not unknown: it comes back with flagged set to False and every other field set to None. flagged_reason is an open string (currently GROUP_JOIN, JOIN_RIGHT_AFTER_CREATION, RANDOM_USERNAME or SCAMLIKE_CHAT) that may gain new values, and it can be None even when flagged is True.

Member insights

get_member_insights(user_ids) takes the same 1-100 user IDs and returns per-member activity data such as msg_count, days_present, wpm and most_active_channel_name.

insights=sdk.get_member_insights(user_ids=["1273073873503522888"])
forresultininsights["results"]:
ifresult["found"]:
print(result["username"], result["msg_count"], result["most_active_channel_name"])

Here absence genuinely means "no data available", so check found rather than assuming a member is inactive. Requesting unknown IDs is not an error. member_type (MODERATOR or REGULAR_MEMBER) is also an open string.

Invite outcomes

get_invite_outcomes(invite_code) returns the outcomes for a single invite code as a flat object. The invite code is URL-encoded for you.

outcomes=sdk.get_invite_outcomes(invite_code="abcd1234")
print(outcomes["total_users"], outcomes["total_suspicious_users"])

An invite code with no recorded outcomes returns a 404, which surfaces as the usual requests.HTTPError (or aiohttp.ClientResponseError for the async method). This is an expected outcome rather than a fault, so handle it explicitly if you may query codes that were never used:

importrequeststry:
outcomes=sdk.get_invite_outcomes(invite_code="abcd1234")
exceptrequests.HTTPErroraserror:
iferror.response.status_code==404:
outcomes=Noneelse:
raise

Invite codes are only unique within a server, since a released vanity code can later be claimed by a different server, so scope any cached results by server ID.

Discord IDs

Discord IDs are sent and returned as strings to avoid precision loss. int values are accepted and coerced with str(). The user_id echoed back in a response is numerically normalized, so an input of "0007" returns as "7" — match results to inputs by array position, or normalize your inputs first.

Testing Mode

CommunityOne allows you to test the full quest completion workflow in your application without affecting production quests data, helping you verify quest functionality before releasing it to your community. When a quest is in testing mode:

  • The quest won't be visible to regular Discord server members
  • No code changes needed! - use the same SDK methods for testing and production quests (the API automatically routes to our internal test environment)

How to enable:

  1. Go to your server's CommunityOne dashboard
  2. Navigate to Hype Engine > Custom Quests
  3. Click the Edit button on your quest
  4. Enable testing mode

Rate Limiting

All API endpoints are subject to rate limiting:

  • 60 requests per minute per server for the quest and leaderboard endpoints
  • 120 requests per minute per server for the analytics endpoints
  • Rate limits are applied separately for each endpoint
  • Exceeding the rate limit will result in a 429 Too Many Requests response

Requirements

  • Python 3.7 or higher
  • requests>=2.25.0
  • aiohttp>=3.8.0

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

CommunityOne SDK

PyPI versionPython versions

Official Python SDK for interacting with the CommunityOne API. This SDK provides both synchronous and asynchronous methods to interact with CommunityOne's API endpoints.

About CommunityOne

CommunityOne is a platform that helps Discord communities grow and engage their members through quests, rewards, and gamification.

Installation

You can install the package using pip:

pip install communityone

Quick Start

fromcommunityoneimportCommunityOneSDK# Initialize the SDK with your server ID and API keysdk=CommunityOneSDK(server_id=YOUR_SERVER_ID, api_key="YOUR_API_KEY")
# Get all custom questscustom_quests=sdk.get_custom_quests()
# Get player informationplayer_info=sdk.get_player_info(discord_user_id="DISCORD_USER_ID")
# Complete a custom questresult=sdk.complete_custom_quest(custom_quest_id="CUSTOM_QUEST_ID", discord_user_id="DISCORD_USER_ID")
# Get completed members for a questcompleted_members=sdk.get_completed_members(custom_quest_id="CUSTOM_QUEST_ID")
# Get global leaderboardleaderboard=sdk.get_global_leaderboard()
# Check whether members were flagged as suspicious accountssuspicious=sdk.check_suspicious_accounts(user_ids=["DISCORD_USER_ID"])
# Get activity insights for membersinsights=sdk.get_member_insights(user_ids=["DISCORD_USER_ID"])
# Get the outcomes recorded for an invite codeoutcomes=sdk.get_invite_outcomes(invite_code="INVITE_CODE")

Async Support

The SDK also provides async methods for all operations:

importasynciofromcommunityoneimportCommunityOneSDKasyncdefmain():
sdk=CommunityOneSDK(server_id=YOUR_SERVER_ID, api_key="YOUR_API_KEY")
# Get custom quests asynchronouslycustom_quests=awaitsdk.get_custom_quests_async()
# Get player information asynchronouslyplayer_info=awaitsdk.get_player_info_async("DISCORD_USER_ID")
# Complete a custom quest asynchronouslyresult=awaitsdk.complete_custom_quest_async(custom_quest_id="CUSTOM_QUEST_ID", discord_user_id="DISCORD_USER_ID")
# Get completed members asynchronouslycompleted_members=awaitsdk.get_completed_members_async(custom_quest_id="CUSTOM_QUEST_ID")
# Get global leaderboard asynchronouslyleaderboard=awaitsdk.get_global_leaderboard_async()
# Check suspicious accounts asynchronouslysuspicious=awaitsdk.check_suspicious_accounts_async(user_ids=["DISCORD_USER_ID"])
# Get member insights asynchronouslyinsights=awaitsdk.get_member_insights_async(user_ids=["DISCORD_USER_ID"])
# Get invite outcomes asynchronouslyoutcomes=awaitsdk.get_invite_outcomes_async(invite_code="INVITE_CODE")
# Run the async codeasyncio.run(main())

Available Methods

Synchronous Methods

  • get_custom_quests(): Get all custom quests for the server
  • get_player_info(discord_user_id): Get information about a player
  • complete_custom_quest(custom_quest_id, discord_user_id): Mark a custom quest as completed
  • get_completed_members(custom_quest_id): Get all members who completed a quest
  • get_global_leaderboard(): Get global leaderboard for the server
  • check_suspicious_accounts(user_ids): Check whether members were flagged as suspicious accounts
  • get_member_insights(user_ids): Get activity insights for members
  • get_invite_outcomes(invite_code): Get the outcomes recorded for an invite code

Asynchronous Methods

  • get_custom_quests_async(): Get all custom quests for the server asynchronously
  • get_player_info_async(discord_user_id): Get player information asynchronously
  • complete_custom_quest_async(custom_quest_id, discord_user_id): Complete a quest asynchronously
  • get_completed_members_async(custom_quest_id): Get completed members asynchronously
  • get_global_leaderboard_async(): Get global leaderboard asynchronously
  • check_suspicious_accounts_async(user_ids): Check suspicious accounts asynchronously
  • get_member_insights_async(user_ids): Get member insights asynchronously
  • get_invite_outcomes_async(invite_code): Get invite outcomes asynchronously

Analytics

The analytics methods return point-in-time data and require the server to be on the Analytics Premium Level 3 tier. Servers on any other tier get a 403.

Suspicious accounts

check_suspicious_accounts(user_ids) accepts between 1 and 100 Discord user IDs and returns one result per requested ID, in the same order as the request. Requesting more or fewer IDs raises a ValueError before the request is sent.

suspicious=sdk.check_suspicious_accounts(user_ids=["1273073873503522888", "851179040428654623"])
forresultinsuspicious["results"]:
ifresult["flagged"]:
print(result["user_id"], result["flagged_reason"], result["join_date"])

A user ID with no suspicious activity is clean, not unknown: it comes back with flagged set to False and every other field set to None. flagged_reason is an open string (currently GROUP_JOIN, JOIN_RIGHT_AFTER_CREATION, RANDOM_USERNAME or SCAMLIKE_CHAT) that may gain new values, and it can be None even when flagged is True.

Member insights

get_member_insights(user_ids) takes the same 1-100 user IDs and returns per-member activity data such as msg_count, days_present, wpm and most_active_channel_name.

insights=sdk.get_member_insights(user_ids=["1273073873503522888"])
forresultininsights["results"]:
ifresult["found"]:
print(result["username"], result["msg_count"], result["most_active_channel_name"])

Here absence genuinely means "no data available", so check found rather than assuming a member is inactive. Requesting unknown IDs is not an error. member_type (MODERATOR or REGULAR_MEMBER) is also an open string.

Invite outcomes

get_invite_outcomes(invite_code) returns the outcomes for a single invite code as a flat object. The invite code is URL-encoded for you.

outcomes=sdk.get_invite_outcomes(invite_code="abcd1234")
print(outcomes["total_users"], outcomes["total_suspicious_users"])

An invite code with no recorded outcomes returns a 404, which surfaces as the usual requests.HTTPError (or aiohttp.ClientResponseError for the async method). This is an expected outcome rather than a fault, so handle it explicitly if you may query codes that were never used:

importrequeststry:
outcomes=sdk.get_invite_outcomes(invite_code="abcd1234")
exceptrequests.HTTPErroraserror:
iferror.response.status_code==404:
outcomes=Noneelse:
raise

Invite codes are only unique within a server, since a released vanity code can later be claimed by a different server, so scope any cached results by server ID.

Discord IDs

Discord IDs are sent and returned as strings to avoid precision loss. int values are accepted and coerced with str(). The user_id echoed back in a response is numerically normalized, so an input of "0007" returns as "7" — match results to inputs by array position, or normalize your inputs first.

Testing Mode

CommunityOne allows you to test the full quest completion workflow in your application without affecting production quests data, helping you verify quest functionality before releasing it to your community. When a quest is in testing mode:

  • The quest won't be visible to regular Discord server members
  • No code changes needed! - use the same SDK methods for testing and production quests (the API automatically routes to our internal test environment)

How to enable:

  1. Go to your server's CommunityOne dashboard
  2. Navigate to Hype Engine > Custom Quests
  3. Click the Edit button on your quest
  4. Enable testing mode

Rate Limiting

All API endpoints are subject to rate limiting:

  • 60 requests per minute per server for the quest and leaderboard endpoints
  • 120 requests per minute per server for the analytics endpoints
  • Rate limits are applied separately for each endpoint
  • Exceeding the rate limit will result in a 429 Too Many Requests response

Requirements

  • Python 3.7 or higher
  • requests>=2.25.0
  • aiohttp>=3.8.0

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages