設定一行で移行無料APIキーを取得
Euler StreamからTik.Toolsへ、設定一行で乗り換え
TikTokLive(Python)やtiktok-live-connector(Node)はそのまま。署名プロバイダーのホストを差し替えるだけです。イベント名もSDKもコードも変わりません。
// connector-drop-in.mjs
// Run: npm i tiktok-live-connector && node connector-drop-in.mjs
// Existing Euler Stream users: ONLY change is the signProviderHost line.
import { WebcastPushConnection } from 'tiktok-live-connector';
const USER = (process.argv[2] || '').replace(/^@/, '') || 'aljazeeraenglish';
const KEY = 'your_api_key'; // <- swap for your free key at https://tik.tools
const conn = new WebcastPushConnection(USER, {
// ↓↓↓ THE ONE LINE TO CHANGE ↓↓↓
signProviderHost: 'https://api.tik.tools', // was: 'https://tiktok.eulerstream.com'
signProviderApiKey: KEY, // was: your Euler API key
// ↑↑↑ THE ONE LINE TO CHANGE ↑↑↑
enableExtendedGiftInfo: true,
});
conn.on('connected', s => console.log('Connected, room', s.roomId));
conn.on('chat', d => console.log('[chat]', d.uniqueId + ':', d.comment));
conn.on('gift', d => console.log('[gift]', d.uniqueId + ' sent', d.giftName, 'x' + d.repeatCount));
conn.on('like', d => console.log('[like]', d.uniqueId, '+' + d.likeCount));
conn.on('member', d => console.log('[join]', d.uniqueId));
conn.on('disconnected', () => console.log('Closed.'));
await conn.connect();# tiktoklive-drop-in.py
# Run: pip install TikTokLive && python tiktoklive-drop-in.py aljazeeraenglish
# Existing Euler Stream users: ONLY change is the sign_api_url line.
import sys
from TikTokLive import TikTokLiveClient
from TikTokLive.events import ConnectEvent, CommentEvent, GiftEvent, LikeEvent, JoinEvent
USER = (sys.argv[1] if len(sys.argv) > 1 else '').lstrip('@') or 'aljazeeraenglish'
KEY = 'your_api_key' # <- swap for your free key at https://tik.tools
client = TikTokLiveClient(
unique_id=USER,
# ↓↓↓ THE ONE LINE TO CHANGE ↓↓↓
sign_api_key=KEY, # was: your Euler API key
web_proxy='https://api.tik.tools', # was: https://tiktok.eulerstream.com (set via TIKTOK_LIVE_SIGN_HOST too)
# ↑↑↑ THE ONE LINE TO CHANGE ↑↑↑
)
@client.on(ConnectEvent)
async def on_connect(e): print('Connected, room', e.unique_id)
@client.on(CommentEvent)
async def on_chat(e): print(f"[chat] {e.user.unique_id}: {e.comment}")
@client.on(GiftEvent)
async def on_gift(e):
if e.gift.streakable and not e.streaking: return
print(f"[gift] {e.user.unique_id} sent {e.gift.name} x{e.repeat_count}")
@client.on(LikeEvent)
async def on_like(e): print(f"[like] {e.user.unique_id} +{e.count}")
@client.on(JoinEvent)
async def on_join(e): print(f"[join] {e.user.unique_id}")
client.run()<!DOCTYPE html>
<!-- Save as euler-dropin.html and double-click. No SDK install needed -
this hits the same sign endpoint Euler Stream users already use,
then pipes the events into a <video>-tag-friendly DOM stream. -->
<meta charset="utf-8">
<title>Tik.Tools - Euler Stream drop-in</title>
<style>
body{font:14px ui-monospace,Menlo,monospace;background:#0a0a0c;color:#e4e4e7;padding:20px;max-width:760px;margin:0 auto}
h1{font-size:18px;margin:0 0 8px}
.bar{display:flex;gap:8px;margin:8px 0 14px}
input,button{font:inherit;background:#14141a;color:#fff;border:1px solid #333;border-radius:6px;padding:6px 10px}
button{background:#2a2a2a;border:none;cursor:pointer;font-weight:700}
.row{padding:6px 10px;border-bottom:1px solid #222;display:flex;gap:10px}
.t{color:#d1d3d4;width:60px;font-size:11px;text-transform:uppercase}
</style>
<h1>Drop-in for Euler Stream</h1>
<div class="bar">
<input id="u" placeholder="username (default: aljazeeraenglish)" />
<button id="go">Connect</button>
</div>
<div id="s">Same flow Euler exposes: JWT mint -> WebSocket. Just point at api.tik.tools.</div>
<div id="feed"></div>
<script>
// EXACTLY the same call shape Euler users make to their /authentication/jwt.
// Only difference: BASE = 'https://api.tik.tools' (was: 'https://tiktok.eulerstream.com')
const BASE = 'https://api.tik.tools';
const WSURL = 'wss://api.tik.tools';
const KEY = 'your_api_key'; // <- swap for your free key at https://tik.tools
let ws = null;
async function connect() {
if (ws) try { ws.close(); } catch {}
feed.innerHTML = '';
let user = u.value.trim().replace(/^@/, '');
if (!user) {
s.textContent = 'Picking a random live creator...';
try {
const r = await fetch(BASE + '/api/live/top-channels').then(r => r.json());
user = (r.channels && r.channels[0] && r.channels[0].uniqueId) || '';
} catch {}
if (!user) { s.textContent = 'No live creators right now, try again in a minute.'; return; }
}
s.textContent = 'Minting JWT...';
const j = await fetch(BASE + '/authentication/jwt?apiKey=' + KEY, {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ allowed_creators: [user], expire_after: 600, max_websockets: 1 }),
}).then(r => r.json());
const token = j.data && j.data.token;
if (!token) { s.textContent = 'Auth failed - get a free key at https://tik.tools'; return; }
s.textContent = 'Connecting to @' + user + '...';
ws = new WebSocket(WSURL + '?uniqueId=' + user + '&jwtKey=' + encodeURIComponent(token));
ws.onopen = () => s.textContent = '@' + user + ' - LIVE (Euler-shape drop-in)';
ws.onmessage = ev => {
const e = JSON.parse(ev.data);
if (e.event === 'roomInfo' || !e.event) return;
const d = e.data || {}, nm = (d.user && d.user.nickname) || d.user_unique_id || 'someone';
const text = d.comment || (d.giftName ? 'sent ' + d.giftName + ' x' + (d.repeatCount || 1) : '');
feed.insertAdjacentHTML('afterbegin',
'<div class="row"><span class="t">' + e.event + '</span><span>' + nm + '</span><span style="color:#9aa0a6;flex:1">' + text + '</span></div>');
while (feed.children.length > 50) feed.removeChild(feed.lastChild);
};
ws.onclose = ev => { s.textContent = 'Closed: ' + (ev.reason || ev.code); };
}
go.onclick = connect;
// Auto-connect on load so the embedded preview starts immediately.
connect();
</script>Write me a minimal one-file program that migrates an existing Euler Stream TikTokLive integration to Tik.Tools. ONE config line changes.
For Python (using TikTokLive lib):
- Was: TikTokLiveClient(unique_id=X, sign_api_key='euler_key')
- Now: TikTokLiveClient(unique_id=X, sign_api_key='your_api_key', web_proxy='https://api.tik.tools')
- Set env TIKTOK_LIVE_SIGN_HOST=https://api.tik.tools OR pass web_proxy
For Node (tiktok-live-connector):
- Was: new WebcastPushConnection(X, { signProviderHost: 'https://tiktok.eulerstream.com', signProviderApiKey: 'euler_key' })
- Now: new WebcastPushConnection(X, { signProviderHost: 'https://api.tik.tools', signProviderApiKey: 'your_api_key' })
For raw HTML/JS (no SDK):
- POST https://api.tik.tools/authentication/jwt?apiKey=your_api_key body {"allowed_creators":["<user>"],"expire_after":600,"max_websockets":1}
- Open WS wss://api.tik.tools?uniqueId=<user>&jwtKey=<token>
The demo key 'your_api_key' is the public default: 10-min sessions, 1 concurrent WS, strict per-IP daily caps. For production parity with Euler, sign up at https://tik.tools for a real key + access to /webcast/fetch /webcast/sign_url /webcast/ws_credentials (full Euler endpoint shape).
Pick the language I asked for. Comment the swap line. Stupid simple to copy/paste.ライブプレビュー
そのまま動く様子をここで確認
Eulerと同じハンドシェイクです: 署名付きトークンの発行 -> WebSocket。下のiframeでは、スニペットのHTML版をそのままapi.tik.toolsに対して実行しています。コピーして貼り付ければ、同じ結果が得られます。
euler-dropin.html実行中
表示されるとプレビューを読み込みます。
// connector-drop-in.mjs
// Run: npm i tiktok-live-connector && node connector-drop-in.mjs
// Existing Euler Stream users: ONLY change is the signProviderHost line.
import { WebcastPushConnection } from 'tiktok-live-connector';
const USER = (process.argv[2] || '').replace(/^@/, '') || 'aljazeeraenglish';
const KEY = 'your_api_key'; // <- swap for your free key at https://tik.tools
const conn = new WebcastPushConnection(USER, {
// ↓↓↓ THE ONE LINE TO CHANGE ↓↓↓
signProviderHost: 'https://api.tik.tools', // was: 'https://tiktok.eulerstream.com'
signProviderApiKey: KEY, // was: your Euler API key
// ↑↑↑ THE ONE LINE TO CHANGE ↑↑↑
enableExtendedGiftInfo: true,
});
conn.on('connected', s => console.log('Connected, room', s.roomId));
conn.on('chat', d => console.log('[chat]', d.uniqueId + ':', d.comment));
conn.on('gift', d => console.log('[gift]', d.uniqueId + ' sent', d.giftName, 'x' + d.repeatCount));
conn.on('like', d => console.log('[like]', d.uniqueId, '+' + d.likeCount));
conn.on('member', d => console.log('[join]', d.uniqueId));
conn.on('disconnected', () => console.log('Closed.'));
await conn.connect();# tiktoklive-drop-in.py
# Run: pip install TikTokLive && python tiktoklive-drop-in.py aljazeeraenglish
# Existing Euler Stream users: ONLY change is the sign_api_url line.
import sys
from TikTokLive import TikTokLiveClient
from TikTokLive.events import ConnectEvent, CommentEvent, GiftEvent, LikeEvent, JoinEvent
USER = (sys.argv[1] if len(sys.argv) > 1 else '').lstrip('@') or 'aljazeeraenglish'
KEY = 'your_api_key' # <- swap for your free key at https://tik.tools
client = TikTokLiveClient(
unique_id=USER,
# ↓↓↓ THE ONE LINE TO CHANGE ↓↓↓
sign_api_key=KEY, # was: your Euler API key
web_proxy='https://api.tik.tools', # was: https://tiktok.eulerstream.com (set via TIKTOK_LIVE_SIGN_HOST too)
# ↑↑↑ THE ONE LINE TO CHANGE ↑↑↑
)
@client.on(ConnectEvent)
async def on_connect(e): print('Connected, room', e.unique_id)
@client.on(CommentEvent)
async def on_chat(e): print(f"[chat] {e.user.unique_id}: {e.comment}")
@client.on(GiftEvent)
async def on_gift(e):
if e.gift.streakable and not e.streaking: return
print(f"[gift] {e.user.unique_id} sent {e.gift.name} x{e.repeat_count}")
@client.on(LikeEvent)
async def on_like(e): print(f"[like] {e.user.unique_id} +{e.count}")
@client.on(JoinEvent)
async def on_join(e): print(f"[join] {e.user.unique_id}")
client.run()<!DOCTYPE html>
<!-- Save as euler-dropin.html and double-click. No SDK install needed -
this hits the same sign endpoint Euler Stream users already use,
then pipes the events into a <video>-tag-friendly DOM stream. -->
<meta charset="utf-8">
<title>Tik.Tools - Euler Stream drop-in</title>
<style>
body{font:14px ui-monospace,Menlo,monospace;background:#0a0a0c;color:#e4e4e7;padding:20px;max-width:760px;margin:0 auto}
h1{font-size:18px;margin:0 0 8px}
.bar{display:flex;gap:8px;margin:8px 0 14px}
input,button{font:inherit;background:#14141a;color:#fff;border:1px solid #333;border-radius:6px;padding:6px 10px}
button{background:#2a2a2a;border:none;cursor:pointer;font-weight:700}
.row{padding:6px 10px;border-bottom:1px solid #222;display:flex;gap:10px}
.t{color:#d1d3d4;width:60px;font-size:11px;text-transform:uppercase}
</style>
<h1>Drop-in for Euler Stream</h1>
<div class="bar">
<input id="u" placeholder="username (default: aljazeeraenglish)" />
<button id="go">Connect</button>
</div>
<div id="s">Same flow Euler exposes: JWT mint -> WebSocket. Just point at api.tik.tools.</div>
<div id="feed"></div>
<script>
// EXACTLY the same call shape Euler users make to their /authentication/jwt.
// Only difference: BASE = 'https://api.tik.tools' (was: 'https://tiktok.eulerstream.com')
const BASE = 'https://api.tik.tools';
const WSURL = 'wss://api.tik.tools';
const KEY = 'your_api_key'; // <- swap for your free key at https://tik.tools
let ws = null;
async function connect() {
if (ws) try { ws.close(); } catch {}
feed.innerHTML = '';
let user = u.value.trim().replace(/^@/, '');
if (!user) {
s.textContent = 'Picking a random live creator...';
try {
const r = await fetch(BASE + '/api/live/top-channels').then(r => r.json());
user = (r.channels && r.channels[0] && r.channels[0].uniqueId) || '';
} catch {}
if (!user) { s.textContent = 'No live creators right now, try again in a minute.'; return; }
}
s.textContent = 'Minting JWT...';
const j = await fetch(BASE + '/authentication/jwt?apiKey=' + KEY, {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ allowed_creators: [user], expire_after: 600, max_websockets: 1 }),
}).then(r => r.json());
const token = j.data && j.data.token;
if (!token) { s.textContent = 'Auth failed - get a free key at https://tik.tools'; return; }
s.textContent = 'Connecting to @' + user + '...';
ws = new WebSocket(WSURL + '?uniqueId=' + user + '&jwtKey=' + encodeURIComponent(token));
ws.onopen = () => s.textContent = '@' + user + ' - LIVE (Euler-shape drop-in)';
ws.onmessage = ev => {
const e = JSON.parse(ev.data);
if (e.event === 'roomInfo' || !e.event) return;
const d = e.data || {}, nm = (d.user && d.user.nickname) || d.user_unique_id || 'someone';
const text = d.comment || (d.giftName ? 'sent ' + d.giftName + ' x' + (d.repeatCount || 1) : '');
feed.insertAdjacentHTML('afterbegin',
'<div class="row"><span class="t">' + e.event + '</span><span>' + nm + '</span><span style="color:#9aa0a6;flex:1">' + text + '</span></div>');
while (feed.children.length > 50) feed.removeChild(feed.lastChild);
};
ws.onclose = ev => { s.textContent = 'Closed: ' + (ev.reason || ev.code); };
}
go.onclick = connect;
// Auto-connect on load so the embedded preview starts immediately.
connect();
</script>Write me a minimal one-file program that migrates an existing Euler Stream TikTokLive integration to Tik.Tools. ONE config line changes.
For Python (using TikTokLive lib):
- Was: TikTokLiveClient(unique_id=X, sign_api_key='euler_key')
- Now: TikTokLiveClient(unique_id=X, sign_api_key='your_api_key', web_proxy='https://api.tik.tools')
- Set env TIKTOK_LIVE_SIGN_HOST=https://api.tik.tools OR pass web_proxy
For Node (tiktok-live-connector):
- Was: new WebcastPushConnection(X, { signProviderHost: 'https://tiktok.eulerstream.com', signProviderApiKey: 'euler_key' })
- Now: new WebcastPushConnection(X, { signProviderHost: 'https://api.tik.tools', signProviderApiKey: 'your_api_key' })
For raw HTML/JS (no SDK):
- POST https://api.tik.tools/authentication/jwt?apiKey=your_api_key body {"allowed_creators":["<user>"],"expire_after":600,"max_websockets":1}
- Open WS wss://api.tik.tools?uniqueId=<user>&jwtKey=<token>
The demo key 'your_api_key' is the public default: 10-min sessions, 1 concurrent WS, strict per-IP daily caps. For production parity with Euler, sign up at https://tik.tools for a real key + access to /webcast/fetch /webcast/sign_url /webcast/ws_credentials (full Euler endpoint shape).
Pick the language I asked for. Comment the swap line. Stupid simple to copy/paste.ステップごとに解説
ステップは二つ。リファクタリングは不要。
1
署名プロバイダーのホストを差し替える
SDKの初期化で設定を二行変えるだけ。署名バックエンドの向き先をhttps://tiktok.eulerstream.comからhttps://api.tik.toolsに変更します。既存のイベントハンドラー、ルームID、SDKのコードはそのままです。tik.toolsのAPIプランはすべてそのまま置き換えて使えます。デモキーyour_api_keyなら登録なしで、制限付きで試せます。
// Node — tiktok-live-connector v2.x (verified working against api.tik.tools)
import { TikTokLiveConnection, SignConfig, WebcastEvent } from 'tiktok-live-connector'
SignConfig.basePath = 'https://api.tik.tools' // was: https://tiktok.eulerstream.com
SignConfig.apiKey = 'tk_your_key' // your tik.tools key
const conn = new TikTokLiveConnection('@username', { fetchRoomInfoOnConnect: false })
conn.on(WebcastEvent.CHAT, e => console.log(e.user.uniqueId, ':', e.comment))
await conn.connect()
// Or env-var (no code change at all):
// SIGN_API_URL=https://api.tik.tools SIGN_API_KEY=tk_your_key node app.js# Python — TikTokLive v6.6+ (one config swap, existing code unchanged)
from TikTokLive.client.web.web_settings import WebDefaults
from TikTokLive import TikTokLiveClient
from TikTokLive.events import CommentEvent
WebDefaults.tiktok_sign_url = "https://api.tik.tools" # was: https://tiktok.eulerstream.com
WebDefaults.tiktok_sign_api_key = "tk_your_key"
client = TikTokLiveClient(unique_id="@username")
@client.on(CommentEvent)
async def on_chat(ev): print(ev.user.unique_id, ":", ev.comment)
await client.connect() # add fetch_live_check=False if running from a datacenter IP
# Or env-var (zero code change):
# SIGN_API_URL=https://api.tik.tools SIGN_API_KEY=tk_your_key python app.py// Direct @eulerstream/euler-api-sdk users — swap basePath
import { EulerStreamApiClient } from '@eulerstream/euler-api-sdk'
const client = new EulerStreamApiClient({
basePath: 'https://api.tik.tools',
apiKey: 'tk_your_key',
})
// Every webcast.* / premium.* / moderation.* method routes to tik.tools.
const res = await client.webcast.retrieveRoomId('username')
console.log(res.data.room_id)// connector-drop-in.mjs
// Run: npm i tiktok-live-connector && node connector-drop-in.mjs
// Existing Euler Stream users: ONLY change is the signProviderHost line.
import { WebcastPushConnection } from 'tiktok-live-connector';
const USER = (process.argv[2] || '').replace(/^@/, '') || 'aljazeeraenglish';
const KEY = 'your_api_key'; // <- swap for your free key at https://tik.tools
const conn = new WebcastPushConnection(USER, {
// ↓↓↓ THE ONE LINE TO CHANGE ↓↓↓
signProviderHost: 'https://api.tik.tools', // was: 'https://tiktok.eulerstream.com'
signProviderApiKey: KEY, // was: your Euler API key
// ↑↑↑ THE ONE LINE TO CHANGE ↑↑↑
enableExtendedGiftInfo: true,
});
conn.on('connected', s => console.log('Connected, room', s.roomId));
conn.on('chat', d => console.log('[chat]', d.uniqueId + ':', d.comment));
conn.on('gift', d => console.log('[gift]', d.uniqueId + ' sent', d.giftName, 'x' + d.repeatCount));
conn.on('like', d => console.log('[like]', d.uniqueId, '+' + d.likeCount));
conn.on('member', d => console.log('[join]', d.uniqueId));
conn.on('disconnected', () => console.log('Closed.'));
await conn.connect();# tiktoklive-drop-in.py
# Run: pip install TikTokLive && python tiktoklive-drop-in.py aljazeeraenglish
# Existing Euler Stream users: ONLY change is the sign_api_url line.
import sys
from TikTokLive import TikTokLiveClient
from TikTokLive.events import ConnectEvent, CommentEvent, GiftEvent, LikeEvent, JoinEvent
USER = (sys.argv[1] if len(sys.argv) > 1 else '').lstrip('@') or 'aljazeeraenglish'
KEY = 'your_api_key' # <- swap for your free key at https://tik.tools
client = TikTokLiveClient(
unique_id=USER,
# ↓↓↓ THE ONE LINE TO CHANGE ↓↓↓
sign_api_key=KEY, # was: your Euler API key
web_proxy='https://api.tik.tools', # was: https://tiktok.eulerstream.com (set via TIKTOK_LIVE_SIGN_HOST too)
# ↑↑↑ THE ONE LINE TO CHANGE ↑↑↑
)
@client.on(ConnectEvent)
async def on_connect(e): print('Connected, room', e.unique_id)
@client.on(CommentEvent)
async def on_chat(e): print(f"[chat] {e.user.unique_id}: {e.comment}")
@client.on(GiftEvent)
async def on_gift(e):
if e.gift.streakable and not e.streaking: return
print(f"[gift] {e.user.unique_id} sent {e.gift.name} x{e.repeat_count}")
@client.on(LikeEvent)
async def on_like(e): print(f"[like] {e.user.unique_id} +{e.count}")
@client.on(JoinEvent)
async def on_join(e): print(f"[join] {e.user.unique_id}")
client.run()<!DOCTYPE html>
<!-- Save as euler-dropin.html and double-click. No SDK install needed -
this hits the same sign endpoint Euler Stream users already use,
then pipes the events into a <video>-tag-friendly DOM stream. -->
<meta charset="utf-8">
<title>Tik.Tools - Euler Stream drop-in</title>
<style>
body{font:14px ui-monospace,Menlo,monospace;background:#0a0a0c;color:#e4e4e7;padding:20px;max-width:760px;margin:0 auto}
h1{font-size:18px;margin:0 0 8px}
.bar{display:flex;gap:8px;margin:8px 0 14px}
input,button{font:inherit;background:#14141a;color:#fff;border:1px solid #333;border-radius:6px;padding:6px 10px}
button{background:#2a2a2a;border:none;cursor:pointer;font-weight:700}
.row{padding:6px 10px;border-bottom:1px solid #222;display:flex;gap:10px}
.t{color:#d1d3d4;width:60px;font-size:11px;text-transform:uppercase}
</style>
<h1>Drop-in for Euler Stream</h1>
<div class="bar">
<input id="u" placeholder="username (default: aljazeeraenglish)" />
<button id="go">Connect</button>
</div>
<div id="s">Same flow Euler exposes: JWT mint -> WebSocket. Just point at api.tik.tools.</div>
<div id="feed"></div>
<script>
// EXACTLY the same call shape Euler users make to their /authentication/jwt.
// Only difference: BASE = 'https://api.tik.tools' (was: 'https://tiktok.eulerstream.com')
const BASE = 'https://api.tik.tools';
const WSURL = 'wss://api.tik.tools';
const KEY = 'your_api_key'; // <- swap for your free key at https://tik.tools
let ws = null;
async function connect() {
if (ws) try { ws.close(); } catch {}
feed.innerHTML = '';
let user = u.value.trim().replace(/^@/, '');
if (!user) {
s.textContent = 'Picking a random live creator...';
try {
const r = await fetch(BASE + '/api/live/top-channels').then(r => r.json());
user = (r.channels && r.channels[0] && r.channels[0].uniqueId) || '';
} catch {}
if (!user) { s.textContent = 'No live creators right now, try again in a minute.'; return; }
}
s.textContent = 'Minting JWT...';
const j = await fetch(BASE + '/authentication/jwt?apiKey=' + KEY, {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ allowed_creators: [user], expire_after: 600, max_websockets: 1 }),
}).then(r => r.json());
const token = j.data && j.data.token;
if (!token) { s.textContent = 'Auth failed - get a free key at https://tik.tools'; return; }
s.textContent = 'Connecting to @' + user + '...';
ws = new WebSocket(WSURL + '?uniqueId=' + user + '&jwtKey=' + encodeURIComponent(token));
ws.onopen = () => s.textContent = '@' + user + ' - LIVE (Euler-shape drop-in)';
ws.onmessage = ev => {
const e = JSON.parse(ev.data);
if (e.event === 'roomInfo' || !e.event) return;
const d = e.data || {}, nm = (d.user && d.user.nickname) || d.user_unique_id || 'someone';
const text = d.comment || (d.giftName ? 'sent ' + d.giftName + ' x' + (d.repeatCount || 1) : '');
feed.insertAdjacentHTML('afterbegin',
'<div class="row"><span class="t">' + e.event + '</span><span>' + nm + '</span><span style="color:#9aa0a6;flex:1">' + text + '</span></div>');
while (feed.children.length > 50) feed.removeChild(feed.lastChild);
};
ws.onclose = ev => { s.textContent = 'Closed: ' + (ev.reason || ev.code); };
}
go.onclick = connect;
// Auto-connect on load so the embedded preview starts immediately.
connect();
</script>Write me a minimal one-file program that migrates an existing Euler Stream TikTokLive integration to Tik.Tools. ONE config line changes.
For Python (using TikTokLive lib):
- Was: TikTokLiveClient(unique_id=X, sign_api_key='euler_key')
- Now: TikTokLiveClient(unique_id=X, sign_api_key='your_api_key', web_proxy='https://api.tik.tools')
- Set env TIKTOK_LIVE_SIGN_HOST=https://api.tik.tools OR pass web_proxy
For Node (tiktok-live-connector):
- Was: new WebcastPushConnection(X, { signProviderHost: 'https://tiktok.eulerstream.com', signProviderApiKey: 'euler_key' })
- Now: new WebcastPushConnection(X, { signProviderHost: 'https://api.tik.tools', signProviderApiKey: 'your_api_key' })
For raw HTML/JS (no SDK):
- POST https://api.tik.tools/authentication/jwt?apiKey=your_api_key body {"allowed_creators":["<user>"],"expire_after":600,"max_websockets":1}
- Open WS wss://api.tik.tools?uniqueId=<user>&jwtKey=<token>
The demo key 'your_api_key' is the public default: 10-min sessions, 1 concurrent WS, strict per-IP daily caps. For production parity with Euler, sign up at https://tik.tools for a real key + access to /webcast/fetch /webcast/sign_url /webcast/ws_credentials (full Euler endpoint shape).
Pick the language I asked for. Comment the swap line. Stupid simple to copy/paste.2
準備ができたら本番用のAPIキーを取得
デモキーyour_api_keyは登録なしで使えますが、上限はWebSocket 1本 / 1セッション10分 / IPあたり1時間に6回の接続です。より高い上限とEulerエンドポイントの完全な互換性が必要ならTik.Toolsの無料キーを取得。
エンドポイント互換
Eulerのすべてのエンドポイントが1:1で対応
Tik.ToolsはEulerのエンドポイント構成をそのまま再現しているので、Euler対応のSDKはパッチなしで動き続けます。
| Euler Stream | Tik.Tools(同じパス) | プラン |
|---|---|---|
POST /webcast/sign_url | POST /webcast/sign_url | デモ |
GET /webcast/check_alive | GET /webcast/check_alive | デモ |
POST /webcast/fetch | POST /webcast/fetch | Basic+ |
POST /webcast/ws_credentials | POST /webcast/ws_credentials | Basic+ |
POST /webcast/sign_websocket | POST /webcast/sign_websocket | Basic+ |
GET /webcast/room_id | GET /webcast/room_id | デモ |
POST /webcast/room_info | POST /webcast/room_info | デモ |
POST /webcast/bulk_live_check | POST /webcast/bulk_live_check | Basic+ |
| おまけ(Eulerにはない機能): 公開ティッカー、ランキング | デモ | |
レスポンス形式は同じです。 sign_urlは
{ status_code, data: { signed_url, x_bogus, user_agent, cookies } }を返します。既存のパーサーはそのまま使えます。レスポンス形式
同じJSONに、移行ヒントを追加
POST https://api.tik.tools/webcast/sign_url?apiKey=your_api_key
Body: { "url": "<upstream URL>" }
Response:
{
"status_code": 0,
"data": {
"signed_url": "<signed upstream URL>",
"x_bogus": "...",
"user_agent": "Mozilla/5.0 ...",
"cookies": "ttwid=<fresh visitor cookie>"
}
}