TopggEx
View SourceA community Elixir SDK for the Top.gg API, allowing you to interact with Discord bot statistics, user votes, and bot information.
Features
- ๐ Complete API Coverage: All Top.gg API endpoints supported
- ๐ Type Safety: Full typespecs and structured data
- โก HTTP/2 Support: Built on Finch for modern HTTP performance
- ๐งช Well Tested: Comprehensive test suite with 95%+ coverage
- ๐ Excellent Documentation: Detailed docs with examples
- ๐๏ธ Clean Architecture: Separated HTTP client for maintainability
Installation
Add topgg_ex
to your list of dependencies in mix.exs
:
def deps do
[
{:topgg_ex, "~> 0.1.0"},
{:finch, "~> 0.19"} # Required HTTP client
]
end
Then run:
mix deps.get
Quick Start
1. Setup
First, add Finch to your application's supervision tree:
# In your application.ex
children = [
{Finch, name: :topgg_finch}
]
2. Create API Client
# Get your token from https://top.gg/api/docs#mybots
{:ok, api} = TopggEx.Api.new("your_topgg_token_here")
3. Post Bot Statistics
# Update your bot's server count
{:ok, stats} = TopggEx.Api.post_stats(api, %{server_count: 1250})
Usage Examples
Bot Statistics
# Post bot stats
{:ok, _} = TopggEx.Api.post_stats(api, %{
server_count: 1250,
shard_count: 2,
shards: [625, 625]
})
# Get your bot's current stats
{:ok, stats} = TopggEx.Api.get_stats(api)
# => %{server_count: 1250, shard_count: 2, shards: [625, 625]}
Bot Information
# Get information about any bot
{:ok, bot} = TopggEx.Api.get_bot(api, "461521980492087297")
# => %{"id" => "461521980492087297", "username" => "Shiro", ...}
# Search for bots
{:ok, results} = TopggEx.Api.get_bots(api, %{
search: %{username: "music"},
limit: 10,
fields: ["id", "username", "short_description"]
})
Vote Checking
# Check if a user has voted
{:ok, has_voted?} = TopggEx.Api.has_voted(api, "205680187394752512")
# => true or false
# Get recent voters
{:ok, voters} = TopggEx.Api.get_votes(api)
# => [%{"username" => "Example", "id" => "123...", "avatar" => "https://..."}, ...]
# Check weekend multiplier status
{:ok, is_weekend?} = TopggEx.Api.is_weekend(api)
# => true or false
Advanced Usage
# Custom Finch instance
{:ok, api} = TopggEx.Api.new("your_token", %{
finch_name: :my_custom_finch,
base_url: "https://top.gg/api" # Optional custom base URL
})
# Complex bot search
{:ok, results} = TopggEx.Api.get_bots(api, %{
search: %{
username: "music bot",
tags: "music"
},
sort: "server_count",
limit: 50,
fields: ["id", "username", "short_description", "server_count"]
})
API Reference
Core Functions
Function | Description | Parameters |
---|---|---|
new/2 | Create API client | token , options |
post_stats/2 | Update bot statistics | api , stats |
get_stats/1 | Get bot statistics | api |
get_bot/2 | Get bot information | api , bot_id |
get_bots/2 | Search bots | api , query |
get_votes/2 | Get recent voters | api , page |
has_voted/2 | Check user vote status | api , user_id |
is_weekend/1 | Check weekend multiplier | api |
Error Handling
All functions return {:ok, result}
on success or {:error, reason}
on failure:
case TopggEx.Api.post_stats(api, %{server_count: 100}) do
{:ok, stats} ->
IO.puts("Stats updated successfully!")
{:error, %{status: 401}} ->
IO.puts("Invalid API token")
{:error, %{status: 429}} ->
IO.puts("Rate limited - try again later")
{:error, reason} ->
IO.puts("Network error: #{inspect(reason)}")
end
Configuration
Environment Variables
You can set your Top.gg token via environment variables:
# config/runtime.exs
config :my_app, :topgg_token, System.get_env("TOPGG_TOKEN")
# In your application
token = Application.get_env(:my_app, :topgg_token)
{:ok, api} = TopggEx.Api.new(token)
Custom HTTP Client Options
{:ok, api} = TopggEx.Api.new("your_token", %{
finch_name: :my_finch, # Custom Finch instance name
base_url: "https://top.gg/api" # Custom API base URL
})
Rate Limiting
Top.gg API has rate limits. The library will return appropriate errors:
- 429 Too Many Requests: You've hit the rate limit
- 403 Forbidden: Invalid token or insufficient permissions
Implement exponential backoff for production applications:
defmodule MyBot.Stats do
def update_stats_with_retry(api, stats, retries \\ 3) do
case TopggEx.Api.post_stats(api, stats) do
{:ok, result} -> {:ok, result}
{:error, %{status: 429}} when retries > 0 ->
Process.sleep(1000 * (4 - retries)) # Exponential backoff
update_stats_with_retry(api, stats, retries - 1)
error -> error
end
end
end
Testing
The library includes comprehensive tests. Run them with:
mix test
For testing your own applications, you can mock the HTTP client:
# In your tests
setup do
bypass = Bypass.open()
{:ok, api} = TopggEx.Api.new("test_token", %{
base_url: "http://localhost:#{bypass.port}/api"
})
{:ok, %{bypass: bypass, api: api}}
end
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request
Development
# Get dependencies
mix deps.get
# Run tests
mix test
# Generate documentation
mix docs
# Check formatting
mix format --check-formatted
# Run static analysis
mix dialyzer
License
This project is licensed under the MIT License - see the LICENSE file for details.