Skip to content

Instantly share code, notes, and snippets.

@diericx
Last active November 6, 2019 23:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save diericx/074df254055cf10f1de3a52f72630511 to your computer and use it in GitHub Desktop.
Save diericx/074df254055cf10f1de3a52f72630511 to your computer and use it in GitHub Desktop.
package main
import (
"encoding/base64"
"encoding/json"
"log"
"net"
"net/http"
"time"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
)
// Small gif that we will serve
var gif = []byte{
71, 73, 70, 56, 57, 97, 1, 0, 1, 0, 128, 0, 0, 0, 0, 0,
255, 255, 255, 33, 249, 4, 1, 0, 0, 0, 0, 44, 0, 0, 0, 0,
1, 0, 1, 0, 0, 2, 1, 68, 0, 59,
}
// Track holds tracking data for a specific event
type Track struct {
ID int `json:"id"`
UserID string `json:"userId"`
FpHash string `json:"fpHash"` // fingerprint hash
PageURL string `json:"pageURL"` // optional (website specific)
PagePath string `json:"pagePath"` // optional ()
PageTitle string `json:"pageTitle"`
PageReferrer string `json:"pageReferrer"`
Event string `json:"event"`
CampaignSource string `json:"campaignSource"`
CampaignMedium string `json:"campaignMedium"`
CampaignName string `json:"campaignName"`
CampaignContent string `json:"campaignContent"`
SentAt time.Time `json:"sentAt"`
IP string
Extra string `json:"extra"` // (optional) extra json
}
func main() {
r := mux.NewRouter()
// Add routes
r.HandleFunc("/v1/pixel/track", func(w http.ResponseWriter, r *http.Request) {
// Get pixel data from client
v := r.URL.Query()
rawEvent := v.Get("data")
// Decode from base64
data, err := base64.StdEncoding.DecodeString(rawEvent)
if err != nil {
panic(err)
}
// Unmarshal json
track := Track{}
if err := json.Unmarshal(data, &track); err != nil {
panic(err)
}
// Grab IP (will be something like "::" for localhost)
ip, _, _ := net.SplitHostPort(r.RemoteAddr)
track.IP = ip
// TODO: Store instead of printing
log.Printf("Tracking Data: %v", track)
// Write gif back to client
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
w.Header().Set("Content-Type", "image/gif")
w.Write(gif)
}).Methods("GET")
// Start server
log.Fatal(http.ListenAndServe(":8080", handlers.CORS(handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type", "Authorization"}), handlers.AllowedMethods([]string{"GET", "POST", "PUT", "HEAD", "OPTIONS"}), handlers.AllowedOrigins([]string{"*"}))(r)))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment