try{requireSameOrigin(request);constuser=awaitrequireUser();constform=awaitrequest.formData();constraw=String(form.get("feedUrl")||"").trim();consturl=newURL(raw);if(url.protocol!=="https:")thrownewError("RSS feed must use HTTPS");constitems=awaitfetchRss(url.toString());if(!items.length)thrownewError("RSS feed has no items");
constexisting=db.prepare("SELECT id FROM sources WHERE user_id=? AND rss_feed_url=?").get(user.id,url.toString())as{id: number}|undefined;
constname=`RSS · ${url.hostname}`;constout=db.prepare("INSERT INTO sources(user_id,name,base_url,token_encrypted,integration_type,rss_feed_url,sync_status) VALUES(?,?,?,?, 'rss',?, 'queued')").run(user.id,name,url.origin,encrypt("rss-read-only"),url.toString());constid=Number(out.lastInsertRowid);
db.prepare("INSERT INTO source_members(source_id,user_id,role) VALUES(?,?,'owner')").run(id,user.id);queuePull(id,"source-created");returnNextResponse.redirect(externalUrl(request,"/dashboard?source=rss-connected"));
constsourceRows=db.prepare("SELECT s.id,s.name,s.base_url,s.sync_status,s.last_synced_at,s.last_error,s.webhook_secret_hash,s.last_webhook_at,s.user_id AS owner_id,s.is_enabled,s.disabled_at,s.sync_tags_json,s.sync_from,s.sync_to,s.sync_attachment_mode,s.attachment_storage_mode,s.attachment_cache_limit_bytes,s.attachment_cache_error,s.remote_display_name,s.remote_avatar_url,s.last_connection_at,s.last_connection_error FROM sources s JOIN source_members sm ON sm.source_id=s.id WHERE sm.user_id=? ORDER BY s.id DESC").all(user.id)asSource[];
constsourceRows=db.prepare("SELECT s.id,s.name,s.base_url,s.integration_type,s.rss_feed_url,s.sync_status,s.last_synced_at,s.last_error,s.webhook_secret_hash,s.last_webhook_at,s.user_id AS owner_id,s.is_enabled,s.disabled_at,s.sync_tags_json,s.sync_from,s.sync_to,s.sync_attachment_mode,s.attachment_storage_mode,s.attachment_cache_limit_bytes,s.attachment_cache_error,s.remote_display_name,s.remote_avatar_url,s.last_connection_at,s.last_connection_error FROM sources s JOIN source_members sm ON sm.source_id=s.id WHERE sm.user_id=? ORDER BY s.id DESC").all(user.id)asSource[];
constsources=sourceRows.map((source)=>({...source,syncTags:(()=>{try{returnJSON.parse(source.sync_tags_json)asstring[];}catch{return[];}})(),members: db.prepare("SELECT u.username,u.id,sm.role FROM source_members sm JOIN users u ON u.id=sm.user_id WHERE sm.source_id=? ORDER BY sm.role DESC,u.username").all(source.id)as{username: string;id: number;role: string}[],jobs: db.prepare("SELECT id,kind,trigger,status,attempts,last_error,created_at,finished_at FROM sync_jobs WHERE source_id=? ORDER BY id DESC LIMIT 5").all(source.id)asJob[]}));
constsources=sourceRows.map((source)=>({...source,syncTags:(()=>{try{returnJSON.parse(source.sync_tags_json)asstring[];}catch{return[];}})(),members: db.prepare("SELECT u.username,u.id,sm.role FROM source_members sm JOIN users u ON u.id=sm.user_id WHERE sm.source_id=? ORDER BY sm.role DESC,u.username").all(source.id)as{username: string;id: number;role: string}[],jobs: db.prepare("SELECT id,kind,trigger,status,attempts,last_error,created_at,finished_at FROM sync_jobs WHERE source_id=? ORDER BY id DESC LIMIT 5").all(source.id)asJob[]}));
if(source.integration_type==="rss"){constitems=awaitfetchRss(source.rss_feed_url||"");for(constitemofitems)db.prepare("INSERT INTO posts(source_id,author_id,remote_memo_name,content,visibility,tags_json,attachments_json,origin,remote_created_at,remote_updated_at,sync_status,hidden,remote_url) VALUES(?,?,?,?,?,'[]','[]','rss',?,?, 'synced',0,?) ON CONFLICT(source_id,remote_memo_name) DO UPDATE SET content=excluded.content,remote_created_at=excluded.remote_created_at,remote_url=excluded.remote_url,hidden=0,updated_at=CURRENT_TIMESTAMP").run(source.id,source.user_id,`rss:${item.id}`,item.content,"PUBLIC",item.publishedAt,item.publishedAt,item.link);constnames=items.map((item)=>`rss:${item.id}`);if(names.length)db.prepare(`UPDATE posts SET hidden=1 WHERE source_id=? AND remote_memo_name NOT IN (${names.map(()=>"?").join(",")})`).run(source.id,...names);db.prepare("UPDATE sources SET sync_status='synced',last_synced_at=CURRENT_TIMESTAMP,last_error=NULL WHERE id=?").run(source.id);return;}
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.