Files
windmill_workflow/alexa-api/test_tts.js
2026-03-03 12:02:55 +09:00

120 lines
4.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* test_tts.js - TTS API テスト
* node test_tts.js
*/
const https = require('https');
const fs = require('fs');
const path = require('path');
const envContent = fs.readFileSync(path.join(__dirname, '.env'), 'utf8');
const COOKIE_STR = envContent.match(/ALEXA_COOKIE=(.+)/)[1].trim();
function makeRequest(url, options = {}, extraCookies = '') {
return new Promise((resolve, reject) => {
const parsed = new URL(url);
const allCookies = COOKIE_STR + (extraCookies ? '; ' + extraCookies : '');
const reqOpts = {
hostname: parsed.hostname,
path: parsed.pathname + parsed.search,
method: options.method || 'GET',
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'ja-JP,ja;q=0.9',
'Cookie': allCookies,
...(options.headers || {}),
},
};
const req = https.request(reqOpts, (res) => {
let body = '';
res.on('data', d => body += d);
res.on('end', () => resolve({ status: res.statusCode, headers: res.headers, body }));
});
req.on('error', reject);
if (options.body) req.write(options.body);
req.end();
});
}
async function main() {
// 1. CSRFトークン取得
console.log('[1] CSRF token取得...');
const langRes = await makeRequest('https://alexa.amazon.co.jp/api/language');
const setCookies = langRes.headers['set-cookie'] || [];
const csrfCookieStr = setCookies.find(c => c.startsWith('csrf='));
const csrfToken = csrfCookieStr ? csrfCookieStr.split('=')[1].split(';')[0] : null;
console.log(' CSRF token:', csrfToken);
console.log(' Status:', langRes.status);
if (!csrfToken) { console.error('CSRF token not found!'); process.exit(1); }
// 2. デバイス一覧取得
console.log('[2] デバイス一覧取得...');
const devRes = await makeRequest('https://alexa.amazon.co.jp/api/devices-v2/device?cached=false');
console.log(' Status:', devRes.status);
const devices = JSON.parse(devRes.body).devices || [];
console.log(' Device count:', devices.length);
// デバイス一覧表示
devices.filter(d => d.deviceFamily !== 'TABLET').forEach(d => {
console.log(` - ${d.accountName} (type=${d.deviceType}, serial=${d.serialNumber})`);
});
// プレハブを探す
const target = devices.find(d => d.serialNumber === 'G0922H08525302K5');
console.log('\nTarget device:', target ? `${target.accountName}` : 'NOT FOUND');
if (!target) { process.exit(1); }
// 2.5. カスタマーIDを取得
const bootstrapRes = await makeRequest('https://alexa.amazon.co.jp/api/bootstrap');
const bootstrap = JSON.parse(bootstrapRes.body);
const customerId = bootstrap.authentication?.customerId;
console.log(' Customer ID:', customerId);
// 3. TTSリクエスト
const sequenceObj = {
'@type': 'com.amazon.alexa.behaviors.model.Sequence',
startNode: {
'@type': 'com.amazon.alexa.behaviors.model.OpaquePayloadOperationNode',
type: 'Alexa.Speak',
operationPayload: {
deviceType: target.deviceType,
deviceSerialNumber: target.serialNumber,
customerId: customerId,
locale: 'ja-JP',
textToSpeak: 'テストです。聞こえますか',
},
},
};
const bodyObj = {
behaviorId: 'PREVIEW',
sequenceJson: JSON.stringify(sequenceObj),
status: 'ENABLED',
};
const body = JSON.stringify(bodyObj);
console.log('\n[3] TTS送信...');
const ttsRes = await makeRequest('https://alexa.amazon.co.jp/api/behaviors/preview', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'csrf': csrfToken,
'Referer': 'https://alexa.amazon.co.jp/spa/index.html',
'Origin': 'https://alexa.amazon.co.jp',
},
body,
}, `csrf=${csrfToken}`);
console.log('TTS status:', ttsRes.status);
console.log('TTS response:', ttsRes.body.substring(0, 500));
if (ttsRes.status === 200 || ttsRes.status === 202) {
console.log('\n成功エコーがしゃべるはずです。');
}
}
main().catch(console.error);