diff --git a/service/controllers/pco_webhook.go b/service/controllers/pco_webhook.go index e4f96f9..7d82638 100644 --- a/service/controllers/pco_webhook.go +++ b/service/controllers/pco_webhook.go @@ -18,6 +18,7 @@ import ( "golang.org/x/oauth2" "google.golang.org/api/option" "google.golang.org/api/youtube/v3" + yt_helpers "git.preston-baxter.com/Preston_PLB/capstone/webhook-service/vendors/youtube" ) var ( @@ -152,7 +153,7 @@ func youtubeServiceForUser(userId primitive.ObjectID) (*youtube.Service, error) } } -func ScheduleLiveStreamFromWebhook(c *gin.Context, body *webhooks.EventDelivery) error { +func ScheduleBroadcastFromWebhook(c *gin.Context, body *webhooks.EventDelivery) error { //get uid from context. Lots of sanitizing just incase var uid primitive.ObjectID if raw, ok := c.Get("user_bson_id"); ok { @@ -163,19 +164,51 @@ func ScheduleLiveStreamFromWebhook(c *gin.Context, body *webhooks.EventDelivery) } } + //Load ytClient for user. It is fetched from cache or created ytClient, err := youtubeServiceForUser(uid) if err != nil { log.WithError(err).Error("Failed to initialize youtube client") return err } + //Load pcoClient for user. It is fetched from cache or created pcoClient, err := pcoServiceForUser(uid) if err != nil { log.WithError(err).Error("Failed to initialize youtube client") return err } - planUpdate := &services.Plan{} + //deserialize the payload + payload := &services.Plan{} + err = body.UnmarshallPayload(payload) + if err != nil { + log.WithError(err).Error("Failed to unmarshall body") + return err + } + + //create the broadcast + //TODO: handle update + //TODO: handle delete + switch body.Name { + case "services.v2.events.plan.created": + return scheduleNewBroadcastFromWebhook(c, payload, ytClient, pcoClient) + default: + return fmt.Errorf("Unkown event error: %s", body.Name) + } +} + +func scheduleNewBroadcastFromWebhook(c *gin.Context, plan *services.Plan, ytClient *youtube.Service, pcoClient *pco.PcoApiClient) error { + times, err := pcoClient.GetPlanTimes(plan.ServiceType.Id, plan.Id) + if err != nil { + log.WithError(err).Error("Failed to get plan times") + return err + } + + broadcast, err := yt_helpers.InsertBroadcast(ytClient, plan.Title, times.StartsAt, yt_helpers.STATUS_PRIVATE) + if err != nil { + log.WithError(err).Error("Failed to schedule broadcast") + return err + } return nil } diff --git a/service/go.mod b/service/go.mod index 2781f88..ce33005 100644 --- a/service/go.mod +++ b/service/go.mod @@ -10,6 +10,7 @@ require ( github.com/sirupsen/logrus v1.9.3 go.mongodb.org/mongo-driver v1.12.1 golang.org/x/oauth2 v0.14.0 + google.golang.org/api v0.150.0 ) require ( @@ -67,7 +68,6 @@ require ( golang.org/x/sync v0.5.0 // indirect golang.org/x/sys v0.14.0 // indirect golang.org/x/text v0.14.0 // indirect - google.golang.org/api v0.150.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 // indirect google.golang.org/grpc v1.59.0 // indirect diff --git a/service/go.sum b/service/go.sum index b30021c..70f7edc 100644 --- a/service/go.sum +++ b/service/go.sum @@ -37,7 +37,6 @@ cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFO cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw= -cloud.google.com/go v0.110.7 h1:rJyC7nWRg2jWGZ4wSJ5nY65GTdYJkg0cd/uXb+ACI6o= cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= @@ -758,7 +757,6 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -1133,8 +1131,6 @@ golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1544,6 +1540,7 @@ google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go. google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b h1:CIC2YMXmIhYw6evmhPxBKJ4fmLbOFtXQN/GV3XOZR8k= google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= diff --git a/service/vendors/pco/webhooks/structs.go b/service/vendors/pco/webhooks/structs.go index 737682a..7588290 100644 --- a/service/vendors/pco/webhooks/structs.go +++ b/service/vendors/pco/webhooks/structs.go @@ -1,6 +1,11 @@ package webhooks -import "git.preston-baxter.com/Preston_PLB/capstone/webhook-service/vendors/pco/services" +import ( + "strings" + + "git.preston-baxter.com/Preston_PLB/capstone/webhook-service/vendors/pco/services" + "github.com/google/jsonapi" +) //Structure delivered to target when sending webhooks type EventDelivery struct { @@ -16,3 +21,8 @@ type EventDelivery struct { //Owner Organization of the event Organization *services.Organization `jsonapi:"relation,organization"` } + +//Unmarshall payload of EventDelivery into the struct you think it is +func (event *EventDelivery) UnmarshallPayload(obj any) error { + return jsonapi.UnmarshalPayload(strings.NewReader(event.Payload), obj) +} diff --git a/service/vendors/youtube/youtube.go b/service/vendors/youtube/youtube.go new file mode 100644 index 0000000..328998c --- /dev/null +++ b/service/vendors/youtube/youtube.go @@ -0,0 +1,26 @@ +package youtube + +import ( + "time" + + "google.golang.org/api/youtube/v3" +) + +const ( + STATUS_PRIVATE = "private" + STATUS_PUBLIC = "public" +) + +//Inserts Broadcast into youtube +func InsertBroadcast(service *youtube.Service, title string, startTime time.Time, privacyStatus string) (*youtube.LiveBroadcast, error) { + liveBroadcast := &youtube.LiveBroadcast{ + Snippet: &youtube.LiveBroadcastSnippet{ + Title: title, + ScheduledStartTime: startTime.Format(time.RFC3339), + }, + Status: &youtube.LiveBroadcastStatus{ + PrivacyStatus: privacyStatus, + }, + } + return service.LiveBroadcasts.Insert([]string{"snippet", "status"}, liveBroadcast).Do() +}