From f632c7dfb3cb5069c5fb3a4993c3739f955c7eb8 Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 22 May 2024 01:20:54 +0600 Subject: [PATCH 01/15] stream/types: move closeResponse to shared --- src/modules/stream/shared.js | 5 +++++ src/modules/stream/types.js | 7 +------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/modules/stream/shared.js b/src/modules/stream/shared.js index 2f898c52..8555f8ba 100644 --- a/src/modules/stream/shared.js +++ b/src/modules/stream/shared.js @@ -16,6 +16,11 @@ const serviceHeaders = { } } +export function closeResponse(res) { + if (!res.headersSent) res.sendStatus(500); + return res.destroy(); +} + export function getHeaders(service) { return { ...defaultHeaders, ...serviceHeaders[service] } } \ No newline at end of file diff --git a/src/modules/stream/types.js b/src/modules/stream/types.js index 87c9f600..a1db0c60 100644 --- a/src/modules/stream/types.js +++ b/src/modules/stream/types.js @@ -6,7 +6,7 @@ import { create as contentDisposition } from "content-disposition-header"; import { metadataManager } from "../sub/utils.js"; import { destroyInternalStream } from "./manage.js"; import { env, ffmpegArgs } from "../config.js"; -import { getHeaders } from "./shared.js"; +import { getHeaders, closeResponse } from "./shared.js"; function toRawHeaders(headers) { return Object.entries(headers) @@ -18,11 +18,6 @@ function closeRequest(controller) { try { controller.abort() } catch {} } -function closeResponse(res) { - if (!res.headersSent) res.sendStatus(500); - return res.destroy(); -} - function killProcess(p) { // ask the process to terminate itself gracefully p?.kill('SIGTERM'); From b0da5bb89317a9165de47f82e3455fa40c74e885 Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 22 May 2024 01:21:34 +0600 Subject: [PATCH 02/15] stream: dont double send headers on critical error --- src/modules/stream/stream.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/stream/stream.js b/src/modules/stream/stream.js index 3b3494b6..08edb079 100644 --- a/src/modules/stream/stream.js +++ b/src/modules/stream/stream.js @@ -1,5 +1,6 @@ import { streamAudioOnly, streamDefault, streamLiveRender, streamVideoOnly, convertToGif } from "./types.js"; import { internalStream } from './internal.js'; +import { closeResponse } from "./shared.js"; export default async function(res, streamInfo) { try { @@ -25,6 +26,6 @@ export default async function(res, streamInfo) { break; } } catch { - res.sendStatus(500); + closeResponse(res) } } From 2534931b60516ded00704d2ae768d945205da542 Mon Sep 17 00:00:00 2001 From: Damir Modyarov Date: Tue, 21 May 2024 23:41:43 +0300 Subject: [PATCH 03/15] tiktok: use webapp-based downloading method (#503) Signed-off-by: Damir Modyarov Co-authored-by: wukko --- src/modules/processing/matchActionDecider.js | 30 ++++--- src/modules/processing/services/tiktok.js | 82 ++++++++++---------- src/modules/stream/shared.js | 8 +- 3 files changed, 68 insertions(+), 52 deletions(-) diff --git a/src/modules/processing/matchActionDecider.js b/src/modules/processing/matchActionDecider.js index f54bb3f5..6b44f8ab 100644 --- a/src/modules/processing/matchActionDecider.js +++ b/src/modules/processing/matchActionDecider.js @@ -2,6 +2,7 @@ import { audioIgnore, services, supportedAudio } from "../config.js"; import { createResponse } from "../processing/request.js"; import loc from "../../localization/manager.js"; import createFilename from "./createFilename.js"; +import { createStream } from "../stream/manage.js"; export default function(r, host, userFormat, isAudioOnly, lang, isAudioMuted, disableMetadata, filenamePattern, toGif, requestIP) { let action, @@ -41,7 +42,7 @@ export default function(r, host, userFormat, isAudioOnly, lang, isAudioMuted, di case "photo": responseType = "redirect"; break; - + case "gif": params = { type: "gif" } break; @@ -68,16 +69,22 @@ export default function(r, host, userFormat, isAudioOnly, lang, isAudioMuted, di params = { picker: r.picker }; break; case "tiktok": - let pickerType = "render"; - if (audioFormat === "mp3" || audioFormat === "best") { + let audioStreamType = "render"; + if (r.bestAudio === "mp3" && (audioFormat === "mp3" || audioFormat === "best")) { audioFormat = "mp3"; - pickerType = "bridge" + audioStreamType = "bridge" } params = { - type: pickerType, picker: r.picker, - u: Array.isArray(r.urls) ? r.urls[1] : r.urls, - copy: audioFormat === "best" ? true : false + u: createStream({ + service: "tiktok", + type: audioStreamType, + u: r.urls, + filename: r.audioFilename, + isAudioOnly: true, + audioFormat, + }), + copy: audioFormat === "best" } } break; @@ -101,7 +108,7 @@ export default function(r, host, userFormat, isAudioOnly, lang, isAudioMuted, di responseType = "redirect"; } break; - + case "twitter": if (r.type === "remux") { params = { type: r.type }; @@ -125,7 +132,7 @@ export default function(r, host, userFormat, isAudioOnly, lang, isAudioMuted, di } break; - case "audio": + case "audio": if (audioIgnore.includes(host) || (host === "reddit" && r.typeId === "redirect")) { return createResponse("error", { t: loc(lang, 'ErrorEmptyDownload') }) @@ -133,7 +140,7 @@ export default function(r, host, userFormat, isAudioOnly, lang, isAudioMuted, di let processType = "render", copy = false; - + if (!supportedAudio.includes(audioFormat)) { audioFormat = "best" } @@ -146,11 +153,12 @@ export default function(r, host, userFormat, isAudioOnly, lang, isAudioMuted, di const isTumblrAudio = host === "tumblr" && !r.filename; const isSoundCloud = host === "soundcloud"; + const isTiktok = host === "tiktok"; if (isBestAudioDefined || isBestHostAudio) { audioFormat = serviceBestAudio; processType = "bridge"; - if (isSoundCloud) { + if (isSoundCloud || (isTiktok && audioFormat === "m4a")) { processType = "render" copy = true } diff --git a/src/modules/processing/services/tiktok.js b/src/modules/processing/services/tiktok.js index b81d57d9..6d3cf314 100644 --- a/src/modules/processing/services/tiktok.js +++ b/src/modules/processing/services/tiktok.js @@ -1,13 +1,13 @@ -import { genericUserAgent, env } from "../../config.js"; +import { genericUserAgent } from "../../config.js"; +import { updateCookie } from "../cookie/manager.js"; +import { extract } from "../url.js"; +import Cookie from "../cookie/cookie.js"; const shortDomain = "https://vt.tiktok.com/"; -const apiPath = "https://api22-normal-c-alisg.tiktokv.com/aweme/v1/feed/?region=US&carrier_region=US"; -const apiUserAgent = "TikTok/338014 CFNetwork/1410.1 Darwin/22.6.0"; +export const cookie = new Cookie({}); export default async function(obj) { - let postId = obj.postId ? obj.postId : false; - - if (!env.tiktokDeviceInfo) return { error: 'ErrorCouldntFetch' }; + let postId = obj.postId; if (!postId) { let html = await fetch(`${shortDomain}${obj.id}`, { @@ -19,54 +19,59 @@ export default async function(obj) { if (!html) return { error: 'ErrorCouldntFetch' }; - if (html.slice(0, 17) === ' r.json()).catch(() => {}); + }) + updateCookie(cookie, res.headers); - detail = detail?.aweme_list?.find(v => v.aweme_id === postId); - if (!detail) return { error: 'ErrorCouldntFetch' }; + const html = await res.text(); + + let detail; + try { + const json = html + .split('')[0] + const data = JSON.parse(json) + detail = data["__DEFAULT_SCOPE__"]["webapp.video-detail"]["itemInfo"]["itemStruct"] + } catch { + return { error: 'ErrorCouldntFetch' }; + } let video, videoFilename, audioFilename, audio, images, - filenameBase = `tiktok_${detail.author.unique_id}_${postId}`, + filenameBase = `tiktok_${detail.author.uniqueId}_${postId}`, bestAudio = 'm4a'; - images = detail.image_post_info?.images; + images = detail.imagePost?.images; - let playAddr = detail.video.play_addr_h264; + let playAddr = detail.video.playAddr; if (obj.h265) { - playAddr = detail.video.bit_rate[0].play_addr - } - if (!playAddr && detail.video.play_addr) { - playAddr = detail.video.play_addr + const h265PlayAddr = detail.video.bitrateInfo.find(b => b.CodecType.includes("h265"))?.PlayAddr.UrlList[0] + playAddr = h265PlayAddr || playAddr } if (!obj.isAudioOnly && !images) { - video = playAddr.url_list[0]; + video = playAddr; videoFilename = `${filenameBase}.mp4`; } else { - let fallback = playAddr.url_list[0]; - audio = fallback; + audio = playAddr; audioFilename = `${filenameBase}_audio`; - if (obj.fullAudio || fallback.includes("music")) { - audio = detail.music.play_url.url_list[0] - audioFilename = `${filenameBase}_audio_original` + + if (obj.fullAudio || !audio) { + audio = detail.music.playUrl; + audioFilename += `_original` } - if (audio.slice(-4) === ".mp3") bestAudio = 'mp3'; + if (audio.includes("mime_type=audio_mpeg")) bestAudio = 'mp3'; } if (video) return { @@ -80,12 +85,9 @@ export default async function(obj) { bestAudio } if (images) { - let imageLinks = []; - for (let i in images) { - let sel = images[i].display_image.url_list; - sel = sel.filter(p => p.includes(".jpeg?")) - imageLinks.push({url: sel[0]}) - } + let imageLinks = images + .map(i => i.imageURL.urlList.find(p => p.includes(".jpeg?"))) + .map(url => ({ url })) return { picker: imageLinks, urls: audio, diff --git a/src/modules/stream/shared.js b/src/modules/stream/shared.js index 8555f8ba..42df2758 100644 --- a/src/modules/stream/shared.js +++ b/src/modules/stream/shared.js @@ -1,4 +1,5 @@ import { genericUserAgent } from "../config.js"; +import { cookie as tiktokCookie } from "../processing/services/tiktok.js"; const defaultHeaders = { 'user-agent': genericUserAgent @@ -13,6 +14,9 @@ const serviceHeaders = { origin: 'https://www.youtube.com', referer: 'https://www.youtube.com', DNT: '?1' + }, + tiktok: { + cookie: tiktokCookie } } @@ -22,5 +26,7 @@ export function closeResponse(res) { } export function getHeaders(service) { - return { ...defaultHeaders, ...serviceHeaders[service] } + // Converting all header values to strings + return Object.entries({ ...defaultHeaders, ...serviceHeaders[service] }) + .reduce((p, [key, val]) => ({ ...p, [key]: String(val) }), {}) } \ No newline at end of file From e13f0b9649c77e2402f5685ec58735451e202142 Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 22 May 2024 02:44:45 +0600 Subject: [PATCH 04/15] readme: update royale link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1ce676ac..3e363c64 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ if you want to run your own instance for whatever purpose, [follow this guide](/ it's *highly* recommended to use a docker compose method unless you run for developing/debugging purposes. ## partners -cobalt is sponsored by [royalehosting.net](https://royalehosting.net/), all main instances are currently hosted on their network :) +cobalt is sponsored by [royalehosting.net](https://royalehosting.net/?partner=cobalt), all main instances are currently hosted on their network :) ## ethics and disclaimer cobalt is a tool for easing content downloads from internet and takes ***zero liability***. you are responsible for what you download, how you use and distribute that content. please be mindful when using content of others and always credit original creators. fair use and credits benefit everyone. From cb72a96f48552235cb54f14b121850f2e2128189 Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 22 May 2024 02:45:20 +0600 Subject: [PATCH 05/15] changelog: remove tiktok broken notice --- src/modules/changelog/changelog.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/changelog/changelog.json b/src/modules/changelog/changelog.json index 5085960c..e90a1a33 100644 --- a/src/modules/changelog/changelog.json +++ b/src/modules/changelog/changelog.json @@ -9,7 +9,7 @@ "width": 1736, "height": 1440 }, - "content": "yesterday, cobalt hit 1 million users around the world! it's an absolutely insane milestone for us and we're incredibly grateful to everyone saving and creating what they love with help of cobalt. thank you for being our friends.\n\nin anticipation of 7 figure user count, we've revamped the cobalt codebase and infrastructure to be faster and more reliable than ever. a combination of many changes has resulted into incredible download speeds (up to 30 MB/s, as tested by both developers in europe).\n\nnote: there's no backend instance in asia just yet, so if you're there, you might experience average speeds *for now*. you can help us afford a dedicated server in asia by donating to cobalt in the \"donate\" menu.\n\nchanges since the last major update\n\nservice improvements:\n*; youtube music support on the main instance is back!\n*; added support for pinterest images and gifs.\n*; cobalt will now use original soundcloud mp3 file when available.\n*; fixed a youtube bug that prevented some videos from downloading.\n\nupdate on tiktok downloads: they're currently not available, but we're working on a fix. follow our twitter/x account or related github issue for timely updates.\n\nui/ux improvements:\n*; cobalt web app is now fully optimized for ipad. you can add it to home screen from share menu to make it act like a native app!\n*; majorly reduced vertical padding when viewing cobalt in mobile web browser, allowing for more content at once. most noticeable on smaller screens.\n*; status bar color is now dynamic in the web browser on ios and web app on android.\n*; web app on android feels way more native than before.\n*; filename style icons are no longer blurry in safari.\n*; changelog notification no longer overlaps with dynamic island on newer iphones when cobalt is installed as a web app.\n*; fixed safe area padding.\n\nother changes:\n*; added support for freebind, made by one of the cobalt developers.\n*; rate limit and max video length limits are now customizable through environment variables.\n*; cobalt api now returns rate limit headers at all times.\n*; majorly cleaned up the codebase: removed unnecessary functions, rewrote those that were cryptic and confusing. it's way more comprehensible and contribution-friendly than ever before.\n*; moved the cobalt repo to our organization on github. everything stayed the same and all old links link back to it.\n\nnote for instance hosters:\nalong with cobalt repo, the docker image also moved! please update the url for it in your config along with watchtower args to include restarting containers (just in case) as seen in updated docker compose example. we're mirroring packages to old url for now, but it won't last forever.\n\nthat's it for now! hope you have an amazing day and share the 1 million celebration with us :)\n\njoin our discord server to discuss everything cobalt there" + "content": "yesterday, cobalt hit 1 million users around the world! it's an absolutely insane milestone for us and we're incredibly grateful to everyone saving and creating what they love with help of cobalt. thank you for being our friends.\n\nin anticipation of 7 figure user count, we've revamped the cobalt codebase and infrastructure to be faster and more reliable than ever. a combination of many changes has resulted into incredible download speeds (up to 30 MB/s, as tested by both developers in europe).\n\nnote: there's no backend instance in asia just yet, so if you're there, you might experience average speeds *for now*. you can help us afford a dedicated server in asia by donating to cobalt in the \"donate\" menu.\n\nchanges since the last major update\n\nservice improvements:\n*; youtube music support on the main instance is back!\n*; added support for pinterest images and gifs.\n*; cobalt will now use original soundcloud mp3 file when available.\n*; fixed a youtube bug that prevented some videos from downloading.\n\nui/ux improvements:\n*; cobalt web app is now fully optimized for ipad. you can add it to home screen from share menu to make it act like a native app!\n*; majorly reduced vertical padding when viewing cobalt in mobile web browser, allowing for more content at once. most noticeable on smaller screens.\n*; status bar color is now dynamic in the web browser on ios and web app on android.\n*; web app on android feels way more native than before.\n*; filename style icons are no longer blurry in safari.\n*; changelog notification no longer overlaps with dynamic island on newer iphones when cobalt is installed as a web app.\n*; fixed safe area padding.\n\nother changes:\n*; added support for freebind, made by one of the cobalt developers.\n*; rate limit and max video length limits are now customizable through environment variables.\n*; cobalt api now returns rate limit headers at all times.\n*; majorly cleaned up the codebase: removed unnecessary functions, rewrote those that were cryptic and confusing. it's way more comprehensible and contribution-friendly than ever before.\n*; moved the cobalt repo to our organization on github. everything stayed the same and all old links link back to it.\n\nnote for instance hosters:\nalong with cobalt repo, the docker image also moved! please update the url for it in your config along with watchtower args to include restarting containers (just in case) as seen in updated docker compose example. we're mirroring packages to old url for now, but it won't last forever.\n\nthat's it for now! hope you have an amazing day and share the 1 million celebration with us :)\n\njoin our discord server to discuss everything cobalt there" }, "history": [{ "version": "7.13", From e48d222d2e10200da31726883ee28f9d3b9ee0a5 Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 22 May 2024 02:46:00 +0600 Subject: [PATCH 06/15] docs/run-an-instance: update issue path --- docs/run-an-instance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/run-an-instance.md b/docs/run-an-instance.md index 28b9dc77..af408d49 100644 --- a/docs/run-an-instance.md +++ b/docs/run-an-instance.md @@ -41,7 +41,7 @@ setup script installs all needed `npm` dependencies, but you have to install `no 4. done. ### ubuntu 22.04 workaround -`nscd` needs to be installed and running so that the `ffmpeg-static` binary can resolve DNS ([#101](https://github.com/wukko/cobalt/issues/101#issuecomment-1494822258)): +`nscd` needs to be installed and running so that the `ffmpeg-static` binary can resolve DNS ([#101](https://github.com/imputnet/cobalt/issues/101#issuecomment-1494822258)): ```bash sudo apt install nscd From 5199b3d8fd160f4eb19f7322d18b1978c52ec5e2 Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 22 May 2024 02:46:23 +0600 Subject: [PATCH 07/15] package: bump version to 7.14.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b00f21d6..f5e17282 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "cobalt", "description": "save what you love", - "version": "7.14", + "version": "7.14.1", "author": "imput", "exports": "./src/cobalt.js", "type": "module", From 03b1248b5fe8412add1065c446aefed7e3869809 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Tue, 21 May 2024 21:27:23 +0000 Subject: [PATCH 08/15] url/extract: convert input to URL object if passed as string --- src/modules/processing/url.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/modules/processing/url.js b/src/modules/processing/url.js index 51883b1b..a006402c 100644 --- a/src/modules/processing/url.js +++ b/src/modules/processing/url.js @@ -127,6 +127,10 @@ export function normalizeURL(url) { } export function extract(url) { + if (!(url instanceof URL)) { + url = new URL(url); + } + const host = getHostIfValid(url); if (!host || !services[host].enabled) { From 2831bc06ad48282aa0fa3cc94936794d8f67d676 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Tue, 21 May 2024 21:27:35 +0000 Subject: [PATCH 09/15] tiktok: fix shortlink parsing --- src/modules/processing/services/tiktok.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/processing/services/tiktok.js b/src/modules/processing/services/tiktok.js index 6d3cf314..8edb2a5b 100644 --- a/src/modules/processing/services/tiktok.js +++ b/src/modules/processing/services/tiktok.js @@ -20,7 +20,8 @@ export default async function(obj) { if (!html) return { error: 'ErrorCouldntFetch' }; if (html.startsWith('", - "device_id": "", - "channel": "googleplay", - "app_name": "musical_ly", - "version_code": "310503", - "device_platform": "android", - "device_type": "Redmi+7", - "os_version": "13" -}' -``` - -you can compress the json to save space. if you're using a `.env` file then the line would would look like this (***note the quotes***): -``` -TIKTOK_DEVICE_INFO='{"iid":"","device_id":"","channel":"googleplay","app_name":"musical_ly","version_code":"310503","device_platform":"android","device_type":"Redmi+7","os_version":"13"}' -``` - #### FREEBIND_CIDR setting a `FREEBIND_CIDR` allows cobalt to pick a random IP for every download and use it for all requests it makes for that particular download. to use freebind in cobalt, you need to follow its [setup instructions](https://github.com/imputnet/freebind.js?tab=readme-ov-file#setup) first. if you configure this option while running cobalt From 1cbceea69c81bccf935e2a64e013210c7243666d Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 22 May 2024 07:33:51 +0600 Subject: [PATCH 12/15] config.json: update troubleshooting link --- src/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.json b/src/config.json index 13633906..640fb2f5 100644 --- a/src/config.json +++ b/src/config.json @@ -52,7 +52,7 @@ "saveToGalleryShortcut": "https://www.icloud.com/shortcuts/14e9aebf04b24156acc34ceccf7e6fcd", "saveToFilesShortcut": "https://www.icloud.com/shortcuts/2134cd9d4d6b41448b2201f933542b2e", "statusPage": "https://status.cobalt.tools/", - "troubleshootingGuide": "https://github.com/wukko/cobalt/blob/current/docs/troubleshooting.md" + "troubleshootingGuide": "https://github.com/imputnet/cobalt/blob/current/docs/troubleshooting.md" }, "celebrations": { "01-01": "🎄", From ba75b90992ff5e386dfa42468a3eb6a5342208ef Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 22 May 2024 07:54:38 +0600 Subject: [PATCH 13/15] docs: update main instance api url --- docs/api.md | 2 +- docs/examples/docker-compose.example.yml | 8 ++++---- docs/run-an-instance.md | 18 +++++++++--------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/api.md b/docs/api.md index 57509669..87ef2489 100644 --- a/docs/api.md +++ b/docs/api.md @@ -2,7 +2,7 @@ this document provides info about methods and acceptable variables for all cobalt api requests. ``` -👍 you can use co.wuk.sh instance in your projects for free, just don't be an asshole. +👍 you can use api.cobalt.tools in your projects for free, just don't be an asshole. ``` ## POST: `/api/json` diff --git a/docs/examples/docker-compose.example.yml b/docs/examples/docker-compose.example.yml index 8f49b61c..fcbcfc63 100644 --- a/docs/examples/docker-compose.example.yml +++ b/docs/examples/docker-compose.example.yml @@ -17,8 +17,8 @@ services: #- 127.0.0.1:9000:9000 environment: - # replace https://co.wuk.sh/ with your instance's target url in same format - API_URL: "https://co.wuk.sh/" + # replace https://api.cobalt.tools/ with your instance's target url in same format + API_URL: "https://api.cobalt.tools/" # replace eu-nl with your instance's distinctive name API_NAME: "eu-nl" # if you want to use cookies when fetching data from services, uncomment the next line and the lines under volume @@ -49,8 +49,8 @@ services: environment: # replace https://cobalt.tools/ with your instance's target url in same format WEB_URL: "https://cobalt.tools/" - # replace https://co.wuk.sh/ with preferred api instance url - API_URL: "https://co.wuk.sh/" + # replace https://api.cobalt.tools/ with preferred api instance url + API_URL: "https://api.cobalt.tools/" labels: - com.centurylinklabs.watchtower.scope=cobalt diff --git a/docs/run-an-instance.md b/docs/run-an-instance.md index 23d6682e..a440d11d 100644 --- a/docs/run-an-instance.md +++ b/docs/run-an-instance.md @@ -54,7 +54,7 @@ sudo service nscd start |:----------------------|:----------|:------------------------|:------------| | `API_PORT` | `9000` | `9000` | changes port from which api server is accessible. | | `API_LISTEN_ADDRESS` | `0.0.0.0` | `127.0.0.1` | changes address from which api server is accessible. **if you are using docker, you usually don't need to configure this.** | -| `API_URL` | ➖ | `https://co.wuk.sh/` | changes url from which api server is accessible.
***REQUIRED TO RUN THE API***. | +| `API_URL` | ➖ | `https://api.cobalt.tools/` | changes url from which api server is accessible.
***REQUIRED TO RUN THE API***. | | `API_NAME` | `unknown` | `ams-1` | api server name that is shown in `/api/serverInfo`. | | `CORS_WILDCARD` | `1` | `0` | toggles cross-origin resource sharing.
`0`: disabled. `1`: enabled. | | `CORS_URL` | not used | `https://cobalt.tools/` | cross-origin resource sharing url. api will be available only from this url if `CORS_WILDCARD` is set to `0`. | @@ -74,13 +74,13 @@ in a docker container, you also need to set the `API_LISTEN_ADDRESS` env to `127 `network_mode` for the container to `host`. ### variables for web -| variable name | default | example | description | -|:---------------------|:---------------------|:------------------------|:--------------------------------------------------------------------------------------| -| `WEB_PORT` | `9001` | `9001` | changes port from which frontend server is accessible. | -| `WEB_URL` | ➖ | `https://cobalt.tools/` | changes url from which frontend server is accessible.
***REQUIRED TO RUN WEB***. | -| `API_URL` | `https://co.wuk.sh/` | `https://co.wuk.sh/` | changes url which is used for api requests by frontend clients. | -| `SHOW_SPONSORS` | `0` | `1` | toggles sponsor list in about popup.
`0`: disabled. `1`: enabled. | -| `IS_BETA` | `0` | `1` | toggles beta tag next to cobalt logo.
`0`: disabled. `1`: enabled. | -| `PLAUSIBLE_HOSTNAME` | ➖ | `plausible.io`* | enables plausible analytics with provided hostname as receiver backend. | +| variable name | default | example | description | +|:---------------------|:----------------------------|:----------------------------|:--------------------------------------------------------------------------------------| +| `WEB_PORT` | `9001` | `9001` | changes port from which frontend server is accessible. | +| `WEB_URL` | ➖ | `https://cobalt.tools/` | changes url from which frontend server is accessible.
***REQUIRED TO RUN WEB***. | +| `API_URL` | `https://api.cobalt.tools/` | `https://api.cobalt.tools/` | changes url which is used for api requests by frontend clients. | +| `SHOW_SPONSORS` | `0` | `1` | toggles sponsor list in about popup.
`0`: disabled. `1`: enabled. | +| `IS_BETA` | `0` | `1` | toggles beta tag next to cobalt logo.
`0`: disabled. `1`: enabled. | +| `PLAUSIBLE_HOSTNAME` | ➖ | `plausible.io`* | enables plausible analytics with provided hostname as receiver backend. | \* don't use plausible.io as receiver backend unless you paid for their cloud service. use your own domain when hosting community edition of plausible. refer to their [docs](https://plausible.io/docs) when needed. From 6c7aa57978a9a79bfd19d8e7fabda2e074265ef8 Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 22 May 2024 07:54:49 +0600 Subject: [PATCH 14/15] setup: update main instance api url --- src/modules/setup.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/setup.js b/src/modules/setup.js index 80032fcd..137f6271 100644 --- a/src/modules/setup.js +++ b/src/modules/setup.js @@ -36,7 +36,7 @@ function setup() { rl.question(q, r1 => { switch (r1.toLowerCase()) { case 'api': - console.log(Bright("\nCool! What's the domain this API instance will be running on? (localhost)\nExample: co.wuk.sh")); + console.log(Bright("\nCool! What's the domain this API instance will be running on? (localhost)\nExample: api.cobalt.tools")); rl.question(q, apiURL => { ob.API_URL = `http://localhost:9000/`; @@ -83,13 +83,13 @@ function setup() { if (webPort && (webURL === "localhost" || !webURL)) ob.WEB_URL = `http://localhost:${webPort}/`; console.log( - Bright("\nOne last thing: what default API domain should be used? (co.wuk.sh)\nIf it's hosted locally, make sure to include the port:") + Cyan(" localhost:9000") + Bright("\nOne last thing: what default API domain should be used? (api.cobalt.tools)\nIf it's hosted locally, make sure to include the port:") + Cyan(" localhost:9000") ); rl.question(q, apiURL => { ob.API_URL = `https://${apiURL.toLowerCase()}/`; if (apiURL.includes(':')) ob.API_URL = `http://${apiURL.toLowerCase()}/`; - if (!apiURL) ob.API_URL = "https://co.wuk.sh/"; + if (!apiURL) ob.API_URL = "https://api.cobalt.tools/"; final() }) }); From 209fa32ec2a0212dfc912133492a2738eee84585 Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 22 May 2024 07:54:58 +0600 Subject: [PATCH 15/15] readme: update main instance api url --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3e363c64..c67631be 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ this list is not final and keeps expanding over time. if support for a service y ## cobalt api cobalt has an open api that you can use in your projects *for free~*. it's easy and straightforward to use, [check out the docs](/docs/api.md) to learn how to use it. -✅ you can use the main api instance ([co.wuk.sh](https://co.wuk.sh/)) in your **personal** projects. +✅ you can use the main api instance ([api.cobalt.tools](https://api.cobalt.tools/)) in your **personal** projects. ❌ you cannot use the free api commercially (anywhere that's gated behind paywalls or ads). host your own instance for this. we reserve the right to restrict abusive/excessive access to the main instance api.