├── public ├── static │ ├── .gitkeep │ ├── css │ │ └── custom.css │ ├── img │ │ ├── yt_plvideo1.png │ │ └── yt_latestvideo1.png │ ├── yaml │ │ ├── endpoints │ │ │ ├── ffz.yaml │ │ │ ├── bttv.yaml │ │ │ ├── math.yaml │ │ │ ├── random.yaml │ │ │ ├── example.yaml │ │ │ ├── dayz.yaml │ │ │ ├── misc.yaml │ │ │ ├── steam.yaml │ │ │ ├── youtube.yaml │ │ │ └── twitch.yaml │ │ └── base │ │ │ └── base_endpoints.yaml │ └── public-key-alex@thomassen.sh.asc ├── robots.txt └── index.html ├── .eslintignore ├── .browserslistrc ├── src ├── assets │ └── logo.png ├── config.js ├── main.js ├── store │ └── index.js ├── components │ ├── Contact.vue │ ├── Cached.vue │ ├── Changelog.vue │ ├── Home.vue │ └── EndpointList.vue ├── router │ └── index.js └── App.vue ├── babel.config.js ├── .gitattributes ├── README.md ├── .gitignore ├── .editorconfig ├── netlify.toml ├── .eslintrc.js ├── package.json └── LICENSE /public/static/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | -------------------------------------------------------------------------------- /public/static/css/custom.css: -------------------------------------------------------------------------------- 1 | .cursor-pointer { 2 | cursor: pointer; 3 | } -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decicus/DecAPI-Docs/HEAD/src/assets/logo.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset', 4 | ], 5 | }; 6 | -------------------------------------------------------------------------------- /public/static/img/yt_plvideo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decicus/DecAPI-Docs/HEAD/public/static/img/yt_plvideo1.png -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.html text eol=lf 2 | *.js text eol=lf 3 | *.yaml text eol=lf 4 | *.vue text eol=lf 5 | *.json text eol=lf -------------------------------------------------------------------------------- /public/static/img/yt_latestvideo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Decicus/DecAPI-Docs/HEAD/public/static/img/yt_latestvideo1.png -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | baseUrl: 'https://decapi.me', 3 | discordUrl: 'https://decapi.link/discord', 4 | }; 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DecAPI-Docs 2 | Docs for DecAPI 3 | 4 | ## Links 5 | - [Documentation for DecAPI (website loaded from this repo)](https://docs.decapi.me/) 6 | - [DecAPI's source code](https://github.com/Decicus/DecAPI) 7 | 8 | ## License 9 | [MIT License](LICENSE) 10 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import App from './App.vue'; 3 | import router from './router'; 4 | import store from './store'; 5 | 6 | Vue.config.productionTip = false; 7 | 8 | new Vue({ 9 | router, 10 | store, 11 | render: (h) => h(App), 12 | }).$mount('#app'); 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*.{html,js,yaml,md,vue}] 5 | end_of_line = lf 6 | indent_style = space 7 | indent_size = 4 8 | charset = utf-8 9 | insert_final_newline = true 10 | 11 | [*.{html,js,yaml,vue}] 12 | trim_trailing_whitespace = true 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | # Netlify is no longer being used by the project. 2 | # However, I am keeping this here in case others want to host their own instance via Netlify :) 3 | [[redirects]] 4 | from = "/*" 5 | to = "/index.html" 6 | status = 200 7 | 8 | [[headers]] 9 | for = "/*" 10 | [headers.values] 11 | X-Frame-Options = "DENY" 12 | X-XSS-Protection = "1; mode=block" 13 | X-Content-Type-Options = "nosniff" -------------------------------------------------------------------------------- /public/static/yaml/endpoints/ffz.yaml: -------------------------------------------------------------------------------- 1 | base_path: "/ffz" 2 | endpoints: 3 | - route: "emotes/:channel" 4 | parameters: 5 | - name: ":channel" 6 | description: "The channel name of the channel to retrieve FrankerFaceZ emotes from." 7 | qs: 8 | - name: 'separator' 9 | description: "The character(s) that should separate each emote. By default it's a single space character." 10 | notes: 11 | - "Returns a list (space-separated by default) of FrankerFaceZ channel emotes available in the channel." 12 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | extends: ["plugin:vue/essential", "@vue/airbnb"], 7 | parserOptions: { 8 | parser: "babel-eslint" 9 | }, 10 | rules: { 11 | "no-console": process.env.NODE_ENV === "production" ? "warn" : "off", 12 | "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off", 13 | indent: ["error", 4], 14 | 'max-len': ['error', { 15 | code: 250, 16 | ignoreUrls: true, 17 | }], 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /public/static/yaml/endpoints/bttv.yaml: -------------------------------------------------------------------------------- 1 | base_path: "/bttv" 2 | endpoints: 3 | - route: "emotes/:channel" 4 | parameters: 5 | - name: ":channel" 6 | description: "The channel to retrieve BetterTTV emotes for" 7 | qs: 8 | - name: "types" 9 | description: 'Comma-separated list of image types you wish to include. 10 |
11 | Currently available: gif or png. Default: all. 12 |
13 | Specifying all will override any other specified type.' 14 | notes: 15 | - "Returns a space-separated list of BetterTTV channel emotes available in the channel." 16 | -------------------------------------------------------------------------------- /public/static/yaml/base/base_endpoints.yaml: -------------------------------------------------------------------------------- 1 | - name: bttv 2 | title: "BetterTTV" 3 | icon: "smile far" 4 | - name: dayz 5 | title: "DayZ" 6 | icon: "gamepad fas" 7 | - name: ffz 8 | title: "FrankerFaceZ" 9 | icon: "smile far" 10 | - name: math 11 | title: "Math" 12 | icon: "calculator fas" 13 | - name: misc 14 | title: "Miscellaneous" 15 | - name: random 16 | title: "Random" 17 | icon: "random fas" 18 | - name: steam 19 | title: "Steam" 20 | icon: "steam fab" 21 | - name: twitch 22 | title: "Twitch" 23 | icon: "twitch fab" 24 | - name: twitter 25 | title: "Twitter" 26 | icon: "twitter fab" 27 | removed: true 28 | - name: youtube 29 | title: "YouTube" 30 | icon: "youtube fab" 31 | -------------------------------------------------------------------------------- /public/static/yaml/endpoints/math.yaml: -------------------------------------------------------------------------------- 1 | base_path: "/math" 2 | endpoints: 3 | - route: "" 4 | qs: 5 | - name: "exp" 6 | description: "The mathematic expression to receive the result from." 7 | required: true 8 | - name: "round" 9 | description: "If specified, it will round to the nearest whole number, but only if there is no value specified or the value specified is 0 or less. Default: 0 (if specified with no value)." 10 | type: "none/int" 11 | notes: 12 | - 'Performs a mathematic operation based on the expression passed to the endpoint.' 13 | - 'Keep in mind to properly URL-encode exp, so that certain characters (such as +) are handled correctly.' 14 | -------------------------------------------------------------------------------- /public/static/yaml/endpoints/random.yaml: -------------------------------------------------------------------------------- 1 | base_path: "/random" 2 | endpoints: 3 | - route: "number/:min/:max" 4 | parameters: 5 | - name: ":min" 6 | description: "The minimum number the result can be - Default: 0." 7 | type: "int" 8 | - name: ":max" 9 | description: "The maximum number the result can be - Default: 100." 10 | type: "int" 11 | qs: 12 | - name: "format" 13 | description: 'If specified, number will be formatted using the default options of number_format()' 14 | notes: 15 | - 'Picks a random number between :min and :max.' 16 | - 'This only uses rand() and should not be used if you want a "truly random" number.' 17 | -------------------------------------------------------------------------------- /public/static/yaml/endpoints/example.yaml: -------------------------------------------------------------------------------- 1 | base_path: "/example" 2 | endpoints: 3 | - route: "sample/:channel/:user" 4 | parameters: 5 | - name: ":channel" 6 | description: "The channel name" 7 | - name: ":user" 8 | description: "The name of the user" 9 | optional: true 10 | qs: 11 | - name: "key=:api_key" 12 | description: "Your custom API key" 13 | - name: "limit=:number" 14 | description: "The limit of list entries - Max: 100" 15 | type: "int" 16 | notes: 17 | - "This is just an example note." 18 | - route: "test/:user" 19 | parameters: 20 | - name: ":user" 21 | description: "The name of the user" 22 | qs: 23 | - name: "limit=:number" 24 | description: "The limit of list entries" 25 | type: "int" 26 | notes: 27 | - "Retrieves information about the user." 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "decapi-docs", 3 | "version": "2.0.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "bootstrap": "^4.6.2", 12 | "core-js": "^3.46.0", 13 | "jquery": "^3.7.1", 14 | "js-yaml": "^3.14.1", 15 | "popper.js": "^1.16.1", 16 | "vue": "^2.7.16", 17 | "vue-resource": "^1.5.3", 18 | "vue-router": "^3.6.5", 19 | "vuex": "^3.6.2" 20 | }, 21 | "devDependencies": { 22 | "@vue/cli-plugin-babel": "~4.5.12", 23 | "@vue/cli-plugin-eslint": "^3.12.1", 24 | "@vue/cli-plugin-router": "~4.5.12", 25 | "@vue/cli-plugin-vuex": "~4.5.12", 26 | "@vue/cli-service": "^4.5.19", 27 | "@vue/eslint-config-airbnb": "^5.3.0", 28 | "babel-eslint": "^10.1.0", 29 | "eslint": "^6.8.0", 30 | "eslint-plugin-import": "^2.32.0", 31 | "eslint-plugin-vue": "^6.2.2", 32 | "vue-template-compiler": "^2.7.16" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import VueResource from 'vue-resource'; 3 | import Vuex from 'vuex'; 4 | import yaml from 'js-yaml'; 5 | 6 | Vue.use(VueResource); 7 | Vue.use(Vuex); 8 | 9 | const store = new Vuex.Store({ 10 | state: { 11 | baseEndpoints: [], 12 | }, 13 | actions: { 14 | LOAD_BASE_ENDPOINTS({ commit }) { 15 | Vue.http 16 | .get('/static/yaml/base/base_endpoints.yaml') 17 | .then(({ body }) => { 18 | const baseEndpoints = yaml.load(body); 19 | commit('UPDATE_BASE_ENDPOINTS', { 20 | baseEndpoints, 21 | }); 22 | }); 23 | }, 24 | }, 25 | mutations: { 26 | UPDATE_BASE_ENDPOINTS: (state, { baseEndpoints }) => { 27 | state.baseEndpoints = baseEndpoints; 28 | }, 29 | }, 30 | getters: { 31 | getBase(state) { 32 | return state.baseEndpoints; 33 | }, 34 | }, 35 | }); 36 | 37 | export default store; 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-2021 Alex Thomassen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | DecAPI Docs 9 | 10 | 11 | 12 | 26 | 27 | 28 | 29 | 30 |
31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/components/Contact.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 35 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import VueResource from 'vue-resource'; 3 | import Router from 'vue-router'; 4 | import yaml from 'js-yaml'; 5 | import EndpointList from '../components/EndpointList.vue'; 6 | import Home from '../components/Home.vue'; 7 | import Changelog from '../components/Changelog.vue'; 8 | import Contact from '../components/Contact.vue'; 9 | import CachedEndpoints from '../components/Cached.vue'; 10 | 11 | Vue.use(Router); 12 | Vue.use(VueResource); 13 | 14 | const router = new Router({ 15 | mode: 'history', 16 | routes: [ 17 | { 18 | path: '/', 19 | name: 'Home', 20 | component: Home, 21 | }, 22 | { 23 | path: '/changelog', 24 | name: 'Changelog', 25 | component: Changelog, 26 | }, 27 | { 28 | path: '/contact', 29 | name: 'Contact', 30 | component: Contact, 31 | }, 32 | { 33 | path: '/cached-endpoints', 34 | name: 'Cached endpoints', 35 | component: CachedEndpoints, 36 | }, 37 | ], 38 | }); 39 | const yamlPath = '/static/yaml'; 40 | 41 | Vue.http.get(`${yamlPath}/base/base_endpoints.yaml`).then((response) => { 42 | const baseEndpoints = yaml.load(response.body); 43 | const routes = []; 44 | baseEndpoints.forEach((base) => { 45 | const { title, name } = base; 46 | routes.push({ 47 | path: `/${name}`, 48 | name: title, 49 | component: EndpointList, 50 | }); 51 | }); 52 | 53 | router.addRoutes(routes); 54 | }); 55 | 56 | export default router; 57 | -------------------------------------------------------------------------------- /public/static/yaml/endpoints/dayz.yaml: -------------------------------------------------------------------------------- 1 | base_path: "/dayz" 2 | endpoints: 3 | - route: "izurvive" 4 | parameters: 5 | qs: 6 | - name: "search" 7 | description: "The location name to search for." 8 | required: true 9 | notes: 10 | - 'Searches for locations based on the search query string, and returns a location name together with a URL to the location on iZurvive.' 11 | - 'This is not always 100% correct. Sorry for any locations that may be incorrect.' 12 | - route: "news" 13 | parameters: 14 | qs: 15 | - name : "search" 16 | description: "Performs a case insensitive search on the news article title, to filter through them." 17 | notes: 18 | - 'Returns the latest news article from the DayZ website.' 19 | - route: "players" 20 | parameters: 21 | qs: 22 | - name: "ip" 23 | description: "The IP address of the server." 24 | required: true 25 | - name: "port" 26 | description: "The connect port of the server." 27 | required: true 28 | type: "int" 29 | - name: "query" 30 | description: "The query port of the server." 31 | required: true 32 | type: "int" 33 | notes: 34 | - 'Queries the specified DayZ server and returns a player count in format of: {PLAYERCOUNT}/{MAXPLAYERS}' 35 | - 'Note: This should also work with other games that use the Source query protocol (such as Miscreated or Counter-Strike: Global Offensive).' 36 | - 'You may notice that even if the IP and ports are correct, you are still getting an error. This might be because the provider that runs the production environment does not allow me to whitelist big ranges of outgoing ports (thus not being able to query the server). Please contact me for any questions.' 37 | - route: "status-report" 38 | parameters: 39 | qs: 40 | deprecated: true 41 | notes: 42 | - 'DEPRECATED: Returns the same as the "news" API endpoint.' 43 | - route: "steam-status-report" 44 | parameters: 45 | qs: 46 | deprecated: true 47 | notes: 48 | - 'DEPRECATED: Returns the same as the "news" API endpoint.' 49 | -------------------------------------------------------------------------------- /public/static/yaml/endpoints/misc.yaml: -------------------------------------------------------------------------------- 1 | base_path: "/misc" 2 | endpoints: 3 | - route: "currency" 4 | parameters: 5 | qs: 6 | - name: "from" 7 | description: "The currency code you are converting from." 8 | required: true 9 | - name: "to" 10 | description: "The currency code you want to convert to." 11 | required: true 12 | - name: "value" 13 | description: "The amount of 'from' you wish to convert." 14 | required: true 15 | type: "float" 16 | - name: "round" 17 | description: "The amount of decimals you wish to round the currency to. Default: 2." 18 | type: "int" 19 | - name: "list" 20 | description: "If this is included in the request, a comma-separated list of available currencies will be listed instead." 21 | notes: 22 | - 'Converts from one currency to another..' 23 | - 'The currency codes follow the ISO 4217 standard.' 24 | - 'The API used for currency conversions is Fixer.io.' 25 | - route: "time" 26 | qs: 27 | - name: "timezone" 28 | description: 'The name of the timezone you want to retrieve the time for.' 29 | required: true 30 | - name: "format" 31 | description: 'The PHP date() format you want the time to be displayed in. - Default: h:i:s A T.' 32 | notes: 33 | - 'Displays the current time in the specified timezone.' 34 | - route: 'time-difference' 35 | qs: 36 | - name: 'first' 37 | description: 'The initial timestamp you want to compare from' 38 | required: true 39 | - name: 'second' 40 | description: 'The second timestamp you want to compare from. If not specified, it defaults to the current time.' 41 | notes: 42 | - 'Returns a human-readable time difference between two timestamps.' 43 | - 'The timestamps can be in any format that strtotime() can understand.' 44 | - 'If you wish to specify a timezone, please include that in the timestamp itself. My recommendation is to follow the ISO 8601 standard. Example: /misc/time-difference?first=2022-10-31T13:37:06+02:00' 45 | - 'Supports localization! Example time in German: /misc/time-difference?first=2022-10-31T13:37:06+02:00&lang=de' 46 | - route: "timezones" 47 | notes: 48 | - 'Returns a list of supported timezones.' 49 | - 'Supports JSON responses.' 50 | bots: false 51 | -------------------------------------------------------------------------------- /public/static/yaml/endpoints/steam.yaml: -------------------------------------------------------------------------------- 1 | base_path: "/steam" 2 | endpoints: 3 | - route: "currencies" 4 | parameters: 5 | qs: 6 | notes: 7 | - 'Lists currencies available on Steam (3-letter code + full name)' 8 | - 'Send the header Accept: application/json to retrieve a JSON object.' 9 | - route: 'global-players' 10 | parameters: 11 | qs: 12 | - name: 'appid' 13 | description: 'The Steam app ID to check the global player count for.' 14 | required: true 15 | type: 'int' 16 | notes: 17 | - "Retrieves the global player count for the specified game. That means every player that's considered 'in-game'" 18 | - "The global player count for each app ID is cached for up to 1 minute (60 seconds)." 19 | - route: "hours/:steam_id/:app_id/readable" 20 | parameters: 21 | - name: ":steam_id" 22 | description: 'The Steam64 ID of the user. See: steamid.co' 23 | type: "int64" 24 | - name: ":app_id" 25 | description: 'The Steam application ID.' 26 | type: "int" 27 | - name: "readable" 28 | description: 'This has to be passed as just readable and nothing else to have any effect. It formats the time to a more "human-readable" format. For example: 190.97 hours = 7 days 22 hours 58 minutes.' 29 | optional: true 30 | qs: 31 | - name: "round" 32 | description: "How many decimals the hours should round to - Default: 2." 33 | type: "int" 34 | - name: "key" 35 | description: "A custom Steam API key. In some cases this is necessary to retrieve profile information about private/friends-only profiles." 36 | notes: 37 | - 'Please keep in mind, that due to a recent change (as of April 2018) with Steam, game information is now set to "Friends-only" by default.
A workaround is to make the profile owner set their game privacy to "Public", which can be done by visiting https://steamcommunity.com/my/edit/settings. (Screenshot for reference)
' 38 | - "Retrieves the player's time played in the specified game (app ID)." 39 | - 'The Steam API key can be retrieved here: https://steamcommunity.com/dev/' 40 | - route: "server_ip/:steam_id" 41 | parameters: 42 | - name: ":steam_id" 43 | description: 'The Steam64 ID of the user. See: steamid.co' 44 | type: "int64" 45 | qs: 46 | notes: 47 | - "Retrieves the gameserver information of the user, if available." 48 | - "This only works for certain games and only if the user's profile is set to public." 49 | -------------------------------------------------------------------------------- /public/static/public-key-alex@thomassen.sh.asc: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | 3 | 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 53 | Cs3+SV+A 54 | =ILq3 55 | -----END PGP PUBLIC KEY BLOCK----- 56 | -------------------------------------------------------------------------------- /public/static/yaml/endpoints/youtube.yaml: -------------------------------------------------------------------------------- 1 | base_path: "/youtube" 2 | endpoints: 3 | - route: "latest_video" 4 | qs: 5 | - name: "user" 6 | description: 'For users with URLs that are formatted like: youtube.com/user/[USERNAME_HERE].' 7 | - name: "id" 8 | description: 'For users with URLs that are formatted like: youtube.com/channel/[ID_HERE].' 9 | - name: "handle" 10 | description: 'For the more recent @ YouTube channel handles. Example: https://www.youtube.com/@Decicus would be @Decicus.' 11 | - name: "skip" 12 | description: 'Skips the specified amount of uploads. - Default: 0. - Maximum: 50.' 13 | type: "int" 14 | - name: "format" 15 | description: "Customize the output format of the latest video. Available variables are: {title}, {id}, {url}. Default format is: {title} - {url}" 16 | - name: "exclude" 17 | description: "Exclude videos that contain the specified text in the video title. This is case-insensitive. Can be combined with include." 18 | - name: "include" 19 | description: "Only include videos that contain the specified text in the video title. This is case-insensitive. Can be combined with exclude." 20 | - name: "no_shorts" 21 | type: "bool" 22 | description: "Will exclude any videos shorter than 1 minute (60 seconds), also known as 'Shorts'. Set no_shorts=1 to enable this." 23 | - name: "no_livestream" 24 | type: "bool" 25 | description: "Will exclude any currently active livestreams. Stream VODs are generally not affected by this setting, unless it's a recently completed livestream (due to caching). Set no_livestream=1 to enable this." 26 | - name: "shorts_url" 27 | type: "bool" 28 | description: "If the video is a 'Short' (less than 1 minute), the URL will be returned as a shorts URL instead. Example: youtube.com/shorts/VIDEO_ID_HERE. Set shorts_url=1 to enable this." 29 | - name: "min_duration" 30 | type: "int" 31 | description: "Will exclude any videos shorter than the specified amount of seconds. For example, set min_duration=180 to exclude videos shorter than 3 minutes (180 seconds)." 32 | - name: "max_duration" 33 | type: "int" 34 | description: "Will exclude any videos longer than the specified amount of seconds. For example, set max_duration=3600 to exclude videos longer than 1 hour (3600 seconds)." 35 | notes: 36 | - 'Retrieves the latest video uploaded to the specified channel and returns the title + URL for it.' 37 | - 'Either user or id has to be specified. If both are specified, id will be used.' 38 | - 'If a YouTube channel URL is in the /c/decicus format, you should use id. One method of retrieving your channel ID is by visiting https://www.youtube.com/account_advanced and copying the "YouTube channel ID". See this screenshot for reference.' 39 | - 'You can also use the YouTube @ handle in the URL as a parameter. Example: https://www.youtube.com/@Decicus would be handle=Decicus. Make sure to include the @ symbol at the start.' 40 | - route: "latest_pl_video" 41 | qs: 42 | - name: "id" 43 | description: 'The ID of the playlist. You can find it in the URL when browsing the playlist after list=.' 44 | type: "string" 45 | required: true 46 | notes: 47 | - 'Important: Because of a bit of a limitation with the YouTube API, the owner of the playlist has to go into the "Playlist settings" and order the playlist by "Date added/published (newest)" for this to work correctly.
Screenshot' 48 | - 'Retrieves the latest video added to a playlist.' 49 | - route: "videoid/:search" 50 | parameters: 51 | - name: ":search" 52 | description: 'The search string.' 53 | qs: 54 | - name: "show_url" 55 | description: 'Prepends https://youtu.be/ before the video ID to make it a proper URL.' 56 | notes: 57 | - 'Searches the YouTube API with the specified string and returns the first result it can find (if any).' 58 | - 'If the search string is a valid video ID, it will just return the video ID.' 59 | - 'Searches are cached for up to 3 hours, to avoid repeated YouTube API requests. This only applies to exact & case insensitive matches on search queries.' 60 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 79 | 80 | 122 | -------------------------------------------------------------------------------- /src/components/Cached.vue: -------------------------------------------------------------------------------- 1 | 118 | 119 | 130 | -------------------------------------------------------------------------------- /src/components/Changelog.vue: -------------------------------------------------------------------------------- 1 | 244 | -------------------------------------------------------------------------------- /public/static/yaml/endpoints/twitch.yaml: -------------------------------------------------------------------------------- 1 | base_path: "/twitch" 2 | endpoints: 3 | - route: "" 4 | notes: 5 | - 'Lists the currently available endpoints - Returns a JSON object' 6 | bots: false 7 | - route: "accountage/:user" 8 | cached: true 9 | parameters: 10 | - name: ":user" 11 | description: 'The name of the user to retrieve the account age for.' 12 | qs: 13 | - name: "precision" 14 | description: 'How precise the timestamp should be in terms of years, months, weeks, days, hours, minutes & seconds.- Default: 2.' 15 | notes: 16 | - 'Retrieves the account age of the specified user.' 17 | - route: "avatar/:user" 18 | cached: true 19 | parameters: 20 | - name: ':user' 21 | description: 'The name of the user to retrieve the avatar for.' 22 | notes: 23 | - 'Retrieves the URL of the avatar for the specified user' 24 | - 'Will fallback to the default Twitch avatar if the user does not have an avatar.' 25 | - route: "creation/:user" 26 | cached: true 27 | parameters: 28 | - name: ":user" 29 | description: "The name of the user." 30 | notes: 31 | - Retrieves the creation date/time of the specified user. 32 | qs: 33 | - name: "format" 34 | description: 35 | - 'Formats the date/time based on the format string specified.' 36 | - 'Default format: M j. Y - h:i:s A (e)' 37 | required: false 38 | type: "string" 39 | - name: "tz" 40 | description: 'Specify the timezone that you want the date/time to be displayed as. List of supported timezones.' 41 | required: false 42 | type: "string" 43 | - route: "followage/:channel/:user?token=YOUR_TOKEN_HERE" 44 | cached: true 45 | parameters: 46 | - name: ":channel" 47 | description: 'The channel name that will be used as reference for checking the "follow age".' 48 | - name: ":user" 49 | description: 'The name of the user that you wish to check the "follow age" for.' 50 | qs: 51 | - name: "token" 52 | required: true 53 | description: 'The token provided by DecAPI when a moderator or the broadcaster authorizes for either followage or followed. If you are a moderator or the broadcaster, you can click here to authorize DecAPI and generate the required token.' 54 | - name: "precision" 55 | description: 'How precise the timestamp should be in terms of years, months, weeks, days, hours, minutes & seconds.- Default: 2.' 56 | type: "int" 57 | notes: 58 | - 'As of September 2023, a token is required to use this endpoint. If you are a moderator or the broadcaster, you can click here to authorize DecAPI and generate the required token.' 59 | - 'Gets the time difference (also known as the "follow age") between when :user followed :channel' 60 | - route: "followcount/:channel" 61 | cached: true 62 | parameters: 63 | - name: "channel" 64 | description: 'The channel name to retrieve the current follower count for.' 65 | notes: 66 | - 'Retrieves the current amount of followers a Twitch channel has.' 67 | - route: "followed/:channel/:user?token=YOUR_TOKEN_HERE" 68 | cached: true 69 | parameters: 70 | - name: ":channel" 71 | description: 'The channel name.' 72 | - name: ":user" 73 | description: 'The name of the user.' 74 | qs: 75 | - name: "token" 76 | required: true 77 | description: 'The token provided by DecAPI when a moderator or the broadcaster authorizes for either followage or followed. If you are a moderator or the broadcaster, you can click here to authorize DecAPI and generate the required token.' 78 | - name: "tz" 79 | description: 'Uses a different timezone for displaying date & time other than UTC. List of supported timezones.' 80 | type: "string" 81 | - name: "format" 82 | description: 'Changes the formatting of the returned date & time. See the PHP date() documentation for reference.
Default format string: M j. Y - h:i:s A (e)' 83 | type: "string" 84 | notes: 85 | - 'As of September 2023, a token is required to use this endpoint. If you are a moderator or the broadcaster, you can click here to authorize DecAPI and generate the required token.' 86 | - 'Retrieves the date and time of when the user followed the channel.' 87 | - 'Example format: Mar 13. 2016 - 07:31:29 PM (UTC)' 88 | - route: "followers/:channel" 89 | deprecated: true 90 | parameters: 91 | - name: ":channel" 92 | description: 'The channel name of the channel you wish to retrieve followers for.' 93 | qs: 94 | - name: "count" 95 | description: 'How many followers to get with the request. Default: 1. Max: 100.' 96 | type: "int" 97 | - name: "num" 98 | description: "Prefixes each follower with a number." 99 | type: "none" 100 | - name: "separator" 101 | description: "Specify the character(s) used for separating each follower. Default: , " 102 | notes: 103 | - 'Deprecated: You can read more here: https://gist.github.com/Decicus/daf7234366387636d5d2fe9f59ba0f11#file-2023-08-11_decapi-twitch-follows-endpoints-md' 104 | - 'Lists the most recent follower(s) a channel has.' 105 | - route: "following/:user" 106 | deprecated: true 107 | parameters: 108 | - name: ":user" 109 | description: 'The username of the user you wanna get the "following" channels from.' 110 | qs: 111 | - name: "limit" 112 | description: 'Specifies the max amount of channels listed per request. Minimum: 1. Maximum: 100. Default: 25.' 113 | type: "int" 114 | - name: "separator" 115 | description: 'Specifies the separator used when listing channel names. Default: , .' 116 | type: "string" 117 | notes: 118 | - 'Deprecated: You can read more here: https://gist.github.com/Decicus/daf7234366387636d5d2fe9f59ba0f11#file-2023-08-11_decapi-twitch-follows-endpoints-md' 119 | - 'Retrieves a list of channels that the specified user is following.' 120 | - route: "game/:channel" 121 | cached: true 122 | parameters: 123 | - name: ":channel" 124 | description: "The channel name." 125 | notes: 126 | - 'Retrieves the current game the channel has been set to.' 127 | - route: "highlight/:channel" 128 | parameters: 129 | - name: ":channel" 130 | description: 'The channel name.' 131 | notes: 132 | - 'Retrieves the latest "highlight" of the specified channel.' 133 | - route: "id/:user" 134 | parameters: 135 | - name: ":user" 136 | description: 'The name of the user.' 137 | notes: 138 | - 'Returns the Twitch user ID of the specified user (if valid).' 139 | - route: "ingests" 140 | bots: false 141 | notes: 142 | - 'Returns a formatted list of available ingest servers.' 143 | - 'This is a "legacy" endpoint. It is better to use the official Twitch API endpoint for this: https://ingest.twitch.tv/ingests' 144 | - route: "multi/:streams" 145 | parameters: 146 | - name: ":streams" 147 | description: 'A space-separated list of streams to generate a multi link with.' 148 | qs: 149 | - name: "streams" 150 | description: 'Can be used as an alternative to the :streams route parameter.' 151 | - name: "service" 152 | description: 'Chooses which multistream service you want to use. Specify something bogus for this parameter to get a list of available services. Default: multistream.' 153 | notes: 154 | - 'Generates a "multi stream" URL based on the channel names passed to it.' 155 | - 'While the streams query parameter is optional, you have to specify the streams as either a route parameter or as the streams query parameter.' 156 | - route: "random_sub/:channel" 157 | qs: 158 | - name: "count" 159 | description: "The amount of subscribers to retrieve - Default: 1." 160 | type: "int" 161 | - name: "field" 162 | description: 'What field from the user object to retrieve. See Twitch API docs to see which ones are available. Default: user_name.' 163 | - name: "separator" 164 | description: 'What character(s) should separate each subscriber value from each other. Default: , .' 165 | notes: 166 | - 'Retrieves a random subscriber from the channel, assuming they have already authorized with DecAPI.' 167 | - 'If you have already authorized via "subcount" or "subpoints", you can already use this API.' 168 | - route: "subcount/:channel" 169 | cached: true 170 | parameters: 171 | - name: ":channel" 172 | description: "The channel name." 173 | qs: 174 | - name: "subtract" 175 | description: "Subscriber count will subtract the specified value and return the result. If you have 102 subs and you specify subtract=2, it will return 100." 176 | type: "int" 177 | notes: 178 | - 'Retrieves the subscriber count of the specified channel.' 179 | - 'This only works for channels that have authenticated and authorized this app.' 180 | - "As of October 2nd, 2021 the subscriber count no longer includes lifetime bot subscriptions or the broadcaster's own subscription. You may need to adjust the subtract parameter if it was previously used for accuracy reasons." 181 | - route: "subpoints/:channel" 182 | cached: true 183 | parameters: 184 | - name: ":channel" 185 | description: "The channel name." 186 | qs: 187 | notes: 188 | - 'Retrieves the amount of subscriber points for the specified channel.' 189 | - 'This only works for channels that have authenticated and authorized this app (if the channel already uses subcount, this works already).' 190 | - 'As of October 2nd, 2021 the subscriber points value is now accurately retrieved from the Twitch API. The "subtract" parameter no longer applies and will be ignored.' 191 | - route: "subscriber_emotes/:channel" 192 | cached: true 193 | parameters: 194 | - name: ":channel" 195 | description: 'The channel name.' 196 | notes: 197 | - 'Retrieves the subscriber emotes for the specified channels and lists them (space-separated).' 198 | - 'JSON results are supported.' 199 | qs: 200 | - name: 'tiers' 201 | description: 'Only available in JSON responses. Specify the tiers parameter with your request and emotes are split into their respective subscriber tiers.' 202 | - route: "status/:channel" 203 | cached: true 204 | parameters: 205 | - name: ":channel" 206 | description: 'The channel name.' 207 | notes: 208 | - 'Retrieves the current title set on the channel.' 209 | - route: "team_members/:team_id" 210 | parameters: 211 | - name: ":team_id" 212 | description: 'The team identifier.' 213 | qs: 214 | - name: "sort" 215 | description: 'If this is specified, it will sort the members of the team alphabetically.
Recommended for a consistent list between requests.' 216 | - name: "text" 217 | description: 'If this is specified, the list will be returned in plaintext compared to a JSON array.' 218 | - name: "implode" 219 | description: 'Works similarly to text.
Specify the text that should separate each team member in a plaintext response. This is an alternative to having a list of members separated by a newline.
If this is specified, specifying the text query string is not necessary as that will already be implied.' 220 | notes: 221 | - 'Retrieves the members of a specified team.' 222 | - 'The team identifier is the identifier used in URLs. Example: The team "New Game Plus" has the identifier "newgameplus".' 223 | - 'JSON results are returned by default. See text or implode query string..' 224 | - route: "title/:channel" 225 | cached: true 226 | parameters: 227 | - name: ":channel" 228 | description: "The channel name." 229 | notes: 230 | - 'Works identical to status - Retrieves the current title set on the channel.' 231 | - route: "total_views/:channel" 232 | parameters: 233 | - name: ":channel" 234 | description: "The channel name." 235 | notes: 236 | - 'Displays the "total views" a channel has.' 237 | - route: "uptime/:channel" 238 | cached: true 239 | parameters: 240 | - name: ":channel" 241 | description: "The channel name." 242 | qs: 243 | - name: "precision" 244 | description: 'How precise the timestamp should be in terms of days, hours, minutes & seconds - Default: 4.' 245 | - name: "offline_msg" 246 | description: 'A custom message to display when the channel is offline. - Default: CHANNEL_NAME is offline' 247 | notes: 248 | - 'Returns how long the specified channel has been live for the current broadcast.' 249 | - 'Even with caching applied, the uptime will still be "calculated" in realtime.' 250 | - route: "viewercount/:channel" 251 | cached: true 252 | parameters: 253 | - name: ":channel" 254 | description: "The channel name." 255 | notes: 256 | - 'Returns how many viewers the channel has, if they are currently streaming.' 257 | - route: "videos/:channel" 258 | cached: true 259 | parameters: 260 | - name: ":channel" 261 | description: "The channel name to retrieve videos for." 262 | qs: 263 | - name: 'offset' 264 | description: 'How many videos to offset by. Default: 0.' 265 | - name: 'limit' 266 | description: 'How many videos to retrieve at once. Minimum: 1. Maximum: 100. Default: 1.' 267 | - name: 'broadcast_type' 268 | description: 'Comma-separated list of video types to retrieve. Click here for reference. Since dedicated endpoints for highlights and uploads already exists, this defaults to archive.' 269 | - name: 'separator' 270 | description: 'Specifies what the separator between each video is.' 271 | - name: 'video_format' 272 | description: 'Specifies the format of each video. Certain "variables" are supported: ${title} and ${url}. Default value is: ${title} - ${url}' 273 | notes: 274 | - 'Retrieves the latest videos from a channel.' 275 | - 'Since it is primarily provided as an alternative to the "latest highlight" and "latest upload" endpoints, it is set to only retrieve VODs (stream archives) by default. Use the broadcast_type parameter to override this.' 276 | - route: "vod_replay/:channel" 277 | cached: true 278 | parameters: 279 | - name: ":channel" 280 | description: "The channel name to retrieve the 'VOD replay' for." 281 | qs: 282 | - name: "minutes" 283 | description: "The amount of minutes to go back and link the 'replay' to. Default: 5." 284 | - name: "offset" 285 | description: "How many VODs to offset when retrieving the VOD information. Default: 0." 286 | notes: 287 | - 'The VOD replay endpoint retrieves the latest VOD (in relation to the offset), takes the specified amount of minutes and returns a timestamped URL. Example: If the streamer has been streaming for roughly 2 hours and 25 minutes and the minutes specified is 15, the URL will be linking to 2 hours and 10 minutes into the VOD.' 288 | - 'Keep in mind that VOD lengths are not fully updated in realtime, and might be "lagging" a few minutes behind the length of the livestream.' 289 | -------------------------------------------------------------------------------- /src/components/Home.vue: -------------------------------------------------------------------------------- 1 | 286 | 287 | 307 | -------------------------------------------------------------------------------- /src/components/EndpointList.vue: -------------------------------------------------------------------------------- 1 | 198 | 199 | 204 | 205 | 444 | --------------------------------------------------------------------------------