Skip to content

Instantly share code, notes, and snippets.

@brbarmex
Created October 1, 2025 17:38
Show Gist options
  • Select an option

  • Save brbarmex/addb675434b760ccb4ec178a86461320 to your computer and use it in GitHub Desktop.

Select an option

Save brbarmex/addb675434b760ccb4ec178a86461320 to your computer and use it in GitHub Desktop.
servicebus
package main
import (
"context"
"encoding/base64"
"encoding/json"
"log"
"net/http"
"os"
"time"
"github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus"
"github.com/gin-gonic/gin"
)
type Token struct {
Queue string `json:"q"`
SessionID string `json:"s"`
LockToken string `json:"l"`
}
func main() {
connStr := os.Getenv("SERVICEBUS_CONNECTION_STRING")
queue := os.Getenv("SERVICEBUS_QUEUE")
client, _ := azservicebus.NewClientFromConnectionString(connStr, nil)
defer client.Close(context.Background())
r := gin.Default()
// Pull: pega 1 msg e devolve body + token
r.GET("/pull", func(c *gin.Context) {
sessionID := c.Query("sessionId")
ctx, cancel := context.WithTimeout(c, 10*time.Second)
defer cancel()
sr, err := client.AcceptSessionForQueue(ctx, queue, sessionID, nil)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
defer sr.Close(context.Background())
msgs, err := sr.ReceiveMessages(ctx, 1, nil)
if err != nil || len(msgs) == 0 {
c.JSON(200, gin.H{"messages": []string{}})
return
}
m := msgs[0]
lockToken := base64.RawURLEncoding.EncodeToString(m.LockToken[:])
tokenObj := Token{Queue: queue, SessionID: sessionID, LockToken: lockToken}
tokenBytes, _ := json.Marshal(tokenObj)
token := base64.RawURLEncoding.EncodeToString(tokenBytes)
c.JSON(200, gin.H{
"body": string(m.Body),
"token": token,
"note": "Esse token deve ser usado no /complete dentro do tempo do lock (~30s-5min)",
})
})
// Complete: recebe token e completa msg
r.POST("/complete", func(c *gin.Context) {
var req struct{ Token string `json:"token"` }
if err := c.BindJSON(&req); err != nil {
c.JSON(400, gin.H{"error": "envie {token}"})
return
}
decoded, _ := base64.RawURLEncoding.DecodeString(req.Token)
var t Token
_ = json.Unmarshal(decoded, &t)
ctx, cancel := context.WithTimeout(c, 15*time.Second)
defer cancel()
sr, err := client.AcceptSessionForQueue(ctx, t.Queue, t.SessionID, nil)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
defer sr.Close(context.Background())
lockBytes, _ := base64.RawURLEncoding.DecodeString(t.LockToken)
var lt [16]byte
copy(lt[:], lockBytes)
// cria um ReceivedMessage mínimo só com o LockToken
msg := &azservicebus.ReceivedMessage{LockToken: lt}
if err := sr.CompleteMessage(ctx, msg, nil); err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
c.JSON(200, gin.H{"status": "completed"})
})
log.Println("listening :8080")
r.Run(":8080")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment