Spaces:
Paused
Paused
| /** | |
| * 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); | |