@@ -25,6 +25,7 @@ import (
2525
2626 "github.com/NdoleStudio/httpsms/pkg/discord"
2727
28+ "cloud.google.com/go/storage"
2829 mexporter "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric"
2930 cloudtrace "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace"
3031 "github.com/NdoleStudio/httpsms/pkg/cache"
@@ -80,13 +81,14 @@ import (
8081
8182// Container is used to resolve services at runtime
8283type Container struct {
83- projectID string
84- db * gorm.DB
85- dedicatedDB * gorm.DB
86- version string
87- app * fiber.App
88- eventDispatcher * services.EventDispatcher
89- logger telemetry.Logger
84+ projectID string
85+ db * gorm.DB
86+ dedicatedDB * gorm.DB
87+ version string
88+ app * fiber.App
89+ eventDispatcher * services.EventDispatcher
90+ logger telemetry.Logger
91+ attachmentRepository repositories.AttachmentRepository
9092}
9193
9294// NewLiteContainer creates a Container without any routes or listeners
@@ -118,6 +120,7 @@ func NewContainer(projectID string, version string) (container *Container) {
118120
119121 container .RegisterMessageListeners ()
120122 container .RegisterMessageRoutes ()
123+ container .RegisterAttachmentRoutes ()
121124 container .RegisterBulkMessageRoutes ()
122125
123126 container .RegisterMessageThreadRoutes ()
@@ -395,7 +398,7 @@ ALTER TABLE discords ADD CONSTRAINT IF NOT EXISTS uni_discords_server_id CHECK (
395398// FirebaseApp creates a new instance of firebase.App
396399func (container * Container ) FirebaseApp () (app * firebase.App ) {
397400 container .logger .Debug (fmt .Sprintf ("creating %T" , app ))
398- app , err := firebase .NewApp (context .Background (), nil , option .WithCredentialsJSON ( container .FirebaseCredentials ()))
401+ app , err := firebase .NewApp (context .Background (), nil , option .WithAuthCredentialsJSON ( option . ServiceAccount , container .FirebaseCredentials ()))
399402 if err != nil {
400403 msg := "cannot initialize firebase application"
401404 container .logger .Fatal (stacktrace .Propagate (err , msg ))
@@ -1430,9 +1433,63 @@ func (container *Container) MessageService() (service *services.MessageService)
14301433 container .MessageRepository (),
14311434 container .EventDispatcher (),
14321435 container .PhoneService (),
1436+ container .AttachmentRepository (),
1437+ container .APIBaseURL (),
14331438 )
14341439}
14351440
1441+ // AttachmentRepository creates a cached AttachmentRepository based on configuration
1442+ func (container * Container ) AttachmentRepository () repositories.AttachmentRepository {
1443+ if container .attachmentRepository != nil {
1444+ return container .attachmentRepository
1445+ }
1446+
1447+ bucket := os .Getenv ("GCS_BUCKET_NAME" )
1448+ if bucket != "" {
1449+ container .logger .Debug ("creating GoogleCloudStorageAttachmentRepository" )
1450+ client , err := storage .NewClient (context .Background (), option .WithAuthCredentialsJSON (option .ServiceAccount , container .FirebaseCredentials ()))
1451+ if err != nil {
1452+ container .logger .Fatal (stacktrace .Propagate (err , "cannot create GCS client" ))
1453+ }
1454+ container .attachmentRepository = repositories .NewGoogleCloudStorageAttachmentRepository (
1455+ container .Logger (),
1456+ container .Tracer (),
1457+ client ,
1458+ bucket ,
1459+ )
1460+ } else {
1461+ container .logger .Debug ("creating MemoryAttachmentRepository (GCS_BUCKET_NAME not set)" )
1462+ container .attachmentRepository = repositories .NewMemoryAttachmentRepository (
1463+ container .Logger (),
1464+ container .Tracer (),
1465+ )
1466+ }
1467+
1468+ return container .attachmentRepository
1469+ }
1470+
1471+ // APIBaseURL returns the API base URL derived from EVENTS_QUEUE_ENDPOINT
1472+ func (container * Container ) APIBaseURL () string {
1473+ endpoint := os .Getenv ("EVENTS_QUEUE_ENDPOINT" )
1474+ return strings .TrimSuffix (endpoint , "/v1/events" )
1475+ }
1476+
1477+ // AttachmentHandler creates a new AttachmentHandler
1478+ func (container * Container ) AttachmentHandler () (handler * handlers.AttachmentHandler ) {
1479+ container .logger .Debug (fmt .Sprintf ("creating %T" , handler ))
1480+ return handlers .NewAttachmentHandler (
1481+ container .Logger (),
1482+ container .Tracer (),
1483+ container .AttachmentRepository (),
1484+ )
1485+ }
1486+
1487+ // RegisterAttachmentRoutes registers routes for the /attachments prefix
1488+ func (container * Container ) RegisterAttachmentRoutes () {
1489+ container .logger .Debug (fmt .Sprintf ("registering %T routes" , & handlers.AttachmentHandler {}))
1490+ container .AttachmentHandler ().RegisterRoutes (container .App ())
1491+ }
1492+
14361493// PhoneAPIKeyService creates a new instance of services.PhoneAPIKeyService
14371494func (container * Container ) PhoneAPIKeyService () (service * services.PhoneAPIKeyService ) {
14381495 container .logger .Debug (fmt .Sprintf ("creating %T" , service ))
0 commit comments