2023-06-07 14:44:25 -05:00
# safetwitch-backend
The backend for [SafeTwitch ](https://codeberg.org/dragongoose/safetwitch )
2023-05-18 20:56:33 -05:00
2023-06-07 14:44:25 -05:00
# Documentation
2023-05-29 17:20:08 -05:00
2023-06-07 14:44:25 -05:00
## API Endpoints
### Disclaimer
Every endpoint can return a 500 status code, and it follows this schema:
```json
{
status: "error",
2023-07-03 14:28:44 -05:00
data: "Error message..."
2023-06-07 14:44:25 -05:00
}
```
2023-07-15 14:31:29 -05:00
### https://streamapi.whateveritworks.org/api/users/xqc
2023-06-07 14:44:25 -05:00
**GET** - :username is any streamer
Gets a specific twitch streamer
#### Responses
###### 200
2023-07-03 14:28:44 -05:00
The request was successful, returns data of type [Streamer ](https://codeberg.org/dragongoose/safetwitch-backend/src/branch/master/extractor/structs/parsed.go )
2023-06-07 14:44:25 -05:00
*Example:*
```json
{
"status": "ok",
"data": {
"username": "filian",
"about": "Welcome to my Vtuber alpha! 3D streaming and variety games! Join the discord! n_n",
"pfp": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9qdHZfdXNlcl9waWN0dXJlcy9mNzVkNDEwMy1hMjY1LTRlMjEtODhiNS00NDc0NWZjMWJmNDQtcHJvZmlsZV9pbWFnZS0zMDB4MzAwLnBuZw",
2023-07-03 14:28:44 -05:00
"banner": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9qdHZfdXNlcl9waWN0dXJlcy9kMjY2OTZlMC1hYjJhLTRlZjEtYTI3Ni0wZmZjZWM5NmM3NzYtcHJvZmlsZV9iYW5uZXItNDgwLnBuZw==",
2023-06-07 14:44:25 -05:00
"followers": 579463,
"socials": [
{
"type": "discord",
"name": "discord.gg/filian",
"link": "https://discord.gg/filian"
},
{
"type": "twitter",
"name": "twitter.com/filianIsLost",
"link": "https://twitter.com/filianIsLost"
}
],
"isLive": false,
"isPartner": true,
"colorHex": "#8040E0",
"id": 198633200,
"stream": null
}
}
```
##### 404
The streamer was not found
2023-07-15 14:31:29 -05:00
### https://streamapi.whateveritworks.org/api/discover
2023-06-07 14:44:25 -05:00
**GET**
Gets the discover page of twitch, a list of categories
#### Responses
##### 200
2023-07-03 14:28:44 -05:00
The request was successful, returns a [CategoryData[]](https://codeberg.org/dragongoose/safetwitch-backend/src/branch/master/extractor/structs/parsed.go)
2023-06-07 14:44:25 -05:00
*Example:*
```json
{
"status": "ok",
"data": [
{
"name": "Just Chatting",
"displayName": "Just Chatting",
"viewers": 510365,
"tags": [
"IRL"
],
"createdAt": null,
"cursor": "eyJzIjoxLCJkIjpmYWxzZSwidCI6dHJ1ZX0=",
"image": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC90dHYtYm94YXJ0LzUwOTY1OC0yODV4MzgwLmpwZw"
},
...
}
```
2023-07-15 14:31:29 -05:00
### https://streamapi.whateveritworks.org/api/discover/Grand Theft Auto V
2023-06-07 14:44:25 -05:00
**GET** - :game is a name of a twitch category
Gets a specific twitch category
#### Responses
##### 200
2023-07-03 14:28:44 -05:00
The server found the category, returns data of type [CategoryPreview[]](https://codeberg.org/dragongoose/safetwitch-backend/src/branch/master/extractor/structs/parsed.go)
2023-06-07 14:44:25 -05:00
*Example:*
```json
{
"status": "ok",
"data": {
"name": "Just Chatting",
"cover": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC90dHYtYm94YXJ0LzUwOTY1OC0xNDR4MTkyLmpwZw",
"description": null,
"viewers": 533593,
"followers": 23147702,
"tags": [
"IRL"
],
"streams": [
{
"title": "CIERRE DEL MERCATO DE LA KINGS LEAGUE | ÚLTIMO DÍA DE MERCATO | ÚLTIMOS CLAUSULAZOS | SE VIENEN LLOROS",
"viewers": 60897,
"preview": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9wcmV2aWV3cy10dHYvbGl2ZV91c2VyX2liYWktNDQweDI0OC5qcGc",
"tags": [
"Español",
"KOI",
"KingsLeague"
],
"cursor": "eyJzIjo2MDg5Ny40NDU3NDY0NjY4NSwiZCI6ZmFsc2UsInQiOnRydWV9",
"streamer": {
"name": "ibai",
"pfp": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9qdHZfdXNlcl9waWN0dXJlcy81NzQyMjhiZS0wMWVmLTRlYWItYmMwZS1hNGY2YjY4YmVkYmEtcHJvZmlsZV9pbWFnZS01MHg1MC5wbmc",
"colorHex": "2A2B62"
}
},
...
]
}
}
```
##### 404
The category was not found
2023-07-15 14:31:29 -05:00
### https://streamapi.whateveritworks.org/api/badges?streamerName=xqc
2023-06-07 14:44:25 -05:00
**GET**
Gets global twitch chat badges
streamerName query is optional, if given it will only provide the badges for that streamer.
#### Responses
##### 200
2023-07-03 14:28:44 -05:00
Server retrieved the badges, returns type [Badge[]](hhttps://codeberg.org/dragongoose/safetwitch-backend/src/branch/master/extractor/structs/parsed.go)
2023-06-07 14:44:25 -05:00
*Example:*
```json
{
"status": "ok",
"data": [
{
"id": "getting-over-it_2;1;",
"setId": "getting-over-it_2",
"title": "Getting Over It",
"version": "1",
"images": {
"image1x": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9iYWRnZXMvdjEvYmI2MjBiNDItZTBlMS00MzczLTkyOGUtZDRhNzMyZjk5Y2NiLzE",
"image2x": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9iYWRnZXMvdjEvYmI2MjBiNDItZTBlMS00MzczLTkyOGUtZDRhNzMyZjk5Y2NiLzI",
"image4x": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9iYWRnZXMvdjEvYmI2MjBiNDItZTBlMS00MzczLTkyOGUtZDRhNzMyZjk5Y2NiLzM"
}
},
...
]
}
```
2023-07-15 14:31:29 -05:00
### https://streamapi.whateveritworks.org/api/search?query=xqc
2023-06-07 14:44:25 -05:00
**GET** - SEARCHQUERY is any string
2023-07-03 14:28:44 -05:00
Searches for categories, streamers, tags, and live streamers. Returns data of type [SearchResult ](https://codeberg.org/dragongoose/safetwitch-backend/src/branch/master/extractor/structs/parsed.go )
2023-06-07 14:44:25 -05:00
#### Responses
##### 200
The server found the search data, returns:
*Example:*
```json
{
"status": "ok",
"data": {
"channels": [
{
"username": "filian",
"followers": 580066,
"isLive": false,
"about": "Welcome to my Vtuber alpha! 3D streaming and variety games! Join the discord! n_n",
"pfp": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9qdHZfdXNlcl9waWN0dXJlcy9mNzVkNDEwMy1hMjY1LTRlMjEtODhiNS00NDc0NWZjMWJmNDQtcHJvZmlsZV9pbWFnZS0xNTB4MTUwLnBuZw",
"isPartner": null,
"colorHex": "#fff",
"id": 198633200
},
...
],
"categories": [
{
"name": "Lilian: The beginning of the end",
"displayName": "Lilian: The beginning of the end",
"viewers": null,
"tags": [
""
],
"image": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9wcmV2aWV3cy10dHYvbGl2ZV91c2VyX2VsbHllbi0xMjgweDcyMC5qcGc"
}
],
"relatedChannels": [
{
"username": "EllyEN",
"about": "HI I'M ELLY❗❗ I'm a cwiminal Vtuber who loves cars, boba, games, & getting into trouble~❗❗",
"pfp": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9qdHZfdXNlcl9waWN0dXJlcy8xZjJjNmQ2Yi1hZmZmLTQ4NGYtYTdjMy1iNGRhZTU2MzllOGMtcHJvZmlsZV9pbWFnZS0zMDB4MzAwLmpwZWc",
"followers": 100538,
"socials": [
{
"type": "twitter",
"name": "Twitter",
"link": "https://www.twitter.com/EllyVtuber"
},
{
"type": "tiktok",
"name": "Tiktok",
"link": "https://www.tiktok.com/@ellyvtuber"
},
{
"type": "youtube",
"name": "YouTube",
"link": "https://www.youtube.com/EllyEN"
}
],
"isLive": true,
"isPartner": true,
"colorHex": "#FA2929",
"id": 141045387,
"stream": {
"title": "little bit of valheim THEN FFXIV! 🌱 I'M OBSESSED LOL | SUBATHON PART 2 DAY 16 | #AlienwareHive !GamerSupps",
"topic": "I'm Only Sleeping",
"startedAt": 1682363001000,
"tags": [
"LGBTQIA",
"NoBackseating",
"Vtuber",
"ENVtuber",
"English"
],
"viewers": 654,
"preview": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9wcmV2aWV3cy10dHYvbGl2ZV91c2VyX2VsbHllbi0xMjgweDcyMC5qcGc"
}
},
...
],
"channelsWithTag": []
}
}
```
2023-07-20 13:39:26 -05:00
### https://streamapi.whateveritworks.org/api/vods/1872917122
**GET** - vodID is any id of a vod
Gets metadata of a VOD, returns [Video ](https://codeberg.org/dragongoose/safetwitch-backend/src/branch/master/extractor/structs/parsed.go )
#### Responses
##### 200
The server found the VOD
*Example:*
```json
{
"status": "ok",
"data": {
"type": "vod",
"preview": "http://localhost:8080/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9jZl92b2RzL2QxbTdqZm9lOXpkYzFqL2JjODQyZGVhNmY2MWVlODM5MzNkX2ZpbGlhbl80MTY0NzEwMjg3M18xNjg5NDU4NzA2Ly90aHVtYi90aHVtYjAtOTB4NjAuanBn",
"game": {
"image": "http://localhost:8080/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC90dHYtYm94YXJ0LzUwOTY1OC17d2lkdGh9eHtoZWlnaHR9LmpwZw==",
"id": "509658",
"name": "Just Chatting",
"displayName": "Just Chatting"
},
"duration": 17520,
"title": "🦂 YOU LAUGH, YOU LOSE today! Eating a Scorpion today. This is it. After 10 laughs it's guaranteed no matter what. Wait I hear something beh",
"publishedAt": "2023-07-15T22:05:11Z",
"views": 81357,
"streamer": {
"username": "filian",
"login": "filian",
"about": "Welcome to my Vtuber alpha! 3D streaming and variety games! Join the discord! n_n",
"pfp": "http://localhost:8080/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9qdHZfdXNlcl9waWN0dXJlcy9mNzVkNDEwMy1hMjY1LTRlMjEtODhiNS00NDc0NWZjMWJmNDQtcHJvZmlsZV9pbWFnZS0zMDB4MzAwLnBuZw==",
"banner": null,
"followers": 656278,
"socials": [
{
"type": "discord",
"name": "discord.gg/filian",
"url": "https://discord.gg/filian"
},
{
"type": "twitter",
"name": "twitter.com/filianIsLost",
"url": "https://twitter.com/filianIsLost"
}
],
"isLive": false,
"isPartner": true,
"colorHex": "8040E0",
"id": "198633200"
},
"id": "1872917122"
}
}
```
### https://streamapi.whateveritworks.org/api/vods/1872917122/10
**GET** - vodID is any id of a vod, offset is the seconds into the vod
Gets comments at that second of a song, returns [VodComment[]](https://codeberg.org/dragongoose/safetwitch-backend/src/branch/master/extractor/structs/parsed.go)
#### Responses
##### 200
The server found the VOD
*Example:*
```json
{
"status": "ok",
"data": [
{
"message": "Pog",
"messager": {
"name": "equiro",
"login": "equiro",
"pfp": "",
"colorHex": "#FF4500"
},
"offset": 6,
"cursor": "eyJpZCI6ImMwM2M0Mzg2LTRhMTUtNGVlMC05NGQ2LTMyYWExZTZjYjFhYSIsImhrIjoiYnJvYWRjYXN0OjQxNjQ3MTAyODczIiwic2siOiJBQUFBQmpwT0Z3QVhjaW5GZjk5a0FBIn0",
"badges": []
}...
]
}
```
2023-06-07 14:44:25 -05:00
## Proxying Endpoints
2023-07-15 14:31:29 -05:00
### https://streamapi.whateveritworks.org/proxy/img/base64Url
2023-06-07 14:44:25 -05:00
**GET**
Proxies an image through the server
:base64Url can be any base64 encoded Url
#### Responses
##### 200
Server returns the requested image
##### 404
The requested image was invalid
2023-07-15 14:31:29 -05:00
### https://streamapi.whateveritworks.org/proxy/stream/xqc/hls.m3u8
2023-06-07 14:44:25 -05:00
**GET**
Gets the m3u8 manifest for a streamer. This manifest will contain all stream qualities if they are live
#### Responses
##### 200
Returns the manifest
##### 400
The streamer is not live
*Example:*
```json
{
"status": "error",
2023-07-03 14:28:44 -05:00
"data": "Streamer is not live"
2023-06-07 14:44:25 -05:00
}
```
2023-07-15 14:31:29 -05:00
### https://streamapi.whateveritworks.org/proxy/stream/sub/encodedUrl
2023-06-07 14:44:25 -05:00
**GET**
Returns the m3u8 manifest for a specific quality under the [master manifest ](#/proxy/stream/:username/hls.m3u8 )
### 200
Returns the manifest file
2023-07-15 14:31:29 -05:00
### https://streamapi.whateveritworks.org/proxy/stream/segment/encodedUrl
2023-06-07 14:44:25 -05:00
**GET**
Gets a segment from one of the quality's manifest file. This is the actual video thats displayed on your screen
### 200
Returns the stream segment, HLS streaming.
2023-07-17 12:16:33 -05:00
2023-07-20 13:39:26 -05:00
### https://streamapi.whateveritworks.org//proxy/vod/:vodID/video.m3u8
2023-07-17 12:16:33 -05:00
**GET**
Gets the master manifest for a VOD
### 200
Returns the manifest file
2023-07-20 13:39:26 -05:00
### https://streamapi.whateveritworks.org//proxy/vod/sub/:encodedUrl/video.m3u8
2023-07-17 12:16:33 -05:00
**GET**
Gets the sub manifest for a VOD
encodedUrl is the url to the sub manifiest from twitch encoded in base64
### 200
Returns the manifest file
2023-07-20 13:39:26 -05:00
### https://streamapi.whateveritworks.org//proxy/vod/sub/:encodedUrl/:segment
2023-07-17 12:16:33 -05:00
**GET**
Gets the sub manifest for a VOD
encodedUrl is the url to the sub manifiest from twitch encoded in base64
segment is the segment from the playlist file, etc 0.ts, 1.ts
### 200
Returns the manifest file