import { idsFromValue } from "./activitypub" import * as db from "./db" import outbox from "./outbox" import { send } from "./request" import ACTOR from "../actor" export default async function inbox(activity:any) { const date = new Date() // get the main recipients ([...new Set()] is to dedupe) const recipientList = [...new Set([...idsFromValue(activity.to), ...idsFromValue(activity.cc), ...idsFromValue(activity.audience)])] // if my list of followers in the list of recipients, then forward to them as well if(recipientList.includes(ACTOR.url + "/followers")) { (await db.listFollowers()).forEach(f => send(f, activity, activity.attributedTo)) } // save this activity to my inbox const id = `${date.getTime().toString(16)}` db.createInboxActivity(activity, id) // TODO: process the activity and update local data switch(activity.type) { case "Follow": follow(activity, id); break; case "Accept": accept(activity); break; case "Reject": reject(activity); break; case "Undo": undo(activity); break; } return new Response("", { status: 204 }) } const follow = async (activity:any, id:string) => { // someone is following me // save this follower locally db.createFollower(activity.actor, id) // send an accept message to the outbox await outbox({ "@context": "https://www.w3.org/ns/activitystreams", type: "Accept", actor: ACTOR.id, to: [activity.actor], object: activity, }); } const undo = async (activity:any) => { switch (activity.object.type) { // someone is undoing their follow of me case "Follow": await db.deleteFollower(activity.actor); break } } const accept = async (activity:any) => { switch (activity.object.type) { // someone accepted my follow of them case "Follow": await db.acceptFollowing(activity.actor); break } } const reject = async (activity:any) => { switch (activity.object.type) { // someone rejected my follow of them case "Follow": await db.deleteFollowing(activity.actor); break } }