├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── .prettierrc ├── README.md ├── components ├── Container.js ├── Counter.js ├── HTTPHeader.tsx ├── Home.js ├── Message.tsx ├── Next.js ├── Vercel.js └── Wrapper.js ├── next-env.d.ts ├── next.config.mjs ├── package-lock.json ├── package.json ├── pages ├── _app.js ├── _meta.json ├── contributors │ └── authoring.mdx ├── docs │ ├── _meta.json │ ├── api │ │ ├── _meta.json │ │ ├── about.mdx │ │ ├── bots.mdx │ │ ├── entity.mdx │ │ ├── users.mdx │ │ └── votes.mdx │ └── libraries │ │ ├── java.mdx │ │ ├── javascript.mdx │ │ └── python.mdx ├── index.mdx └── resources │ ├── downtime.mdx │ ├── ratelimits.mdx │ ├── references.mdx │ ├── usage.mdx │ ├── webhooks.mdx │ ├── weekends.mdx │ └── widgets.mdx ├── postcss.config.js ├── public ├── .nextra │ └── data-default.json ├── 85FC9DAF-60F4-4839-8BB8-31DAA7BE3303.png ├── Banner.png ├── Bannerz.png ├── InfinityBotList-Banner.png ├── Nextjs.png ├── Tailwind.png ├── icon.svg ├── infinity.png └── next.svg ├── styles.css ├── tailwind.config.js └── theme.config.js /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [InfinityBotList, TheRealToxicDev] 2 | patreon: infinitybots 3 | ko_fi: therealtoxicdev 4 | custom: [docs.botlist.site, infinitybots.gg] 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | **Describe the bug** 10 | A clear and concise description of what the bug is. 11 | 12 | **To Reproduce** 13 | Steps to reproduce the behavior: 14 | 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | 28 | - OS: [e.g. iOS] 29 | - Browser [e.g. chrome, safari] 30 | - Version [e.g. 22] 31 | 32 | **Smartphone (please complete the following information):** 33 | 34 | - Device: [e.g. iPhone6] 35 | - OS: [e.g. iOS8.1] 36 | - Browser [e.g. stock browser, safari] 37 | - Version [e.g. 22] 38 | 39 | **Additional context** 40 | Add any other context about the problem here. 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | **Is your feature request related to a problem? Please describe.** 10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 11 | 12 | **Describe the solution you'd like** 13 | A clear and concise description of what you want to happen. 14 | 15 | **Describe alternatives you've considered** 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | 18 | **Additional context** 19 | Add any other context or screenshots about the feature request here. 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .next 3 | build 4 | .pnpm-debug.log 5 | yarn-error.log -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "quoteProps": "as-needed", 4 | "singleQuote": true, 5 | "trailingComma": "all" 6 | } 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 | 5 |
6 |

7 | 8 | Official Documentation Site for the Infinity Bot List Website 9 | Discord Server, Staff Team and Companion API. 10 | 11 | --- 12 | 13 | ## Self Hosting 14 | 15 | > Not Supported 16 | 17 | **PLEASE LEAVE ALL CREDITS IN PLACE OR YOU MAY BE SUBJECT TO A TAKEDOWN YOU ARE WELCOME TO ADD THAT IT HAS BEEN EDITIED BY WHOEVER BUT ALL RIGHTS ARE RESERVED** 18 | 19 | --- 20 | 21 | ## Contributing 22 | 23 | Please read: https://docs.infinitybotlist.com/docs/contributors/authoring 24 | 25 | --- 26 | 27 | ## Contributors 28 | 29 | 30 | 31 | 32 | 33 | --- 34 | 35 | ## Made With 36 | 37 | [Next.js](https://nextjs.org/) | [TailwindCSS](https://tailwindcss.com/) 38 | -------------------------------------------------------------------------------- /components/Container.js: -------------------------------------------------------------------------------- 1 | export default function Container({ children }) { 2 | return
{children}
; 3 | } 4 | -------------------------------------------------------------------------------- /components/Counter.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect, useRef } from 'react'; 2 | import Wrapper from './Wrapper'; 3 | 4 | export default function Counter() { 5 | const [seconds, setSeconds] = useState(0); 6 | 7 | useInterval(() => { 8 | setSeconds(seconds + 1); 9 | }, 1000); 10 | 11 | return ( 12 | 13 |

Time elapsed: {seconds}

14 |
15 | ); 16 | } 17 | 18 | function useInterval(callback, delay) { 19 | const savedCallback = useRef(); 20 | 21 | useEffect(() => { 22 | savedCallback.current = callback; 23 | }); 24 | 25 | useEffect(() => { 26 | function tick() { 27 | savedCallback.current(); 28 | } 29 | 30 | let id = setInterval(tick, delay); 31 | return () => clearInterval(id); 32 | }, [delay]); 33 | } 34 | -------------------------------------------------------------------------------- /components/HTTPHeader.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styled from 'styled-components'; 3 | import { CopyToClipboard } from 'react-copy-to-clipboard'; 4 | 5 | const mappings = { 6 | POST: { 7 | color: '#78b993', 8 | background: '#212133', 9 | border: '#193123', 10 | }, 11 | GET: { 12 | color: '#7979d4', 13 | background: '#212133', 14 | border: '#47476b', 15 | }, 16 | }; 17 | 18 | const HeaderWrapper = styled.div` 19 | border: 1px solid ${(props) => mappings[props.method].border}; 20 | background: ${(props) => mappings[props.method].background}; 21 | border-radius: 4px; 22 | display: flex; 23 | align-items: center; 24 | flex-flow: row wrap; 25 | justify-content: space-between; 26 | margin-bottom: 24px; 27 | `; 28 | 29 | const MethodName = styled.h2` 30 | color: ${(props) => mappings[props.method].color}; 31 | font-weight: 700; 32 | font-size: 14px; 33 | margin: 0 10px 0 0; 34 | `; 35 | 36 | const EndpointUrl = styled.span` 37 | color: white; 38 | `; 39 | 40 | const CopyButton = styled.button` 41 | color: ${(props) => mappings[props.method].color}; 42 | background: inherit; 43 | font-size: 14px; 44 | border: none; 45 | cursor: pointer; 46 | height: 45px; 47 | align-items: center; 48 | font-weight: 500; 49 | padding: 0 10px; 50 | &:hover { 51 | filter: brightness(0.6); 52 | } 53 | `; 54 | 55 | const Header = styled.span` 56 | padding: 10px 15px; 57 | display: flex; 58 | align-items: center; 59 | `; 60 | 61 | export default function HTTPHeader({ type, path }) { 62 | const [copied, setCopy] = React.useState(false); 63 | React.useEffect(() => { 64 | if (copied) { 65 | setTimeout(() => setCopy(false), 3000); 66 | } 67 | }, [copied]); 68 | const BASE_URL = 'https://spider.infinitybots.gg/'; 69 | const fullUrl = new URL(path, BASE_URL).href; 70 | const url = path; 71 | return ( 72 | 73 |
74 | {type} 75 | $&'), 78 | }} 79 | /> 80 |
81 | setCopy(true)}> 82 | {copied ? 'Copied!' : 'Copy URL'} 83 | 84 |
85 | ); 86 | } 87 | -------------------------------------------------------------------------------- /components/Home.js: -------------------------------------------------------------------------------- 1 | import { Icon } from "@iconify-icon/react" 2 | import Head from 'next/head'; 3 | import Link from 'next/link'; 4 | import toast, { Toaster } from 'react-hot-toast'; 5 | 6 | const features = [ 7 | { 8 | name: 'Lightweight', 9 | description: `We use a Lightweight, Responsive RESTful API for all POST and GET Requests.`, 10 | icon: "mdi:paper-airplane", 11 | }, 12 | { 13 | name: 'Performance', 14 | description: `Our API is Made in Go (next/http) and Rust (axum) and it's all OSS on our github!`, 15 | icon: "mdi:lightning-bolt", 16 | }, 17 | { 18 | name: 'Reliable', 19 | description: `We put our users first and ensure our code is reliable. It even powers our entire site and is fully documented, no security-by-obfuscation here!`, 20 | icon: "mdi:eye-outline", 21 | }, 22 | { 23 | name: 'Sensible API', 24 | description: `Our API is simple to use and provides Error Messages and Responses that even a monkey could understand 😏`, 25 | icon: "mdi:access-point-check", 26 | }, 27 | { 28 | name: 'Developer Friendly', 29 | description: `We Encourage and Support all User/Developer based Contributions. Whether it be making us a Library or anything of the sort!`, 30 | icon: "mdi:cursor-default-click-outline", 31 | }, 32 | { 33 | name: 'Extremely Extensible', 34 | description: `You can use our API to build the most complex features. Such as: Vote Logs, Vote Rewards and so much more.`, 35 | icon: "mdi:google-circles-extended", 36 | }, 37 | ]; 38 | 39 | export default function Page() { 40 | return <> 41 | 42 | Infinity 43 | 44 |
45 |

46 | 47 | INFINITY DOCS. 48 | {' '} 49 |

50 |

51 | Official Documentation for Infinity Bot List 52 |

53 |
54 |
55 | 58 | 59 | → Get started 60 | 61 | 62 |
63 | 64 |
65 | 68 | 69 | → Get Support 70 | 71 | 72 |
73 | 74 |
75 | 78 | 79 | → Advanced Docs 80 | 81 | 82 |
83 |
84 |
85 | 86 |
87 |

88 | Features! 89 |

90 |

91 | Our API is designed to be modern and easy to use while being lean, 92 | responsive and insanely performant! 93 |

94 |
95 | {features.map((feature) => ( 96 |
100 |
101 | 102 |
103 |
104 |

105 | {feature.name} 106 |

107 |

108 | {feature.description} 109 |

110 |
111 |
112 | ))} 113 |
114 |
115 | 116 | ; 117 | } 118 | -------------------------------------------------------------------------------- /components/Message.tsx: -------------------------------------------------------------------------------- 1 | export default function Message({ type, title, children }) { 2 | return
{children}
; 3 | } 4 | -------------------------------------------------------------------------------- /components/Next.js: -------------------------------------------------------------------------------- 1 | export default function Nextjs({ height = 20 }) { 2 | return ( 3 | 4 | 11 | 16 | 29 | 46 | 51 | 61 | 70 | 77 | 82 | 87 | 94 | 99 | 103 | 118 | 135 | 136 | 137 | 138 | ); 139 | } 140 | -------------------------------------------------------------------------------- /components/Vercel.js: -------------------------------------------------------------------------------- 1 | export default function Vercel({ height = 20 }) { 2 | return ( 3 | 7 | 8 | 12 | 13 | 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /components/Wrapper.js: -------------------------------------------------------------------------------- 1 | export default function Wrapper({ children }) { 2 | return ( 3 |
4 | {children} 5 |
6 | ); 7 | } 8 | -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | import nextra from 'nextra' 2 | 3 | const withNexta = nextra({ 4 | theme: 'nextra-theme-docs', 5 | themeConfig: './theme.config.js', 6 | staticImage: true, 7 | latex: true, 8 | flexsearch: { 9 | codeblocks: false 10 | }, 11 | defaultShowCopyCode: false 12 | }); 13 | 14 | export default withNexta({ 15 | reactStrictMode: true, 16 | eslint: { 17 | ignoreDuringBuilds: true 18 | } 19 | }) 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@infinity/docs", 3 | "version": "6.0.0", 4 | "author": "Toxic Dev", 5 | "contributors": [ 6 | { "name": "Rootspring" }, 7 | { "name": "Cheesycod" } 8 | ], 9 | "scripts": { 10 | "dev": "next", 11 | "start": "next start", 12 | "build": "next build" 13 | }, 14 | "dependencies": { 15 | "@iconify-icon/react": "^1.0.5", 16 | "eslint-plugin-react": "latest", 17 | "eslint-plugin-react-hooks": "latest", 18 | "eslint-plugin-tailwindcss": "latest", 19 | "next": ">=13", 20 | "nextra": "^2.2.14", 21 | "nextra-theme-docs": "^2.2.14", 22 | "prism-react-renderer": "^1.2.1", 23 | "prismjs": "^1.26.0", 24 | "react": "*", 25 | "react-copy-to-clipboard": "^5.0.4", 26 | "react-dom": "*", 27 | "react-hot-toast": "^2.2.0", 28 | "styled-components": "^5.3.3", 29 | "tailwindcss": "^3.0.15" 30 | }, 31 | "devDependencies": { 32 | "@typescript-eslint/eslint-plugin": "latest", 33 | "@typescript-eslint/parser": "latest", 34 | "autoprefixer": "^10.4.2", 35 | "copy-to-clipboard": "^3.3.1", 36 | "eslint": "latest", 37 | "eslint-config-next": "latest", 38 | "eslint-config-prettier": "latest", 39 | "postcss": "^8.4.5", 40 | "prettier": "^2.8.4" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /pages/_app.js: -------------------------------------------------------------------------------- 1 | import '../styles.css'; 2 | import 'nextra-theme-docs/style.css'; 3 | import Prism from 'prism-react-renderer/prism'; 4 | (typeof global !== 'undefined' ? global : window).Prism = Prism; 5 | 6 | require('prismjs/components/prism-java'); 7 | require('prismjs/components/prism-json'); 8 | require('prismjs/components/prism-python'); 9 | require('prismjs/components/prism-jsx'); 10 | require('prismjs/components/prism-markdown'); 11 | 12 | export default function Nextra({ Component, pageProps }) { 13 | return 14 | } 15 | -------------------------------------------------------------------------------- /pages/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "index": { 3 | "title": "Home", 4 | "type": "page", 5 | "href": "/" 6 | }, 7 | "websites": { 8 | "title": "Website", 9 | "type": "menu", 10 | "items": { 11 | "prod": { 12 | "title": "Production", 13 | "href": "https://infinitybots.gg" 14 | }, 15 | "staging": { 16 | "title": "Staging", 17 | "href": "https://reedwhisker.infinitybots.gg" 18 | } 19 | } 20 | }, 21 | "documentation": { 22 | "title": "Documentation", 23 | "type": "menu", 24 | "items": { 25 | "prod": { 26 | "title": "Production", 27 | "href": "https://spider.infinitybots.gg/docs" 28 | }, 29 | "staging": { 30 | "title": "Staging", 31 | "href": "https://spider-staging.infinitybots.gg/docs" 32 | } 33 | } 34 | }, 35 | "contributors": { 36 | "title": "Contributors", 37 | "type": "doc" 38 | }, 39 | "docs": { 40 | "title": "Documentation", 41 | "type": "doc" 42 | }, 43 | "resources": { 44 | "title": "Resources", 45 | "type": "doc" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /pages/contributors/authoring.mdx: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | The Infinity Bot List Documentation is made possible through contributors made by project maintainers and community members. 4 | Each page corresponds to a Markdown file and can be edited via GitHub to then appear on the public site once the build completes. 5 | 6 | This site contains public-facing usage documentation, internal implementation documentation intended for contributors 7 | infinity staff documentation, server documentation and documentation regarding FAQS and useful info. 8 | As such, the pages are divided into multiple navigation trees under the base `pages` directory: 9 | 10 | | Tree | Description | 11 | | ----------- | -------------------------------------------------------- | 12 | | `docs ` | API Implementation, Common Use Cases, Tutorials and more | 13 | | `guides ` | API Implementation, Common Use Cases, Tutorials and more | 14 | | `staff ` | API Implementation, Common Use Cases, Tutorials and more | 15 | | `server ` | API Implementation, Common Use Cases, Tutorials and more | 16 | | `programs ` | API Implementation, Common Use Cases, Tutorials and More | 17 | 18 | --- 19 | 20 | ## Source 21 | 22 | The source documentation can be found [here](https://spider.infinitybots.gg/docs) 23 | 24 | Please use ^ as a reference when editting the guide or making integrations on top of our API! 25 | 26 | Structures present in the guide *may* contain inaccuracies. 27 | 28 | **No warranty is provided for any information presented here or any damagers caused by using our API and related documentation.** 29 | 30 | --- 31 | 32 | ## Components 33 | 34 | We implement a variety of Built-In Features for our Contributors to use and interact with. 35 | 36 | ### HTTP Header 37 | 38 | This is our base feature for POST and GET request examples. 39 | 40 |
41 | 42 | import HTTPHeader from '../../components/HTTPHeader'; 43 | 44 | ## Examples 45 | 46 | 47 | 48 | 49 | ## Usage 50 | 51 | ```markdown 52 | import HTTPHeader from '../../components/HTTPHeader'; 53 | 54 | 55 | 56 | 57 | ``` 58 | 59 | --- 60 | 61 | ### Bleed 62 | 63 | When wrapping your content with ``, it will be slightly wider than the container 64 | and will overflow on both sides. 65 | 66 | It providers a better reading experience when you want to present some graphical information, which normally 67 | looks nicer in a larger size. 68 | 69 | For example you can put text, image, video or any component inside 70 | or You can even make it full-bleed using ``: 71 | 72 | import { Bleed } from 'nextra-theme-docs' 73 | 74 | ## Examples 75 | 76 | 77 |
78 | _There is nothing to writing. All you do is sit down at a typewriter and **bleed**._ 79 | 80 | — Ernest Hemingway 81 | 82 |
83 |
84 | 85 | 86 | 100 | 101 | 102 | ### Usage 103 | 104 | ```markdown 105 | import { Bleed } from 'nextra-theme-docs' 106 | 107 | Hey, I can use **Markdown** syntax here. 108 | 109 | 110 | ![Landscape](https://source.unsplash.com/eaxwP9J_V6s/1600x398) 111 | 112 | 113 | 114 | 120 | 121 | ``` 122 | 123 | ```markdown 124 | 125 |
126 | _There is nothing to writing. All you do is sit down at a typewriter and **bleed**._ 127 | 128 | — Ernest Hemingway 129 | 130 |
131 |
132 | ``` 133 | 134 | --- 135 | 136 | ## Callout 137 | 138 | A built-in component provided by `nextra-theme-docs`. 139 | 140 | import { Callout } from 'nextra-theme-docs' 141 | 142 | ## Example 143 | 144 | 145 | A **callout** is a short piece of text intended to attract attention. 146 | 147 | 148 | ## Usage 149 | 150 | ### Default 151 | 152 | 153 | **Space Invaders** is a 1978 shoot 'em up arcade game developed by Tomohiro 154 | Nishikado. 155 | 156 | 157 | ```markdown 158 | import { Callout } from 'nextra-theme-docs' 159 | 160 | 161 | **Space Invaders** is a 1978 shoot 'em up arcade game developed by Tomohiro 162 | Nishikado. 163 | 164 | ``` 165 | 166 | ### Warning 167 | 168 | 169 | This API will be deprecated soon. 170 | 171 | 172 | ```markdown 173 | import Callout from 'nextra-theme-docs/callout' 174 | 175 | 176 | This API will be deprecated soon. 177 | 178 | ``` 179 | 180 | ### Error 181 | 182 | 183 | This is a dangerous feature that can cause everything to explode. 184 | 185 | 186 | ```markdown 187 | import Callout from 'nextra-theme-docs/callout' 188 | 189 | 190 | This is a dangerous feature that can cause everything to explode. 191 | 192 | ``` 193 | -------------------------------------------------------------------------------- /pages/docs/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "api": "API", 3 | "libraries": "Libraries" 4 | } 5 | -------------------------------------------------------------------------------- /pages/docs/api/_meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "about": "About", 3 | "bots": "Bots", 4 | "entity": "Entities", 5 | "users": "Users", 6 | "votes": "Votes" 7 | } 8 | -------------------------------------------------------------------------------- /pages/docs/api/about.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Intro 3 | --- 4 | 5 | # Introduction 6 | 7 | Hey there 👋, welcome to our Official Documentation! 8 | 9 | --- 10 | 11 | ## Getting Help 12 | 13 | If you need some help or think you have spotted a problem with our API you can talk to us in our 14 | [`#api-support`](https://discord.com/channels/758641373074423808/826363644295643136) channel in our [discord server](https://infinitybots.gg/redirect/discord). 15 | 16 | --- 17 | 18 | ## API Intro 19 | 20 | Infinity uses a REST(ish) API for most of its functionality. This API is used by our website and our bots to interact with the database. 21 | 22 | **For more up-to-date api reference, see [spider.infinitybots.gg/docs](https://spider.infinitybotlist.com). Please check this as well when developing against the API. Many endpoints on v4 especially are quite complex and nested and can't be documented easily here.** 23 | 24 | #### Base Url 25 | 26 | [spider.infinitybots.gg](https://spider.infinitybots.gg) (v4 API) 27 | 28 | The older `api.infinitybotlist.com` base URL will continue to work but it is recommended for newer bots to use `spider.infinitybots.gg` 29 | 30 | --- 31 | 32 | ## Authorization 33 | 34 | To access our API you need to authorize yourself or in this case your bot, this can be done by using your Infinity API Token which can be found in the `Owner Section` of your bots page. 35 | 36 | ![Owner Section Screenshot](https://media.discordapp.net/attachments/832011830238248961/871632845821591562/image0.png) 37 | 38 | Authentication is performed with the `authorization` HTTP header: 39 | 40 | ``` 41 | Authorization: "your-secret-token" 42 | ``` 43 | -------------------------------------------------------------------------------- /pages/docs/api/bots.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Bots 3 | --- 4 | 5 | import HTTPHeader from '../../../components/HTTPHeader'; 6 | import { Callout } from 'nextra-theme-docs' 7 | 8 | # Bots 9 | 10 | 11 | All endpoints use [Dynamic Ratelimits](/docs/resources/ratelimits). A list of all endpoints can be found [here](https://spider.infinitybots.gg/docs) 12 | 13 | 14 | **The below contains only the basic and common actions required by bot developers. A full list of endpoints provided by the Infinity Bot List API can be found [here](https://spider.infinitybots.gg/docs#tag--Bots) 15 | 16 | --- 17 | 18 | ## Post Bot Stats 19 | 20 | 21 | 22 | ### Headers 23 | 24 | | Field | Type | Description | Required | 25 | | ------------- | -------- | ---------------------------------- | -------- | 26 | | Authorization | `string` | The Bots `Infinity Bots API Token` | ✔️ | 27 | 28 | ### Body 29 | 30 | _Not all fields are documented here, see [here](https://spider.infinitybots.gg/docs#post-/bots/stats) for the full list_ 31 | 32 | | Field | Type | Description | Required | 33 | | ---------- | ---------- | -------------------------------- | -------- | 34 | | servers | `uint64` | Amount of servers the bot is in. | ✔️ | 35 | | shards | `uint64` | Amount of shards the bot has. | ❌ | 36 | | users | `uint64` | Amount of users the bot has. | ❌ | 37 | | shard_list | `[]uint64` | Shard list of bot. | ❌ | 38 | 39 | ### Response 40 | 41 | This endpoint returns a `204 No Content` with no response body. As such, you should not attempt to process any response body if a success code is returned 42 | 43 | ### Example 44 | 45 | ```py 46 | import requests 47 | req = requests.post(f"{API_URL}/bots/stats", json={"servers": 4000, "shards": 2}, headers={"Authorization": f"{TOKEN}"}) 48 | 49 | if req.status >= 200 and req.status < 400: 50 | print("SUCCESS!") 51 | 52 | print("ERROR:", req.json()) 53 | ``` 54 | 55 | --- 56 | 57 | ## Get User Entity Votes 58 | 59 | 60 | * - Note that you can replace 'bot' with the [entity](./entity) in question here, for example `server` or `pack`. For example `users/:userID/servers/:serverID/votes` and `users/:userID/packs/:packID/votes`. 61 | 62 | 63 | 64 | 65 | ### Body 66 | 67 | This endpoint does not accept a request body. Any bodies sent will either be ignored or will result in error. The sending of request body to endpoints that do not support it is *undefined behaviour* that may change at random without notice. 68 | 69 | ### Response 70 | 71 | _Not all fields are documented here, see [here](https://spider-staging.infinitybots.gg/docs/public.popplio#get-/users/-uid-/-target_type-s/-target_id-/votes) for the full list_ 72 | 73 | | Response | Description | 74 | | -------------- | --------------------------------------------------------------------------------------------------- | 75 | | valid votes | All of the valid votes for the current time period | 76 | | has_voted | If the user has Voted Recently (True or False) | 77 | | wait | How much time to wait (if applicable) | 78 | | vote_info | Some vote-related context such as `vote_time` | 79 | -------------------------------------------------------------------------------- /pages/docs/api/entity.mdx: -------------------------------------------------------------------------------- 1 | # Entity 2 | 3 | An entity is an abstraction used by the API. It represents a set of objects (or entities) that uses shared code/endpoints to perform tasks. 4 | 5 | This makes the Infinity Bot List API more generic and allows for reviews, voting etc. to work out-of-the-box for new systems like packs and s 6 | erver listing. 7 | 8 | The list of entities in the API are non-exhaustive. Some entities do not support all actions, or may support certain actions etc. 9 | 10 | - Users 11 | - Bots 12 | - Servers 13 | - Teams 14 | - Packs 15 | -------------------------------------------------------------------------------- /pages/docs/api/users.mdx: -------------------------------------------------------------------------------- 1 | import HTTPHeader from '../../../components/HTTPHeader'; 2 | 3 | # Users 4 | 5 | A user represents a Account used to Access/Login to our site. 6 | It is not associated with any other platform like Discord. 7 | However we do store some of your Discord User Info such as ID and Username. 8 | 9 | _Not all endpoints are documented here. See [here](https://spider.infinitybots.gg/docs#tag--Users) for more accurate documentation regarding users_ 10 | 11 | 12 | ## Get User 13 | 14 | 15 | 16 | Retrieves information about a particular user based on their User ID. 17 | 18 | --- 19 | 20 | ## Structure 21 | 22 | _The structure returned by this API is quite complex, large and always expanding. Please see [here](https://spider.infinitybots.gg/docs#get-/users/-id-) for a **much** more accurate documentation on all keys sent by this endpoint_ 23 | 24 | | Field | Type | Description | 25 | | ------------- | --------- | ---------------------------------------------- | 26 | | user. | `User` | The user object of the user on the site. | 27 | | about | `String?` | Some information about the User. | 28 | | certified | `Boolean` | The users IBL Certified Dev Status. | 29 | | bot_developer | `Boolean` | The users Bot Developer Status. | 30 | | staff | `Boolean` | If the User is IBL Staff (True or False). | 31 | | extra_links | `Array[Link]` | The extra links of a user | 32 | 33 | ## Example Response 34 | 35 | See [here](https://spider.infinitybots.gg/docs#get-/users/-id-) for an example response returned by this API. Note that it is quite large and combines data that was previously in seperate endpoints to reduce the number of required API requests. 36 | -------------------------------------------------------------------------------- /pages/docs/api/votes.mdx: -------------------------------------------------------------------------------- 1 | import HTTPHeader from '../../../components/HTTPHeader'; 2 | 3 | # Votes 4 | 5 | We offer a custom Voting System as a way for users to support their favorite [entities](./entity). 6 | 7 | Users can currently vote for a entity every 12 hours, with the exception of double vote time periods, with 6 hour cooldown periods, and premium entities, if the entity supports premium, with a 4 hours cooldown for these cases. 8 | 9 | See [our docs](https://spider.infinitybots.gg/docs#tag--Votes) for more accurate documentation regarding the endpoints provided by the voting API 10 | -------------------------------------------------------------------------------- /pages/docs/libraries/java.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Java 3 | --- 4 | 5 | # IBL4J 6 | 7 | Java Wrapper used for interacting with the Infinity Bots List API. 8 | 9 |
10 |

11 | 12 | JitPack 16 | 17 |

18 |
19 | 20 | ## Installation 21 | 22 | - Replace `VERSION` by the [latest release](https://github.com/Zone-Infinity/IBL4J/releases/) 23 | 24 | ### Maven 25 | 26 | ```xml 27 | 28 | jitpack.io 29 | https://jitpack.io 30 | 31 | ``` 32 | 33 | ```xml 34 | 35 | com.github.Zone-Infinity.IBL4J 36 | ibl4j 37 | VERSION 38 | 39 | 40 | 41 | com.github.Zone-Infinity.IBL4J 42 | ibl-library 43 | VERSION 44 | 45 | ``` 46 | 47 | ### Gradle 48 | 49 | ```xml 50 | maven { url 'https://jitpack.io' } 51 | ``` 52 | 53 | ```xml 54 | implementation 'com.github.Zone-Infinity:IBL4J:VERSION' 55 | ``` 56 | 57 | ## Post Method 58 | 59 | ```java 60 | // jda is your JDA instance 61 | IBLDiscordClient iblDiscordClient = new JDAClient(jda); 62 | 63 | IBL ibl = new IBLBuilder(iblDiscordClient, "IBL_TOKEN"); 64 | 65 | // Post only server count 66 | ibl.postServerCount(response -> { 67 | System.out.println(response.getMessage()); 68 | }); 69 | 70 | // Post server count and shard count 71 | ibl.postStats(response -> { 72 | System.out.println(response.getMessage()); 73 | }); 74 | ``` 75 | 76 | ## Auto Posting 77 | 78 | ```java 79 | // Post every 5 minutes 80 | ibl.autoPostStats(Executors.newSingleThreadExecutor(), response -> { 81 | System.out.println(response.getMessage()); 82 | }); 83 | 84 | // Post every `delay` in `timeunit` 85 | ibl.autoPostStats(Executors.newSingleThreadExecutor(), 5, TimeUnit.MINUTES, response -> { 86 | System.out.println(response.getMessage()); 87 | }); 88 | ``` 89 | 90 | ## Get method 91 | 92 | ### Get your bot data 93 | 94 | ```java 95 | // bot is me.infinity.ibl.data.entities.IBLBot instance. 96 | ibl.getStats(bot -> { 97 | // Votes 98 | System.out.println(bot.getAnalytics().getVotes()); 99 | // Short Description 100 | System.out.println(bot.getShortDescription()); 101 | }); 102 | ``` 103 | 104 | ### Get any Bots data 105 | 106 | ```java 107 | IBL.getBotStats("BOT_ID", bot -> { 108 | if(!bot.exists()) System.out.println("Bot doesn't exist on the list"); 109 | 110 | // Prefix 111 | System.out.println(bot.getPrefix()); 112 | // Github Link 113 | System.out.println(bot.getLinks().getGithub()); 114 | }); 115 | ``` 116 | 117 | ### Get any Users data 118 | 119 | ```java 120 | IBL.getUserInfo("USER_ID", user -> { 121 | if(!user.exists()) System.out.println("User doesn't exist on the list"); 122 | 123 | // Is a staff or not 124 | System.out.println(user.isStaff()); 125 | // User's Github 126 | System.out.println(user.getLinks().getGithub()); 127 | }); 128 | ``` 129 | -------------------------------------------------------------------------------- /pages/docs/libraries/javascript.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: JavaScript 3 | --- 4 | 5 | import HTTPHeader from '../../../components/HTTPHeader'; 6 | import { Tab, Tabs } from 'nextra-theme-docs' 7 | 8 | 9 | 10 | 11 | ## Infinity-Bots API 12 | 13 |
14 |

15 | 16 | npm installnfo 20 | 21 |

22 |
23 | 24 | This is our Official NPM Module used for Posting and Getting Stats. 25 | 26 | --- 27 | 28 | ### Installation 29 | 30 | `npm i infinity-bots@latest` 31 | 32 | --- 33 | 34 | ### Links 35 | 36 | - Support: [Join our Discord](https://botlist.site/discord) 37 | 38 | --- 39 | 40 | ### postBotStats() 41 | 42 | ```jsx 43 | const poster = new InfinityBots('AUTH_TOKEN', client.user.id); 44 | 45 | await poster.postBotStats({ 46 | servers: client.guilds.cache.size, 47 | shards: '0', 48 | }).catch((err) => { 49 | return console.log(`Error occured while posting stats: ${err.stack}`); 50 | }); 51 | 52 | console.log('Posted stats to Infinity Bot List!'); 53 | ``` 54 |
55 | 56 | 57 | ## Auto-Poster 58 | 59 |
60 |

61 | 62 | npm installnfo 66 | 67 |

68 |
69 | 70 | This is our Official NPM Module used for posting Server and Shard Count Stats. 71 | 72 | > Note: This Module will post stats every 5 Minutes 73 | 74 | --- 75 | 76 | ### Installation 77 | 78 | `npm i ibl-autopost@latest` 79 | 80 | --- 81 | 82 | ### Links 83 | 84 | - Support: [Join our Discord](https://botlist.site/discord) 85 | 86 | --- 87 | 88 | ### Supported Librarys 89 | 90 | - Discord.js 91 | - Eris 92 | 93 | --- 94 | 95 | ### Example 96 | 97 | ```jsx 98 | const { InfinityAutoPoster } = require('ibl-autopost'); 99 | 100 | const poster = InfinityAutoPoster('auth_token', client); // your discord.js or eris client 101 | 102 | // Optional Logger 103 | poster.on('posted', (stats) => { 104 | console.log( 105 | `Posted stats to the Infinity Bot List API | ${stats.servers} servers`, 106 | ); 107 | }); 108 | ``` 109 | 110 | --- 111 | 112 | ### Example Error 113 | 114 | ```jsx 115 | const { InfinityAutoPoster } = require('ibl-autopost'); 116 | 117 | const poster = InfinityAutoPoster('auth_token', client); // your discord.js or eris client 118 | 119 | // Optional Logger 120 | poster.on('error', (err) => { 121 | console.log(err); 122 | }); 123 | ``` 124 |
125 | 126 | 127 | ## Webhooks 128 | 129 |
130 |

131 | 132 | npm installnfo 136 | 137 |

138 |
139 | 140 | This is our Official NPM Module used for tracking Votes to a Custom Webhook. 141 | 142 | --- 143 | 144 | ### Installation 145 | 146 | `npm i infinity-bots@latest` 147 | 148 | --- 149 | 150 | ### Links 151 | 152 | - Support: [Join our Discord](https://botlist.site/discord) 153 | 154 | --- 155 | 156 | ### Getting Started 157 | 158 | Interacting with your Custom Webhooks is simple. 159 | Follow the steps listed below and you should have no issues! 160 | 161 | 1. Head to your Bots Edit Page on our Website 162 | 2. Find the "Custom Webhooks URL" Section 163 | 3. Paste your Server Link and Auth Token 164 | 165 | ![Example](https://media.discordapp.net/attachments/653733403841134600/912823693703512134/IMG_1383.png) 166 | 167 | --- 168 | 169 | ### Response Paramaters 170 | 171 | | Param | Description | 172 | | --------- | ------------------------------------------------------------------------- | 173 | | botID | The Discord ID (Snowflake) for the Bot who Recieved a Vote | 174 | | userID | The Discord ID (Snowflake) of the User who Voted | 175 | | userName | The Username of the User who Voted | 176 | | count | The Bots new Vote Count | 177 | | timestamp | The Date and Time of the Vote | 178 | | type | The TYPE of Request (Should always be "VOTE" or "TEST" for test Requests) | 179 | 180 | --- 181 | 182 | ### Example (Express) 183 | 184 | ```jsx 185 | const express = require('express') 186 | const Infinity = require('infinity-bots') 187 | 188 | const app = express() // Your express app 189 | 190 | const webhook = new Infinity.Webhook('Some_Auth_Token') // Add your Webhooks Auth Token 191 | 192 | app.post('/votes', webhook.hookListener(async (vote, req, res) => { 193 | 194 | let client = req.app.get('client') 195 | 196 | let voteLog = new MessageEmbed() 197 | .setTitle('⬆️ UpVote Logs') 198 | .setColor('#0EFF00') 199 | .setDescription(`Somone has voted for me on [Infinity Bot List](https://infinitybotlist.com/bots/BOT_ID/vote)`) 200 | .addField('User', `${vote.userName}`, true) 201 | .addField('User ID', `${vote.userID}`, true 202 | .setTimestamp() 203 | 204 | await client.guilds.cache.get('Some_Server_ID').channels.cache.get('Some_Channel_ID').send({ embeds: [voteLog] }); 205 | 206 | })) 207 | 208 | app.listen(3000) // your port 209 | 210 | ``` 211 | 212 | --- 213 | 214 | ### Example (Fastify) 215 | 216 | ```jsx 217 | const Infinity = require('infinity-bots'); 218 | 219 | const webhook = new Infinity.Webhook('Some_Auth_Token') 220 | 221 | const voteHook = (fastify, options, done) => { 222 | 223 | fastify.post("/vote", webhook.hookListener(async (vote, req, res) => { 224 | 225 | let client = req.client 226 | 227 | let voteLog = new MessageEmbed() 228 | .setTitle('⬆️ UpVote Logs') 229 | .setColor('#0EFF00') 230 | .setDescription(`Somone has voted for me on [Infinity Bot List](https://infinitybotlist.com/bots/BOT_ID/vote)`) 231 | .addField('User', `${vote.userName}`, true) 232 | .addField('User ID', `${vote.userID}`, true 233 | .setTimestamp() 234 | 235 | await client.guilds.cache.get('Some_Server_ID').channels.cache.get('Some_Channel_ID').send({ embeds: [voteLog] }); 236 | 237 | })); 238 | 239 | done() 240 | }; 241 | ``` 242 |
243 | 244 | ## Voting Module 245 | 246 |
247 |

248 | 249 | npm installnfo 253 | 254 |

255 |
256 | 257 | This is our Official NPM Module used for interacting with your bots Votes. 258 | 259 | --- 260 | 261 | ### Installation 262 | 263 | `npm i infinitybots-votes.js@latest` 264 | 265 | --- 266 | 267 | ### Links 268 | 269 | - Support: [Join our Discord](https://botlist.site/discord) 270 | 271 | --- 272 | 273 | ### checkUserVoted() 274 | 275 | ###### Response Paramaters 276 | 277 | | Param | Description | 278 | | -------- | --------------------------------------------------------- | 279 | | hasVoted | If the User has Voted in the last 6 Hours (True or False) | 280 | 281 | --- 282 | 283 | ### Example Usage 284 | 285 | ```jsx 286 | const { MessageEmbed } = require('discord.js'); 287 | const moment = require('moment'); 288 | const fetch = require('node-fetch'); 289 | 290 | const IBLVotes = require('infinitybots-votes.js'); 291 | const voteData = new IBLVotes() 292 | 293 | module.exports.run = async (client, message, args, params) => { 294 | 295 | let user = message.mentions.members.first() || client.users.cache.get(args[0]); 296 | 297 | if (!user) return message.channel.send("Please provide a user to check if the have voted"); 298 | 299 | await voteData.checkUserVoted(client.user.id, user.id, function(data) { 300 | 301 | if (data.hasVoted) { 302 | 303 | let embed = new MessageEmbed() 304 | .setTitle('Vote Check') 305 | .setColor('GREEN') 306 | .setDescription(`<@!${user.id}> has voted within the last 6 Hours!`) 307 | 308 | return message.channel.send(embeds: [embed]) 309 | 310 | } else { 311 | 312 | let embed = new MessageEmbed() 313 | .setTitle('Vote Check') 314 | .setColor('RED') 315 | .setDescription(`<@!${user.id}> has not voted within the last 6 Hours!`) 316 | 317 | 318 | return message.channel.send(embeds: [embed]) 319 | } 320 | }) 321 | } 322 | 323 | module.exports.help = { 324 | name: 'has-voted', 325 | category: 'owner', 326 | aliases: ['cv', 'check-voted'], 327 | description: 'Check if a User has Voted', 328 | example: '``has-voted``' 329 | } 330 | 331 | module.exports.requirements = { 332 | userPerms: [], 333 | clientPerms: ['SEND_MESSAGES', 'EMBED_LINKS'], 334 | ownerOnly: true, 335 | } 336 | 337 | module.exports.limits = { 338 | rateLimit: 2, 339 | cooldown: 1e4 340 | } 341 | 342 | ``` 343 |
344 |
345 | -------------------------------------------------------------------------------- /pages/docs/libraries/python.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Python 3 | --- 4 | 5 | # IBL.py 6 | 7 | Using IBLPy is easy. Here, we will assume you are just using this to post stats using our autoposter and a webhook. The first thing you will need to do is create a Bot Client. A Bot Client is the base of all bot operations on IBLPy (there is also a User Client as the base of all user operations on IBLPy). 8 | 9 | You can create a Bot Client like this:: 10 | 11 | ```python 12 | ibl = IBLPy.BotClient(id = bot_id, api_token = api_token_here) 13 | ``` 14 | 15 | Replace bot_id and api_token_here with your bots ID and the api token (you don't have to give your api token and you can remove this parameter altogether if you just need to get the bot, but for autoposting and stat posting, you need to provide an API Token) 16 | 17 | Next setup discord.py normally (with a `on_ready` event). You will get something like this (the exact discord.py Client you use may be different):: 18 | 19 | ```python 20 | ibl = IBLPy.BotClient(id = bot_id, api_token = api_token_here) 21 | client = discord.Client() 22 | 23 | @client.event 24 | async def on_ready(): 25 | # This part is important, make sure you have a on_ready event like this 26 | # Autoposting and webhooks will be done in this function/event 27 | 28 | client.run(BOT_TOKEN) 29 | ``` 30 | 31 | The `on_ready` event is where we will do our autoposting and webhooks. If you are not using discord.py, please check the Documentation for which functions you have to use.) 32 | 33 | ## Posting Stats Manually 34 | 35 | In most cases, you will want to use autoposting to do this, but you `can` do it manually like below:: 36 | 37 | ```python 38 | ibl = IBLPy.BotClient(id = bot_id, api_token = api_token_here) 39 | 40 | res = await ibl.set_stats(guild_count = guild_count_here, shard_count = shard_count_here) # Asynchronous, needs to be in an async function 41 | 42 | if res.success: 43 | print("Success") 44 | else: 45 | print("Fail") 46 | ``` 47 | 48 | --- 49 | 50 | ## Autoposting 51 | 52 | In order to setup autoposting, we need to create an AutoPoster inside our `on_ready` function. To do so, add something like the below code snippet to your `on_ready` function:: 53 | 54 | ap = IBLPy.AutoPoster(interval = 300, botcli = ibl, discli = client, on_post = None, sharding = False) 55 | ap.start() # Starts the autoposter in the background 56 | 57 | If you run this right now, you will see that it does post stats every 5 minutes and also logs it. Log configuration ia upcoming and will use logging. You can use `ap.stop()` to stop an AutoPoster. The interval must be in seconds and if it is below the 5 minutes or 300 seconds above, it will automatically be set to 5 minutes. This is to prevent ratelimits, which are strict on IBL 58 | 59 | --- 60 | 61 | ## Webhooks 62 | 63 | Since webhooks are blocking, you must put it at the end of your `on_ready` function or nothing below it in `on_ready` will be executed. To setup webhooks, add something like the below code snippet to your `on_ready` function:: 64 | 65 | ```python 66 | wh = IBLPy.Webhook(botcli = ibl, secret = "YOUR WEBHOOK SECRET", coro = get_vote) 67 | wh.start_ws_task(route = "/ibl/webhook", port = 8016) 68 | ``` 69 | 70 | The webhook secret is the one you configured in IBL, use None if you don't want to use one (not recommended as this allows anyone to POST to your webhook freely including non-IBL users). IBLPy will check the webhook secret sent against what is givenand will return a 401 status code (and not call your vote function) is the secret is invalid thus allowing only IBL to POST to your webhook. 71 | 72 | The route parameter below is what route to use for your webhook, coro is the async coroutine to run when you get a vote and must be awaitable and must accept a vote parameter containing the vote and a secret parameter (which will be sent for extra verification) 73 | 74 | The port parameter is the port the webhook should listen at (the below webhook is running at http://0.0.0.0:8016/ibl/webhook). You can now tunnel/reverse proxy this and add your webhook to IBL. 75 | 76 | If you run this now, you will have discord.py, autoposting and webhooks working simultaneously! You're done! 77 | 78 | --- 79 | 80 | ## Getting A Bot 81 | 82 | IBLPy makes it easy to get a bot from the API and parses it for you in a easy to use format of :class:`~IBLPy.base_fn.IBLBot`. To use this, create a Bot Client of the bot you want to get (with or without the API token). Then call `get_bot` like below:: 83 | 84 | ```python 85 | ibl = IBLPy.BotClient(id = bot_id, api_token = api_token_here) 86 | 87 | bot = await ibl.get_bot() # Asynchronous, needs to be in an async function 88 | 89 | print(str(bot)) 90 | ``` 91 | -------------------------------------------------------------------------------- /pages/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Home 3 | --- 4 | 5 | import Home from '../components/Home'; 6 | 7 | 8 | -------------------------------------------------------------------------------- /pages/resources/downtime.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Downtime 3 | --- 4 | 5 | import { Callout } from 'nextra-theme-docs' 6 | 7 | 8 | Downtime Detection is currently not yet working and is still a work-in-progress 9 | 10 | 11 | # Downtime Handler 12 | 13 | Our API implements a process of checking a bots uptime in a periodic basis, however this is not finalized yet and so is not yet documented here. 14 | 15 | The percentage system however is finalized as the below formula (in JavaScript) 16 | 17 | ```jsx 18 | let percent = (bot.uptime / bot.total_uptime) * 100; 19 | ``` 20 | 21 | --- 22 | 23 | ## Exceeding the Downtime Percentage 24 | 25 | While Infinity Bot List *used* to delete bots for having too low an uptime, this is currently no longer the case and is being rethought 26 | -------------------------------------------------------------------------------- /pages/resources/ratelimits.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Ratelimits 3 | --- 4 | 5 | # Ratelimits 6 | 7 | Our API implements a process for limiting and preventing spam requests. 8 | API users that regularly hit and ignore the limit will be blocked from our platform. 9 | These rate limits are in place to help prevent the abuse and overload of our services. 10 | 11 | --- 12 | 13 | **As of v4, all ratelimits including global ratelimits are dynamic and can be added/removed at _any_ time as we require** 14 | 15 | - Not all endpoints may return these headers however these may still have ratelimits. 16 | - A number for the purpose of the below table is defined as a number stringified 17 | 18 | ## Rate Limit Header Structure 19 | 20 | | Field | Type | Description | 21 | | -------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | 22 | | retry-after | `Number` | Amount of time until the Rate Limit Expires. Learn more about this header [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) | 23 | 24 | --- 25 | 26 | ## Rate Limit Response Structure 27 | 28 | | Field | Type | Description | 29 | | ------- | -------- | ---------------------------------------------------------------------------------------- | 30 | | message | `String` | Error Message for the Rate Limit Response. This is a constant as per below and is static | 31 | | error | `Bool` | Whether or not this is an error response. This is a constant as per below and is static | 32 | 33 | ## Example Rate Limit Response 34 | 35 | ```json 36 | { 37 | "message": "....!", 38 | "error": true 39 | } 40 | ``` 41 | 42 | Clients are expected to use the `Retry-After` header. Ratelimit responses are now static to improve performance 43 | -------------------------------------------------------------------------------- /pages/resources/references.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: References 3 | --- 4 | 5 | import HTTPHeader from '../../components/HTTPHeader'; 6 | 7 | ## Link 8 | 9 | A link represents a link on the list. 10 | 11 | | Field | Type | Description | 12 | | -------------------------------------- | -------- | -------------------- | 13 | | name | `String` | The name of the link | 14 | | value | `String` | The value of the link | 15 | 16 | **Example** 17 | 18 | ```json 19 | {"name": "Name of the link", "value": "http://example.com"} 20 | ``` 21 | 22 | --- -------------------------------------------------------------------------------- /pages/resources/usage.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: API Usage 3 | --- 4 | 5 | # API Usage 6 | 7 | If you prefer to interact with our raw API instead of using a Third Party Module 8 | you can follow the usage guides and examples below which should be more then enough to 9 | get you started xD 10 | 11 | --- 12 | 13 | ## Javascript Usage 14 | 15 | ```jsx 16 | const fetch = require('node-fetch'); 17 | fetch(`https://spider.infinitybots.gg/bots/stats`, { 18 | method: 'POST', 19 | headers: { 20 | "Authorization": 'api-key-here', 21 | 'Content-Type': 'application/json', 22 | }, 23 | body: JSON.stringify({ 24 | servers: 100, 25 | shards: 69, 26 | }), 27 | }).then(async (res) => console.log(await res.json())); 28 | ``` 29 | 30 | --- 31 | 32 | ## Python Usage 33 | 34 | ```python 35 | import aiohttp 36 | 37 | # In a async function 38 | async def post_stats(): 39 | async with aiohttp.ClientSession() as sess: 40 | headers= { 41 | "Authorization": "Your api token", 42 | } 43 | json={ 44 | "servers": len(bot.guilds) or 0, # Change this if you use custom clustering 45 | "shards": bot.shard_count or 0 # Change this if you use custom clustering 46 | } 47 | async with sess.post(f"https://spider.infinitybots.gg/bots/stats", headers=headers, json=json) as res: 48 | # Do something with the response. EX 49 | # if res.status == 200: 50 | # ... 51 | ``` 52 | -------------------------------------------------------------------------------- /pages/resources/webhooks.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Webhooks 3 | --- 4 | 5 | # Webhooks 6 | 7 | **Users who just want to log events to discord should note that Infinity Bot List supports Discord Webhooks for all events. It's actually mandatory for a webhook event to also have an associated discord webhook in order to be considered an event!** 8 | 9 | Infinity Bot List supports a webhooks system (that is still a constant work in progress however) for getting real-time updates and information about an [entity](./entity). 10 | 11 | This includes, but is not limited to: 12 | 13 | - Bot votes 14 | - New bot reviews 15 | - Updates on bot reviews 16 | - Edits to a team (name and avatar only at this time) 17 | 18 | **Note:** More events will be added. Lots of our time was spent ensuring a sane webhooks experience for our users. 19 | 20 | If you need help setting up custom webhooks inside of your bot or web server don't be afraid to ask in our [discord server](https://infinitybotlist.com/join) in the `》api-support` channel. 21 | 22 | --- 23 | 24 | ## IBL Funnels 25 | 26 | To make setting up custom webhooks easier, Infinity Bot List provides `IBL Funnels` which is a (locally-ran/self-hosted) service that automatically handles the authentication bits for you, then sends them to either a/an (firewall'd) local webserver of your choice OR to a script or executable that you define. This means, you just need to handle the raw event (as JSON) with all the authentication handled for you! 27 | 28 | You will need iblcli to be downloaded first. Download this from [seedguide](https://infinitybots.gg/help/contribute/seedguide) for your OS and CPU architecture. *Ignore the seeding stuff as that is irrelevant and will be removed once our Developer Docs are a bit better.* 29 | 30 | Next, run `ibl funnel setup`, login when prompted by following the onscreen prompts and opening the OAuth2 URL when prompted. After logging in, set a port that the webhook will listen on and the domain at which Infinity Bot List will POST to the webhook by following the onscreen instructions and selecting the correct options. 31 | 32 | Ladtly, create the funnels for your entity and you're all set! For forwards to, provide a script/executable that IBL should call with the webhook data in the ``DATA`` environment variable or a (local/on-server) webserver that `iblcli` will send the data to after authentication. 33 | 34 | Note that `iblcli` will handle all the painful stuff like setting up the webhook config on the site using the P`atch Webhook` API for the tntity. It will also generate a random webhook secret as well. 35 | 36 | Once you're ready, run `ibl funnel start` and voila, everything should just work!!! 37 | 38 | 39 | --- 40 | 41 | ## Manual setup 42 | 43 | If you wish to use a custom webhook server without using IBL Funnels, you can! 44 | 45 | Firstly, start by setting up the webhook URL by either going to Settings > Webhooks for the entity OR by using the `Patch Webhook` API endpoint for the entity in question directly. 46 | 47 | ### Authenticating webhooks 48 | 49 | So now that you have a webhook added to the site. You now need to authorize/authenticate the webhook and decrypt the data in order to handle it. **Note that Infinity Bot List WILL, from time to time, randomly send 'bad intent webhooks' to you to ensure that you are correctly handling security. Any webhooks that cannot be correctly parsed MUST be responded with a status code of 403 or the webhook WILL be automatically deleted during a 'bad intent' test run** 50 | 51 | *Note that all examples are provided in JS as of right now*. 52 | 53 | 1a. Check the protocol version: 54 | - The current protocol version is `splashtail` 55 | - Check the `X-Webhook-Protocol` header and ensure that it is equal to the current protocol version 56 | 57 | ```js 58 | const supportedProtocol = 'splashtail' 59 | if (req.headers["x-webhook-protocol"] != supportedProtocol) { 60 | reply.status(403).send({ 61 | message: "Invalid protocol version!", 62 | }); 63 | return; 64 | } 65 | ``` 66 | 67 | 1b. A nonce is used to randomize the signature for retries. Ensure a nonce exists by checking the header's existence: 68 | 69 | ```js 70 | if (!req.headers["x-webhook-nonce"]) { 71 | reply.status(403).send({ 72 | message: "No nonce provided?", 73 | }); 74 | return; 75 | } 76 | ``` 77 | 78 | 2. Next calculate the expected signature 79 | - To do so, you must first get the body of the request 80 | - Then use HMAC-SHA512 with the webhook secret as key and the body as the request body to get the ``signedBody``. Note that the format/digest should be ``hex`` 81 | - Then use HMAC-SHA512 with the nonce as the key and the signed body as the message to get the expected signature. Note that the format/digest should be ``hex`` 82 | 83 | ```js 84 | let body: string = req.body; 85 | 86 | if (!body) { 87 | reply.status(400).send({ 88 | message: "No request body provided?", 89 | }); 90 | return; 91 | } 92 | 93 | // Create hmac 512 hash 94 | let signedBody = crypto 95 | .createHmac("sha512", webhookSecret) 96 | .update(body) 97 | .digest("hex"); 98 | 99 | // Create the actual signature using x-webhook-nonce by performing a second hmac 100 | let nonce = req.headers["x-webhook-nonce"].toString(); 101 | let expectedTok = crypto 102 | .createHmac("sha512", nonce) 103 | .update(signedBody) 104 | .digest("hex"); 105 | ``` 106 | 107 | 3. Compare this value with the ``X-Webhook-Signature`` header 108 | - If they are equal, the request is valid and you can continue processing it 109 | - If they are not equal, the request is invalid and you should return a 403 status code 110 | 111 | ```js 112 | if (req.headers["x-webhook-signature"] != expectedTok) { 113 | console.log( 114 | `Expected: ${expectedTok} Got: ${req.headers["x-webhook-signature"]}` 115 | ); 116 | reply.status(403).send({ 117 | message: "Invalid signature", 118 | }); 119 | return; 120 | } 121 | ``` 122 | 123 | 4. Next decrypt the request body. This is both an additional security to prevent sensitive information from being leaked and also ensures that the webhook has been implemented with a decent level of security on your server 124 | - First hash the concatenation of the webhook secret and the nonce using SHA256 125 | - Then read the body as a hex string and decrypt it using AES-256-GCM with the hashed secret as the key 126 | 127 | ```js 128 | // sha256 on key 129 | let hashedKey = crypto 130 | .createHash("sha256") 131 | .update(webhookSecret + nonce) 132 | .digest(); 133 | 134 | let enc = Buffer.from(body, "hex"); 135 | const tag = enc.subarray(enc.length - tagLength, enc.length); 136 | const iv = enc.subarray(0, ivLength); 137 | const toDecrypt = enc.subarray(ivLength, enc.length - tag.length); 138 | const decipher = crypto.createDecipheriv("aes-256-gcm", hashedKey, iv); 139 | decipher.setAuthTag(tag); 140 | const res = Buffer.concat([decipher.update(toDecrypt), decipher.final()]); 141 | 142 | // Parse the decrypted body 143 | let data = JSON.parse(res.toString("utf-8")); 144 | ``` 145 | 146 | --- 147 | 148 | ### Timeout 149 | 150 | The timeout applied to webhooks is not stable or defined here in order to protect against Denial Of Service attacks by slow clients. However, the maximum response time of your server in accepting, authenticating and performing (initial) processing of an event should be a maximum of 10 seconds under peak load and in general should be lower than that. 151 | 152 | If you need to perform a long-running task upon recieving an event, you may need to use a background task (goroutines, asyncio tasks, etc) to meet this. 153 | 154 | ### Acknowledgement 155 | 156 | - Webhooks sent by Infinity Bot List **must** be acknowledged with a `2XX` status response (like 200 or 204) in order to be considered successful. 157 | - Unsuccessful webhooks will trigger a [retry](#retrial). 158 | 159 | ### Retrials and deletions 160 | 161 | - Webhook requests that time out or return a `5XX` status response (like 500) will be retried up to 10 times. 162 | - Errors resulting with status `4XX` (400, 422 etc.) will not be retried for obvious reasons. 163 | - **Webhooks resulting in a status code of 404 or 410 will be automatically deleted, regardless of whether it is a 'bad intent' webhook or not** 164 | - **Webhooks that respond with a `2XX` status code to a 'bad intent' webhook will automatically deleted for not properly handling authentication** 165 | - *The above list is non-exhaustive* 166 | 167 | ### Data Format 168 | 169 | See [webhook events](https://spider.infinitybots.gg/docs#tag--Webhooks) for the exact data format to expect for a custom webhook. 170 | -------------------------------------------------------------------------------- /pages/resources/weekends.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Weekends 3 | --- 4 | 5 | # Weekends 6 | 7 | Infinity Bots implements a method for registering Votes handled on a Weekend. 8 | Any votes on `Fri-Sun` will count as double with a reduced ratelimit! 9 | 10 | --- 11 | 12 | ## Vote Limits Table 13 | 14 | | Limit | Description | weekend | premium | 15 | | ----- | ------------ | --------- | ------- | 16 | | 4 | 4 hours | false | true | 17 | | 6 | 6 Hours | true | false | 18 | | 12 | 12 Hours | false | false | 19 | 20 | --- -------------------------------------------------------------------------------- /pages/resources/widgets.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Widgets 3 | --- 4 | 5 | import { Bleed } from 'nextra-theme-docs' 6 | 7 | # Widgets 8 | 9 | Embeds or "Widgets" are images that can display your bots stats on your own website! On this page we will tell you how to access and customize them. 10 | 11 | --- 12 | 13 | ## Usage 14 | 15 | To use the embed, you can insert the following link as an IFrame or Image into your website / documentation. 16 | 17 | ### Iframe 18 | 19 | ```markdown 20 |