Hex.pm Documentation License

A 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

FunctionDescriptionParameters
new/2Create API clienttoken, options
post_stats/2Update bot statisticsapi, stats
get_stats/1Get bot statisticsapi
get_bot/2Get bot informationapi, bot_id
get_bots/2Search botsapi, query
get_votes/2Get recent votersapi, page
has_voted/2Check user vote statusapi, user_id
is_weekend/1Check weekend multiplierapi

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

  1. Fork the repository
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. 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.

Acknowledgments

  • Thanks to the Top.gg team for providing the API
  • Built with Finch for modern HTTP performance
  • Inspired by the JavaScript topgg.js library