2025-01-03 04:47:07 -05:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"git.simponic.xyz/simponic/phoneof/adapters/messaging"
|
|
|
|
"git.simponic.xyz/simponic/phoneof/api/chat"
|
|
|
|
"git.simponic.xyz/simponic/phoneof/api/template"
|
|
|
|
"git.simponic.xyz/simponic/phoneof/api/types"
|
|
|
|
"git.simponic.xyz/simponic/phoneof/args"
|
|
|
|
"git.simponic.xyz/simponic/phoneof/utils"
|
|
|
|
)
|
|
|
|
|
|
|
|
func LogRequestContinuation(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain {
|
|
|
|
return func(success types.Continuation, _failure types.Continuation) types.ContinuationChain {
|
|
|
|
context.Start = time.Now().UTC()
|
|
|
|
context.Id = utils.RandomId()
|
|
|
|
|
|
|
|
log.Println(req.Method, req.URL.Path, req.RemoteAddr, context.Id)
|
|
|
|
return success(context, req, resp)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func LogExecutionTimeContinuation(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain {
|
|
|
|
return func(success types.Continuation, _failure types.Continuation) types.ContinuationChain {
|
|
|
|
end := time.Now().UTC()
|
|
|
|
log.Println(context.Id, "took", end.Sub(context.Start))
|
|
|
|
|
|
|
|
return success(context, req, resp)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func HealthCheckContinuation(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain {
|
|
|
|
return func(success types.Continuation, _failure types.Continuation) types.ContinuationChain {
|
|
|
|
resp.WriteHeader(200)
|
|
|
|
resp.Write([]byte("healthy"))
|
|
|
|
return success(context, req, resp)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func FailurePassingContinuation(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain {
|
|
|
|
return func(_success types.Continuation, failure types.Continuation) types.ContinuationChain {
|
|
|
|
return failure(context, req, resp)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func IdContinuation(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain {
|
|
|
|
return func(success types.Continuation, _failure types.Continuation) types.ContinuationChain {
|
|
|
|
return success(context, req, resp)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func CacheControlMiddleware(next http.Handler, maxAge int) http.Handler {
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
header := fmt.Sprintf("public, max-age=%d", maxAge)
|
|
|
|
w.Header().Set("Cache-Control", header)
|
|
|
|
next.ServeHTTP(w, r)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func MakeMux(argv *args.Arguments, dbConn *sql.DB) *http.ServeMux {
|
|
|
|
mux := http.NewServeMux()
|
|
|
|
|
|
|
|
staticFileServer := http.FileServer(http.Dir(argv.StaticPath))
|
|
|
|
mux.Handle("GET /static/", http.StripPrefix("/static/", CacheControlMiddleware(staticFileServer, 3600)))
|
|
|
|
|
|
|
|
makeRequestContext := func() *types.RequestContext {
|
|
|
|
return &types.RequestContext{
|
|
|
|
DBConn: dbConn,
|
|
|
|
Args: argv,
|
|
|
|
TemplateData: &map[string]interface{}{},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mux.HandleFunc("GET /health", func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
requestContext := makeRequestContext()
|
|
|
|
LogRequestContinuation(requestContext, r, w)(HealthCheckContinuation, FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
|
|
})
|
|
|
|
|
|
|
|
mux.HandleFunc("GET /", func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
requestContext := makeRequestContext()
|
|
|
|
|
|
|
|
templateFile := "home.html"
|
|
|
|
LogRequestContinuation(requestContext, r, w)(template.TemplateContinuation(templateFile, true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
|
|
})
|
|
|
|
|
2025-01-03 04:50:07 -05:00
|
|
|
mux.HandleFunc("POST /chat/me", func(w http.ResponseWriter, r *http.Request) {
|
2025-01-03 04:47:07 -05:00
|
|
|
requestContext := makeRequestContext()
|
|
|
|
LogRequestContinuation(requestContext, r, w)(chat.ValidateFren, FailurePassingContinuation)(template.TemplateContinuation("chat.html", true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
|
|
})
|
|
|
|
|
|
|
|
mux.HandleFunc("GET /chat/messages", func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
requestContext := makeRequestContext()
|
|
|
|
LogRequestContinuation(requestContext, r, w)(chat.ValidateFren, FailurePassingContinuation)(chat.FetchMessagesContinuation, FailurePassingContinuation)(template.TemplateContinuation("messages.html", false), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
|
|
})
|
|
|
|
|
2025-01-05 18:16:26 -05:00
|
|
|
httpsms := messaging.HttpSmsContinuation(os.Getenv("HTTPSMS_API_TOKEN"), os.Getenv("FROM_PHONE_NUMBER"), os.Getenv("TO_PHONE_NUMBER"), argv.HttpSmsEndpoint)
|
2025-01-05 19:23:56 -05:00
|
|
|
ntfy := messaging.SendNtfy(argv.NtfyEndpoint)
|
2025-01-05 18:16:26 -05:00
|
|
|
sendMessageContinuation := chat.SendMessageContinuation(messaging.Compose(ntfy, httpsms))
|
2025-01-03 04:47:07 -05:00
|
|
|
mux.HandleFunc("POST /chat", func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
requestContext := makeRequestContext()
|
|
|
|
LogRequestContinuation(requestContext, r, w)(chat.ValidateFren, FailurePassingContinuation)(sendMessageContinuation, FailurePassingContinuation)(template.TemplateContinuation("chat.html", true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
|
|
})
|
|
|
|
|
2025-01-05 18:16:26 -05:00
|
|
|
smsEventProcessor := chat.ChatEventProcessorContinuation(os.Getenv("TO_PHONE_NUMBER"), os.Getenv("HTTPSMS_SIGNING_KEY"), ntfy)
|
2025-01-03 04:47:07 -05:00
|
|
|
mux.HandleFunc("POST /chat/event", func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
requestContext := makeRequestContext()
|
|
|
|
LogRequestContinuation(requestContext, r, w)(smsEventProcessor, FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
|
|
|
|
})
|
|
|
|
|
|
|
|
return mux
|
|
|
|
}
|