1

I'm wondering what is the best way to iterate over some conditionals to generate a complete XML response for an adTag.

See vmap xml file here: https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpremidpostpod&ciu_szs=300x250&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&impl=s&cmsid=496&vid=short_onecue&correlator=

I am building an array of elements using a single type of struct that would represent a single Adbreak and then I need to wrap them all in vmap:VMAP element. This would be very easy for me to solve in Node.js but I have delegated my ad server to Golang and am having some trouble with generating XML's.

I want to do a loop through each condition. For example: preRoll := 1, midRoll1 := 3, midRoll2 := 3, midRoll3 := 1, postRoll := 1. And I would be iterating based on those numbers, so preRoll := 1 would result with

<vmap:AdBreak timeOffset="start" breakType="linear" breakId="preroll">
 <vmap:AdSource id="preroll-ad-1" allowMultipleAds="false" followRedirects="true">
  <vmap:AdTagURI templateType="vast3">
   <![CDATA[ https://pubads.g.doubleclick.net/gampad/ads?slotname=/21775744923/external/vmap_ad_samples&sz=640x480&ciu_szs=300x250&cust_params=sample_ar%3Dpremidpostpod&url=&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&useragent=Mozilla/5.0+(Windows+NT+10.0%3B+Win64%3B+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/103.0.0.0+Safari/537.36,gzip(gfe)&vad_type=linear&vpos=preroll&pod=1&ppos=1&lip=true&min_ad_duration=0&max_ad_duration=30000&vrid=1270234&cmsid=496&video_doc_id=short_onecue&kfa=0&tfcd=0 ]]>
  </vmap:AdTagURI>
 </vmap:AdSource>
</vmap:AdBreak>

and then I would append the next AdBreak element after that. I do not want to generate a file, I am simply responding and serving the file when a get request is made to the endpoint. Im also wondering how I would conditionally change the attributes for each element because it seems I can only define them within the struct object literal ``

type Vmap struct {
    AdBreak string
}

func marshallVmap() ([]byte, error) {
    temp := struct {
        vmap string `vmap:Adbreak`
    }{
        vmap: "a",
    }
    return xml.MarshalIndent(temp, "", " ")
}

func GenerateAndServeVmap(r *http.Request) ([]byte, error) {
    vmaps := make([]interface{}, 0)
    preRoll := true
    // midRoll1 := 3
    // postRoll := true
    if preRoll {
        t, _ := marshallVmap()
        vmaps = append(vmaps, t)
    }
    xml.MarshalIndent(vmaps, "", " ")
    fmt.Printf(" %v", vmaps)
    return []byte(vmaps), nil
}

func handleAdRequests(w http.ResponseWriter, r *http.Request) {
 vmap, err := ad_queue.GenerateAndServeVmap(r)
 if err != nil {
  return
 }
 w.Header().Set("Content-Type", "application/xml")
 w.Header().Set("Access-Control-Allow-Credentials", "true")
 w.Write(vmap)
}

Update: I've since made some progress using the following method:

type Vmap struct {
    XMLName  xml.Name  `xml:"vmap:VMAP"`
    VmapAttr string    `xml:"xmlns:vmap,attr"`
    Version  string    `xml:"version,attr"`
    AdBreaks []AdBreak `xmlns:"vmap,namespace"`
}

type AdBreak struct {
    XMLName    xml.Name `xml:"vmap:AdBreak"`
    TimeOffset string   `xml:"timeOffset,attr"`
    BreakType  string   `xml:"breakType,attr"`
    BreakId    string   `xml:"breakId,attr"`
    AdSource   AdSource `xmlns:"vmap,namespace"`
}

type AdSource struct {
    XMLName          xml.Name `xml:"vmap:AdSource"`
    Id               string   `xml:"id,attr"`
    AllowMultipleAds string   `xml:"allowMultipleAds,attr"`
    FollowRedirects  string   `xml:"followRedirects,attr"`
    AdTagUri         AdTagUri `xmlns:"vmap,namespace"`
}

type AdTagUri struct {
    XMLName      xml.Name `xml:"vmap:AdTagURI"`
    TemplateType string   `xml:"templateType,attr"`
    Url          string   `xml:",innerxml"`
}

func GenerateAndServeVmap(r *http.Request) ([]byte, error) {
    response := Vmap{
        xml.Name{},
        "http://www.iab.net/videosuite/vmap",
        "1.0",
        []AdBreak{
            {xml.Name{}, "start", "linear", "preroll",
                AdSource{xml.Name{}, "preroll-ad-1", "false", "true",
                    AdTagUri{xml.Name{}, "vast3", "<![CDATA[ https://pubads.g.doubleclick.net/gampad/ads?slotname=/21775744923/external/vmap_ad_samples&sz=640x480&ciu_szs=300x250&cust_params=sample_ar%3Dpremidpostpod&url=&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&useragent=Mozilla/5.0+(Windows+NT+10.0%3B+Win64%3B+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/103.0.0.0+Safari/537.36,gzip(gfe)&vad_type=linear&vpos=preroll&pod=1&ppos=1&lip=true&min_ad_duration=0&max_ad_duration=30000&vrid=1270234&cmsid=496&video_doc_id=short_onecue&kfa=0&tfcd=0 ]]>"},
                },
            },
            {xml.Name{}, "00:00:15", "linear", "midroll-1",
                AdSource{xml.Name{}, "midroll-1-ad-1", "false", "true",
                    AdTagUri{xml.Name{}, "vast3", "yup"},
                },
            },
        },
    }

    x, err := xml.MarshalIndent(response, "", " ")
    if err != nil {
        return nil, err
    }
    return []byte(x), nil
}

func handleAdRequests(w http.ResponseWriter, r *http.Request) {
    // log.Printf("%v", r)
    origin := r.Header.Get("Origin")
    supportedOrigins := []Origin{{"https://imasdk.googleapis.com"}, {"imasdk.googleapis.com"}, {"http://localhost:3000"}, {"localhost:3000"}}
    match := false

    for i := range supportedOrigins {
        if supportedOrigins[i].Name == origin {
            w.Header().Set("Access-Control-Allow-Origin", origin)
            match = true
        }
    }
    if match == false {
        w.Header().Set("Access-Control-Allow-Origin", "*")
    }

    vmap, err := ad_queue.GenerateAndServeVmap(r)
    if err != nil {
        return
    }

    w.Header().Set("Content-Type", "application/xml")
    w.Header().Set("Access-Control-Allow-Credentials", "true")
    w.Write(vmap)
}
lovgrandma
  • 133
  • 1
  • 9

0 Answers0