module ap.util; import std.format; import std.json; import requests; import slf4d; import singletons; import net.request_pool; import webfinger; import ap.errors; import ap.actor; import ap.activity_stream; enum { ActivityJson = "application/activity+json", ActivityJsonLd = `application/ld+json; profile="https://www.w3.org/ns/activitystreams"`, } /++ + Fetches remote actor based on WebFinger link + Params: + wf = WebFinger link to user + Returns: User Actor JSON representation +/ JSONValue apFetchRemoteUser(JSONValue wf) { PRequest rq = PRequest(); rq.url = wf["href"].str; rq.headers["Accept"] = wf["type"].str; Response rs = Rp.request(rq, true); return parseJSON(cast(string) rs.responseBody); } /++ + Fetches remote ActivityStream object by its id + Params: + id = the id of ActivityStream object + Returns: ActivityStream object +/ ASObject apFetchASObject(string id, string contentType = ActivityJson) { PRequest rq = PRequest(); rq.url = id; rq.headers["Accept"] = contentType; Response rs = Rp.request(rq, true); return new ASObject(parseJSON(cast(string) rs.responseBody)); } /++ + Resolves remote user to Actor based on username handle + Params: + username = Account username + Returns: ActivityPub Actor +/ ASObject apResolveRemoteUsername(string username) { JSONValue resource = wfRequestAccount(username); JSONValue accountLink; foreach (link; resource["links"].array) if ( link["type"].str == ActivityJsonLd || link["type"].str == ActivityJson ) { accountLink = link; break; } if (accountLink == JSONValue()) throw new Exception("No valid activity streams href found for " ~ username); string id = accountLink["href"].str; string contentType = accountLink["type"].str; // return new Actor(apFetchASObject(id, contentType)); return apFetchASObject(id, contentType); }