205 lines
5.8 KiB
Go
205 lines
5.8 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/flosch/pongo2"
|
|
"github.com/gofiber/fiber/v2"
|
|
"github.com/stripe/stripe-go"
|
|
"github.com/stripe/stripe-go/customer"
|
|
)
|
|
|
|
func PricingTableHandler(c *fiber.Ctx) error {
|
|
return c.SendString(generatePricingTableChatHTML(c))
|
|
}
|
|
|
|
func generatePricingTableChatHTML(c *fiber.Ctx) string {
|
|
var result User
|
|
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, "SELECT global currentUser { stripe_id, email } LIMIT 1;", &result)
|
|
if err != nil {
|
|
fmt.Println("Error getting user")
|
|
panic(err)
|
|
}
|
|
|
|
clientSecretSession := CreateClientSecretSession(c)
|
|
|
|
stripeTable := `
|
|
<stripe-pricing-table
|
|
pricing-table-id="prctbl_1PJAxDP2nW0okNQyY0Q3mbg4"
|
|
publishable-key="pk_live_51OxXuWP2nW0okNQyme1qdwbL535jbMmM1uIUi6U5zcvEUUwKraktmpCzudXNdPSTxlHpw2FbCtxpwbyFFcasQ7aj000tJJGpWW"
|
|
customer-session-client-secret="` + clientSecretSession + `">
|
|
</stripe-pricing-table>`
|
|
|
|
closeBtn := `
|
|
<div class="is-flex is-justify-content-flex-end">
|
|
<a class="button is-small is-danger is-outlined" hx-get="/loadChat" hx-target="#chat-container" hx-swap="outerHTML"
|
|
hx-trigger="click">
|
|
<span class="icon">
|
|
<i class="fa-solid fa-xmark"></i>
|
|
</span>
|
|
</a>
|
|
</div>`
|
|
|
|
htmlString := "<div class='columns is-centered' id='chat-container'><div class='column is-12-mobile is-8-tablet is-6-desktop' id='chat-messages'>"
|
|
|
|
NextMessages := []TemplateMessage{}
|
|
nextMsg := TemplateMessage{
|
|
Icon: "icons/bouvai2.png", // Assuming Icon is a field you want to include from Message
|
|
Content: "<br>" + stripeTable + closeBtn,
|
|
Hidden: false, // Assuming Hidden is a field you want to include from Message
|
|
Id: "0",
|
|
Name: "JADE",
|
|
}
|
|
NextMessages = append(NextMessages, nextMsg)
|
|
|
|
botOut, err := botTmpl.Execute(pongo2.Context{"Messages": NextMessages, "ConversationAreaId": 0, "NotClickable": true, "notFlex": true, "DontShowName": true})
|
|
if err != nil {
|
|
fmt.Println("Error executing template")
|
|
panic(err)
|
|
}
|
|
htmlString += botOut
|
|
htmlString += "<div style='height: 10px;'></div>"
|
|
htmlString += "</div></div>"
|
|
|
|
// Render the HTML template with the messages
|
|
return htmlString
|
|
}
|
|
|
|
func CreateNewStripeCustomer(name string, email string) string {
|
|
params := &stripe.CustomerParams{
|
|
Name: stripe.String(name),
|
|
Email: stripe.String(email),
|
|
}
|
|
result, err := customer.New(params)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return result.ID
|
|
}
|
|
|
|
func IsCurrentUserSubscribed(c *fiber.Ctx) (bool, bool) {
|
|
var user User
|
|
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, "SELECT global currentUser { stripe_id } LIMIT 1;", &user)
|
|
if err != nil {
|
|
fmt.Println("Error getting user")
|
|
panic(err)
|
|
}
|
|
result, err := customer.Get(user.StripeID, nil)
|
|
if err != nil {
|
|
fmt.Println("Error getting customer")
|
|
panic(err)
|
|
}
|
|
if result.Subscriptions.TotalCount == 0 {
|
|
return false, false
|
|
}
|
|
|
|
// Check if an active product "prod_PnDjBBwvQN36cQ" is in the subscription. It is the premium plan
|
|
isPremium := false
|
|
for _, sub := range result.Subscriptions.Data {
|
|
if sub.Plan.Product.ID == "prod_Q9TpVos0t8QtX3" && sub.Plan.Active {
|
|
isPremium = true
|
|
break
|
|
}
|
|
}
|
|
|
|
isBasic := false
|
|
for _, sub := range result.Subscriptions.Data {
|
|
if sub.Plan.Product.ID == "prod_QDHakyHUeHLMET" && sub.Plan.Active {
|
|
isBasic = true
|
|
break
|
|
}
|
|
}
|
|
|
|
return isPremium, isBasic
|
|
}
|
|
|
|
func IsCurrentUserLimiteReached(c *fiber.Ctx, isBasic bool) bool {
|
|
// 30 days ago
|
|
date := time.Now().AddDate(0, 0, -30)
|
|
// Count the number of Usage for the current user
|
|
var count int64
|
|
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, `
|
|
WITH
|
|
U := (
|
|
SELECT Usage
|
|
FILTER .user = global currentUser AND .date >= <datetime>$0
|
|
)
|
|
SELECT count(U)
|
|
`, &count, date)
|
|
if err != nil {
|
|
fmt.Println("Error counting Usage")
|
|
panic(err)
|
|
}
|
|
// 500 if isBasic is false, otherwise 10000
|
|
if isBasic {
|
|
return count >= 4000
|
|
} else {
|
|
return count >= 200
|
|
}
|
|
}
|
|
|
|
func CreateClientSecretSession(c *fiber.Ctx) string {
|
|
var user User
|
|
err := edgeGlobalClient.WithGlobals(map[string]interface{}{"ext::auth::client_token": c.Cookies("jade-edgedb-auth-token")}).QuerySingle(edgeCtx, "SELECT global currentUser { stripe_id } LIMIT 1;", &user)
|
|
if err != nil {
|
|
fmt.Println("Error getting user")
|
|
panic(err)
|
|
}
|
|
|
|
url := "https://api.stripe.com/v1/customer_sessions"
|
|
method := "POST"
|
|
apiKey := stripe.Key
|
|
|
|
payload := []byte(fmt.Sprintf("customer=%s&components[pricing_table][enabled]=true", user.StripeID))
|
|
|
|
req, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
|
|
if err != nil {
|
|
fmt.Println("failed to create request")
|
|
panic(err)
|
|
}
|
|
req.Header.Add("Authorization", "Bearer "+apiKey)
|
|
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println("failed to execute request")
|
|
panic(err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
body, _ := io.ReadAll(resp.Body)
|
|
fmt.Println("failed to create customer session")
|
|
panic(fmt.Sprintf("failed to create customer session: %s", string(body)))
|
|
}
|
|
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
fmt.Println("failed to read response body")
|
|
panic(err)
|
|
}
|
|
|
|
type CustomerSessionResponse struct {
|
|
ClientSecret string `json:"client_secret"`
|
|
CustomerID string `json:"customer"`
|
|
}
|
|
|
|
var customerSession CustomerSessionResponse
|
|
if err := json.Unmarshal(body, &customerSession); err != nil {
|
|
fmt.Println("failed to unmarshal response")
|
|
panic(err)
|
|
}
|
|
|
|
if user.StripeID != customerSession.CustomerID {
|
|
panic("customer_id does not match")
|
|
}
|
|
|
|
return customerSession.ClientSecret
|
|
}
|