diff --git a/README.md b/README.md index ab16992..c7d2e95 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Use agents instead if you need: This extension showcases the skillset approach by providing three simple endpoints that generate random development data: - Random commit messages -- Lorem ipsum text generation +- URL shortener - Random user data ## Getting Started @@ -72,22 +72,19 @@ URL: https:///random-commit-message Parameters: { "type": "object" } Return type: String --- -Name: random_lorem_ipsum -Inference description: Generates a random Lorem Ipsum text. Responses should have html tags present. -URL: https:///random-lorem-ipsum +Name: shorten_url +Inference description: Shortens a long URL using the CleanURI service. Send a JSON body with the "url" field and receive the shortened URL in the response. +URL: https:///shorten-url Parameters: { - "type": "object", - "properties": { - "number_of_paragraphs": { - "type": "number", - "description": "The number of paragraphs to be generated. Must be between 1 and 10 inclusive" - }, - "paragraph_length": { - "type": "string", - "description": "The length of each paragraph. Must be one of \"short\", \"medium\", \"long\", or \"verylong\"" - } - } + "type": "object", + "properties": { + "url": { + "type": "string", + "description": "The long URL to be shortened." + } + }, + "required": ["url"] } Return type: String --- @@ -111,8 +108,7 @@ Return type: String Here's some example things: * `@skillset-example please create a random commit message` -* `@skillset-example generate a lorem ipsum` -* `@skillset-example generate a short lorem ipsum with 3 paragraphs` +* `@skillset-example please short this url https://github.com` * `@skillset-example generate random user data` ## Implementation @@ -120,7 +116,7 @@ Here's some example things: This bot provides a passthrough to a couple of other APIs: * For commit messages, https://whatthecommit.com/ -* For Lorem Ipsum, https://loripsum.net/ +* For shorting URLs, https://cleanuri.com/ * For user data, https://randomuser.me/ ## Documentation diff --git a/handlers/loripsum.go b/handlers/loripsum.go deleted file mode 100644 index f4ba7ce..0000000 --- a/handlers/loripsum.go +++ /dev/null @@ -1,116 +0,0 @@ -package handlers - -import ( - "encoding/json" - "fmt" - "io" - "net/http" - "net/url" - "path" -) - -func Loripsum(w http.ResponseWriter, r *http.Request) { - fmt.Println("Loripsum Called") - - params := &struct { - NumberOfParagraphs int `json:"number_of_paragraphs"` - ParagraphLength string `json:"paragraph_length"` - Decorate bool `json:"decorate"` - Link bool `json:"link"` - UnorderedLists bool `json:"unordered_lists"` - NumberedLists bool `json:"numbered_lists"` - DescriptionLists bool `json:"description_lists"` - BlockQuotes bool `json:"blockquotes"` - Code bool `json:"code"` - Headers bool `json:"headers"` - AllCaps bool `json:"all_caps"` - Prude bool `json:"prude"` - }{} - - err := json.NewDecoder(r.Body).Decode(¶ms) - if err != nil { - w.WriteHeader(http.StatusBadRequest) - return - } - - p := "api" - if params.NumberOfParagraphs != 0 { - if params.NumberOfParagraphs < 0 { - p = path.Join(p, "1") - } else if params.NumberOfParagraphs > 10 { - p = path.Join(p, "10") - } else { - p = path.Join(p, fmt.Sprintf("%v", params.NumberOfParagraphs)) - } - } - - if params.ParagraphLength == "short" || params.ParagraphLength == "medium" || params.ParagraphLength == "long" || params.ParagraphLength == "verylong" { - p = path.Join(p, params.ParagraphLength) - } - - if params.Decorate { - p = path.Join(p, "decorate") - } - - if params.Link { - p = path.Join(p, "link") - } - - if params.UnorderedLists { - p = path.Join(p, "ul") - } - - if params.NumberedLists { - p = path.Join(p, "ol") - } - - if params.DescriptionLists { - p = path.Join(p, "dl") - } - - if params.BlockQuotes { - p = path.Join(p, "bq") - } - - if params.Code { - p = path.Join(p, "code") - } - - if params.Headers { - p = path.Join(p, "headers") - } - - if params.AllCaps { - p = path.Join(p, "allcaps") - } - - if params.Prude { - p = path.Join(p, "prude") - } - - u, _ := url.Parse("https://loripsum.net") - u.Path = p - - req, err := http.NewRequestWithContext(r.Context(), http.MethodGet, u.String(), nil) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return - } - - resp, err := (&http.Client{}).Do(req) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - w.WriteHeader(http.StatusInternalServerError) - return - } - - if _, err := io.Copy(w, resp.Body); err != nil { - fmt.Println("Something unrecoverable went wrong") - return - } -} diff --git a/handlers/shorten_url.go b/handlers/shorten_url.go new file mode 100644 index 0000000..8da57fb --- /dev/null +++ b/handlers/shorten_url.go @@ -0,0 +1,60 @@ +package handlers + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" +) + +// CleanURI API for shortening URLs +// https://cleanuri.com/docs + +// Structure to receive the JSON request with the URL to shorten +type ShortenRequest struct { + URL string `json:"url"` +} + +// HTTP handler to shorten URLs using the CleanURI API +func ShortenURL(w http.ResponseWriter, r *http.Request) { + fmt.Println("ShortenURL Called") // Log to know the handler was called + + // Decode the request body expecting a JSON with the "url" field + var reqData ShortenRequest + if err := json.NewDecoder(r.Body).Decode(&reqData); err != nil { + http.Error(w, "Invalid JSON", http.StatusBadRequest) + return + } + fmt.Printf("URL to shorten: %s\n", reqData.URL) // Log the received URL + + // Prepare the form body for the request to CleanURI + form := []byte("url=" + reqData.URL) + // Create the HTTP POST request to the CleanURI API + req, err := http.NewRequestWithContext(r.Context(), http.MethodPost, "https://cleanuri.com/api/v1/shorten", bytes.NewBuffer(form)) + if err != nil { + http.Error(w, "Failed to create request", http.StatusInternalServerError) + return + } + // Set the header to indicate the body is a form + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + + // Make the request to CleanURI + resp, err := http.DefaultClient.Do(req) + if err != nil { + http.Error(w, "Failed to contact CleanURI", http.StatusInternalServerError) + return + } + defer resp.Body.Close() + + // If CleanURI responds with a code other than 200 OK, return the error + if resp.StatusCode != http.StatusOK { + body, _ := io.ReadAll(resp.Body) + http.Error(w, fmt.Sprintf("CleanURI error: %s", string(body)), http.StatusInternalServerError) + return + } + + // If everything goes well, copy CleanURI's response to the client + w.Header().Set("Content-Type", "application/json") + io.Copy(w, resp.Body) +} \ No newline at end of file diff --git a/main.go b/main.go index 80c60f8..b814d65 100644 --- a/main.go +++ b/main.go @@ -17,8 +17,8 @@ func main() { func run() error { http.HandleFunc("/random-commit-message", handlers.CommitMessage) - http.HandleFunc("/random-lorem-ipsum", handlers.Loripsum) http.HandleFunc("/random-user", handlers.User) + http.HandleFunc("/shorten-url", handlers.ShortenURL) http.HandleFunc("/_ping", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("OK")) })