Kraft102's picture
Update backend source
34367da verified
/**
* Minimal Showpad Integration Test
* Tests Showpad API connection and asset fetching
*
* REQUIREMENTS:
* - SHOWPAD_CLIENT_ID and SHOWPAD_CLIENT_SECRET must be set
* - Create OAuth client at: https://tdcerhverv.showpad.biz Admin > API > OAuth Clients
*/
import { config } from 'dotenv';
import { resolve } from 'path';
// Load environment
const __dirname = new URL('.', import.meta.url).pathname.replace(/^\/([A-Z]:)/, '$1');
config({ path: resolve(__dirname, '../.env') });
console.log('Testing Showpad Integration...\n');
console.log('Config:');
console.log(' Subdomain:', process.env.SHOWPAD_SUBDOMAIN || '(missing)');
console.log(' Username:', process.env.SHOWPAD_USERNAME || '(missing)');
console.log(' Password:', process.env.SHOWPAD_PASSWORD ? '***' : '(missing)');
console.log(' Client ID:', process.env.SHOWPAD_CLIENT_ID || '❌ MISSING - CREATE AT SHOWPAD ADMIN');
console.log(' Client Secret:', process.env.SHOWPAD_CLIENT_SECRET ? '***' : '❌ MISSING - CREATE AT SHOWPAD ADMIN');
console.log('');
interface ShowpadAuthResponse {
access_token: string;
token_type: string;
expires_in: number;
}
async function testShowpadAuth(): Promise<string | null> {
const baseUrl = process.env.SHOWPAD_BASE_URL || 'https://tdcerhverv.showpad.biz';
const username = process.env.SHOWPAD_USERNAME;
const password = process.env.SHOWPAD_PASSWORD;
const clientId = process.env.SHOWPAD_CLIENT_ID;
const clientSecret = process.env.SHOWPAD_CLIENT_SECRET;
if (!username || !password) {
console.error('❌ Missing SHOWPAD_USERNAME or SHOWPAD_PASSWORD');
return null;
}
if (!clientId || !clientSecret) {
console.error('❌ Missing SHOWPAD_CLIENT_ID or SHOWPAD_CLIENT_SECRET');
console.error('');
console.error('πŸ“‹ To get OAuth credentials:');
console.error(' 1. Go to https://tdcerhverv.showpad.biz');
console.error(' 2. Navigate to Admin > Settings > API');
console.error(' 3. Click "Manage OAuth Clients"');
console.error(' 4. Create a new OAuth client');
console.error(' 5. Copy the Client ID and Secret to your .env file');
return null;
}
console.log('Attempting Showpad authentication...');
const tokenUrl = `${baseUrl}/api/v3/oauth2/token`;
const params = new URLSearchParams({
grant_type: 'password',
username,
password,
client_id: clientId,
client_secret: clientSecret
});
try {
const response = await fetch(tokenUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: params.toString()
});
console.log(`Auth Response: ${response.status} ${response.statusText}`);
if (!response.ok) {
const error = await response.text();
console.error('❌ Auth failed:', error);
return null;
}
const data: ShowpadAuthResponse = await response.json();
console.log('βœ… Authentication successful!');
console.log(` Token type: ${data.token_type}`);
console.log(` Expires in: ${data.expires_in}s`);
return data.access_token;
} catch (error) {
console.error('❌ Auth error:', error);
return null;
}
}
async function testFetchAssets(token: string): Promise<void> {
const subdomain = process.env.SHOWPAD_SUBDOMAIN || 'tdcerhverv';
const apiUrl = `https://${subdomain}.api.showpad.com/v4/assets?limit=10`;
console.log('\nFetching assets...');
console.log(`API URL: ${apiUrl}`);
try {
const response = await fetch(apiUrl, {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
'Accept': 'application/json'
}
});
console.log(`Assets Response: ${response.status} ${response.statusText}`);
if (!response.ok) {
const error = await response.text();
console.error('❌ Fetch failed:', error);
return;
}
const data = await response.json();
const items = data.items || [];
console.log(`βœ… Fetched ${items.length} assets`);
// Count images
const imageTypes = ['image/png', 'image/jpeg', 'image/gif', 'image/webp', 'image/svg+xml'];
const imageExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg'];
let imageCount = 0;
for (const asset of items) {
const isImage =
(asset.mimeType && imageTypes.includes(asset.mimeType)) ||
(asset.name && imageExtensions.some((ext: string) => asset.name.toLowerCase().endsWith(ext))) ||
asset.resourcetype === 'image';
if (isImage) imageCount++;
console.log(` - ${asset.name} (${asset.mimeType || asset.resourcetype || 'unknown'})`);
}
console.log(`\nπŸ“Š Summary: ${imageCount} images out of ${items.length} assets`);
} catch (error) {
console.error('❌ Fetch error:', error);
}
}
async function main() {
const token = await testShowpadAuth();
if (token) {
await testFetchAssets(token);
}
console.log('\nTest complete.');
}
main().catch(console.error);