lightningtipbot/internal/lnbits/webhook/webhook.go
calle 0631fd53eb
WIP: Satdress (#331)
* satdress rebase

* check config

* satdress rebase

* check config

* check for invoices

* return error

* Update inline photo v5 (#332)

* update url

* round logo

* resize

Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com>

* new logo (#333)

Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com>

* help (#334)

Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com>

* add file (#335)

Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com>

* markdown (#336)

Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com>

* satdress rebase

* check config

* satdress rebase

* check for invoices

* return error

* satdress works

* add lnbits

* timeout

* error checking

* small lnd

* errors

* button fix

Co-authored-by: LightningTipBot <88730856+LightningTipBot@users.noreply.github.com>
2022-04-29 14:28:12 +02:00

126 lines
3.7 KiB
Go

package webhook
import (
"encoding/json"
"fmt"
"time"
"github.com/LightningTipBot/LightningTipBot/internal"
"github.com/LightningTipBot/LightningTipBot/internal/lnbits"
"github.com/LightningTipBot/LightningTipBot/internal/telegram"
log "github.com/sirupsen/logrus"
"gorm.io/gorm"
"net/http"
"github.com/LightningTipBot/LightningTipBot/internal/storage"
"github.com/gorilla/mux"
tb "gopkg.in/lightningtipbot/telebot.v3"
"github.com/LightningTipBot/LightningTipBot/internal/i18n"
)
type Server struct {
httpServer *http.Server
bot *tb.Bot
c *lnbits.Client
database *gorm.DB
buntdb *storage.DB
}
type Webhook struct {
CheckingID string `json:"checking_id"`
Pending bool `json:"pending"`
Amount int64 `json:"amount"`
Fee int64 `json:"fee"`
Memo string `json:"memo"`
Time int64 `json:"time"`
Bolt11 string `json:"bolt11"`
Preimage string `json:"preimage"`
PaymentHash string `json:"payment_hash"`
Extra struct{} `json:"extra"`
WalletID string `json:"wallet_id"`
Webhook string `json:"webhook"`
WebhookStatus interface{} `json:"webhook_status"`
}
func NewServer(bot *telegram.TipBot) *Server {
srv := &http.Server{
Addr: internal.Configuration.Lnbits.WebhookServerUrl.Host,
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
apiServer := &Server{
c: bot.Client,
database: bot.DB.Users,
bot: bot.Telegram,
httpServer: srv,
buntdb: bot.Bunt,
}
apiServer.httpServer.Handler = apiServer.newRouter()
go apiServer.httpServer.ListenAndServe()
log.Infof("[Webhook] Server started at %s", internal.Configuration.Lnbits.WebhookServerUrl)
return apiServer
}
func (w *Server) GetUserByWalletId(walletId string) (*lnbits.User, error) {
user := &lnbits.User{}
tx := w.database.Where("wallet_id = ?", walletId).First(user)
if tx.Error != nil {
return user, tx.Error
}
return user, nil
}
func (w *Server) newRouter() *mux.Router {
router := mux.NewRouter()
router.HandleFunc("/", w.receive).Methods(http.MethodPost)
return router
}
func (w *Server) receive(writer http.ResponseWriter, request *http.Request) {
log.Debugln("[Webhook] Received request")
webhookEvent := Webhook{}
// need to delete the header otherwise the Decode will fail
request.Header.Del("content-length")
err := json.NewDecoder(request.Body).Decode(&webhookEvent)
if err != nil {
log.Errorf("[Webhook] Error decoding request: %s", err.Error())
writer.WriteHeader(400)
return
}
user, err := w.GetUserByWalletId(webhookEvent.WalletID)
if err != nil {
log.Errorf("[Webhook] Error getting user: %s", err.Error())
writer.WriteHeader(400)
return
}
log.Infoln(fmt.Sprintf("[⚡️ WebHook] User %s (%d) received invoice of %d sat.", telegram.GetUserStr(user.Telegram), user.Telegram.ID, webhookEvent.Amount/1000))
writer.WriteHeader(200)
// trigger invoice events
txInvoiceEvent := &telegram.InvoiceEvent{Invoice: &telegram.Invoice{PaymentHash: webhookEvent.PaymentHash}}
err = w.buntdb.Get(txInvoiceEvent)
if err != nil {
log.Errorln(err)
} else {
// do something with the event
if c := telegram.InvoiceCallback[txInvoiceEvent.Callback]; c.Function != nil {
if err := telegram.AssertEventType(txInvoiceEvent, c.Type); err != nil {
log.Errorln(err)
return
}
c.Function(txInvoiceEvent)
return
}
}
// fallback: send a message to the user if there is no callback for this invoice
_, err = w.bot.Send(user.Telegram, fmt.Sprintf(i18n.Translate(user.Telegram.LanguageCode, "invoiceReceivedMessage"), webhookEvent.Amount/1000))
if err != nil {
log.Errorln(err)
}
}