package main import ( "encoding/json" "github.com/gorilla/mux" "io/ioutil" "log" "net/http" "net/url" "regexp" "willnorris.com/go/webmention" ) func Serve() { webfingerHandler := func(w http.ResponseWriter, r *http.Request) { w.Header().Set("content-type", "application/jrd+json; charset=utf-8") name := r.URL.Query().Get("resource") // should be something like acct:user@example.com urlBaseUrl, _ := url.Parse(baseURL) re := regexp.MustCompile(`^acct:(.*)@` + regexp.QuoteMeta(urlBaseUrl.Host) + `$`) name = re.ReplaceAllString(name, "$1") actor := actors[name] // error out if this actor does not exist if actor == nil { w.WriteHeader(http.StatusNotFound) return } responseMap := make(map[string]interface{}) responseMap["subject"] = "acct:" + actor.Name + "@" + urlBaseUrl.Host // links is a json array with a single element var links [1]map[string]string link1 := make(map[string]string) link1["rel"] = "self" link1["type"] = ContentTypeAs2 link1["href"] = actor.iri links[0] = link1 responseMap["links"] = links response, _ := json.Marshal(responseMap) _, _ = w.Write(response) } inboxHandler := func(w http.ResponseWriter, r *http.Request) { b, err := ioutil.ReadAll(r.Body) if err != nil { panic(err) } activity := make(map[string]interface{}) err = json.Unmarshal(b, &activity) if err != nil { w.WriteHeader(http.StatusInternalServerError) return } if activity["type"] == "Follow" { actor := actors[mux.Vars(r)["actor"]] // error out if this actor does not exist if actor == nil { w.WriteHeader(http.StatusNotFound) return } actor.Accept(activity) } else if activity["type"] == "Undo" { // TODO: Implement unfollow } else if activity["type"] == "Create" { object, ok := activity["object"].(map[string]interface{}) if ok { inReplyTo, ok := object["inReplyTo"].(string) id, ok2 := object["id"].(string) if ok && ok2 && len(inReplyTo) > 0 && len(id) > 0 { webmentionClient := webmention.New(nil) endpoint, err := webmentionClient.DiscoverEndpoint(inReplyTo) if err != nil || len(endpoint) < 1 { return } _, err = webmentionClient.SendWebmention(endpoint, id, inReplyTo) if err != nil { log.Println("Sending webmention to " + inReplyTo + " failed") return } log.Println("Sent webmention to " + inReplyTo) } } } } // Add the handlers to a HTTP server gorilla := mux.NewRouter() gorilla.HandleFunc("/.well-known/webfinger", webfingerHandler) gorilla.HandleFunc("/{actor}/inbox", inboxHandler) gorilla.HandleFunc("/{actor}/inbox/", inboxHandler) http.Handle("/", gorilla) log.Fatal(http.ListenAndServe(":8081", nil)) }