mirror of
https://github.com/google-wallet/rest-samples.git
synced 2026-01-08 05:03:54 -05:00
Migrate to googleapis instead of raw json/http
This commit is contained in:
@@ -20,15 +20,19 @@ package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/google/uuid"
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/oauth2/google"
|
||||
oauthJwt "golang.org/x/oauth2/jwt"
|
||||
"google.golang.org/api/option"
|
||||
"google.golang.org/api/walletobjects/v1"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
@@ -45,17 +49,21 @@ const (
|
||||
|
||||
type demoLoyalty struct {
|
||||
credentials *oauthJwt.Config
|
||||
httpClient *http.Client
|
||||
service *walletobjects.Service
|
||||
batchUrl, classUrl, objectUrl string
|
||||
}
|
||||
|
||||
// [START auth]
|
||||
// Create authenticated HTTP client using a service account file.
|
||||
func (d *demoLoyalty) auth() {
|
||||
b, _ := os.ReadFile(os.Getenv("GOOGLE_APPLICATION_CREDENTIALS"))
|
||||
credentials, _ := google.JWTConfigFromJSON(b, "https://www.googleapis.com/auth/wallet_object.issuer")
|
||||
credentialsFile := os.Getenv("GOOGLE_APPLICATION_CREDENTIALS")
|
||||
b, _ := os.ReadFile(credentialsFile)
|
||||
credentials, err := google.JWTConfigFromJSON(b, walletobjects.WalletObjectIssuerScope)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to create credentials: %v", err)
|
||||
}
|
||||
d.credentials = credentials
|
||||
d.httpClient = d.credentials.Client(oauth2.NoContext)
|
||||
d.service, _ = walletobjects.NewService(context.Background(), option.WithCredentialsFile(credentialsFile))
|
||||
}
|
||||
|
||||
// [END auth]
|
||||
@@ -63,33 +71,22 @@ func (d *demoLoyalty) auth() {
|
||||
// [START createClass]
|
||||
// Create a class.
|
||||
func (d *demoLoyalty) createClass(issuerId, classSuffix string) {
|
||||
newClass := fmt.Sprintf(`
|
||||
{
|
||||
"programName": "Program name",
|
||||
"issuerName": "Issuer name",
|
||||
"reviewStatus": "UNDER_REVIEW",
|
||||
"id": "%s.%s",
|
||||
"programLogo": {
|
||||
"contentDescription": {
|
||||
"defaultValue": {
|
||||
"value": "Logo description",
|
||||
"language": "en-US"
|
||||
}
|
||||
},
|
||||
"sourceUri": {
|
||||
"uri": "http://farm8.staticflickr.com/7340/11177041185_a61a7f2139_o.jpg"
|
||||
}
|
||||
}
|
||||
var loyaltyClass *walletobjects.LoyaltyClass = new(walletobjects.LoyaltyClass)
|
||||
logo := walletobjects.Image {
|
||||
SourceUri: &walletobjects.ImageUri {
|
||||
Uri: "http://farm8.staticflickr.com/7340/11177041185_a61a7f2139_o.jpg",
|
||||
},
|
||||
}
|
||||
`, issuerId, classSuffix)
|
||||
|
||||
res, err := d.httpClient.Post(classUrl, "application/json", bytes.NewBuffer([]byte(newClass)))
|
||||
|
||||
loyaltyClass.Id = fmt.Sprintf("%s.%s", issuerId, classSuffix)
|
||||
loyaltyClass.ProgramName = "Program name"
|
||||
loyaltyClass.IssuerName = "Issuer name"
|
||||
loyaltyClass.ReviewStatus = "UNDER_REVIEW"
|
||||
loyaltyClass.ProgramLogo = &logo
|
||||
res, err := d.service.Loyaltyclass.Insert(loyaltyClass).Do()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
b, _ := io.ReadAll(res.Body)
|
||||
fmt.Printf("Class insert response:\n%s\n", b)
|
||||
fmt.Printf("Class insert id:\n%v\n", res.Id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,87 +95,67 @@ func (d *demoLoyalty) createClass(issuerId, classSuffix string) {
|
||||
// [START createObject]
|
||||
// Create an object.
|
||||
func (d *demoLoyalty) createObject(issuerId, classSuffix, objectSuffix string) {
|
||||
newObject := fmt.Sprintf(`
|
||||
{
|
||||
"classId": "%s.%s",
|
||||
"heroImage": {
|
||||
"contentDescription": {
|
||||
"defaultValue": {
|
||||
"value": "Hero image description",
|
||||
"language": "en-US"
|
||||
}
|
||||
},
|
||||
"sourceUri": {
|
||||
"uri": "https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg"
|
||||
}
|
||||
},
|
||||
"barcode": {
|
||||
"type": "QR_CODE",
|
||||
"value": "QR code"
|
||||
},
|
||||
"locations": [
|
||||
{
|
||||
"latitude": 37.424015499999996,
|
||||
"longitude": -122.09259560000001
|
||||
}
|
||||
],
|
||||
"accountName": "Account name",
|
||||
"state": "ACTIVE",
|
||||
"linksModuleData": {
|
||||
"uris": [
|
||||
{
|
||||
"id": "LINK_MODULE_URI_ID",
|
||||
"uri": "http://maps.google.com/",
|
||||
"description": "Link module URI description"
|
||||
},
|
||||
{
|
||||
"id": "LINK_MODULE_TEL_ID",
|
||||
"uri": "tel:6505555555",
|
||||
"description": "Link module tel description"
|
||||
}
|
||||
]
|
||||
},
|
||||
"imageModulesData": [
|
||||
{
|
||||
"id": "IMAGE_MODULE_ID",
|
||||
"mainImage": {
|
||||
"contentDescription": {
|
||||
"defaultValue": {
|
||||
"value": "Image module description",
|
||||
"language": "en-US"
|
||||
}
|
||||
},
|
||||
"sourceUri": {
|
||||
"uri": "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"textModulesData": [
|
||||
{
|
||||
"body": "Text module body",
|
||||
"header": "Text module header",
|
||||
"id": "TEXT_MODULE_ID"
|
||||
}
|
||||
],
|
||||
"id": "%s.%s",
|
||||
"loyaltyPoints": {
|
||||
"balance": {
|
||||
"int": 800
|
||||
},
|
||||
"label": "Points"
|
||||
},
|
||||
"accountId": "Account id"
|
||||
var loyaltyObject *walletobjects.LoyaltyObject = new(walletobjects.LoyaltyObject)
|
||||
loyaltyObject.Id = fmt.Sprintf("%s.%s", issuerId, objectSuffix)
|
||||
loyaltyObject.ClassId = fmt.Sprintf("%s.%s", issuerId, classSuffix)
|
||||
loyaltyObject.AccountName = "Account name"
|
||||
loyaltyObject.AccountId = "Account id"
|
||||
loyaltyObject.State = "ACTIVE"
|
||||
loyaltyObject.LoyaltyPoints = &walletobjects.LoyaltyPoints {
|
||||
Balance: &walletobjects.LoyaltyPointsBalance { Int: 800 },
|
||||
Label: "Points",
|
||||
}
|
||||
`, issuerId, classSuffix, issuerId, objectSuffix)
|
||||
|
||||
res, err := d.httpClient.Post(objectUrl, "application/json", bytes.NewBuffer([]byte(newObject)))
|
||||
|
||||
loyaltyObject.HeroImage = &walletobjects.Image {
|
||||
SourceUri: &walletobjects.ImageUri {
|
||||
Uri: "https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg",
|
||||
},
|
||||
}
|
||||
loyaltyObject.Barcode = &walletobjects.Barcode {
|
||||
Type: "QR_CODE",
|
||||
Value: "QR code",
|
||||
}
|
||||
loyaltyObject.Locations = []*walletobjects.LatLongPoint {
|
||||
&walletobjects.LatLongPoint {
|
||||
Latitude: 37.424015499999996,
|
||||
Longitude: -122.09259560000001,
|
||||
},
|
||||
}
|
||||
loyaltyObject.LinksModuleData = &walletobjects.LinksModuleData {
|
||||
Uris: []*walletobjects.Uri {
|
||||
&walletobjects.Uri {
|
||||
Id: "LINK_MODULE_URI_ID",
|
||||
Uri: "http://maps.google.com/",
|
||||
Description: "Link module URI description",
|
||||
},
|
||||
&walletobjects.Uri {
|
||||
Id: "LINK_MODULE_TEL_ID",
|
||||
Uri: "tel:6505555555",
|
||||
Description: "Link module tel description",
|
||||
},
|
||||
},
|
||||
}
|
||||
loyaltyObject.ImageModulesData = []*walletobjects.ImageModuleData {
|
||||
&walletobjects.ImageModuleData {
|
||||
Id: "IMAGE_MODULE_ID",
|
||||
MainImage: &walletobjects.Image {
|
||||
SourceUri: &walletobjects.ImageUri{
|
||||
Uri: "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
loyaltyObject.TextModulesData = []*walletobjects.TextModuleData {
|
||||
&walletobjects.TextModuleData {
|
||||
Body: "Text module body",
|
||||
Header: "Text module header",
|
||||
Id: "TEXT_MODULE_ID",
|
||||
},
|
||||
}
|
||||
res, err := d.service.Loyaltyobject.Insert(loyaltyObject).Do()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
b, _ := io.ReadAll(res.Body)
|
||||
fmt.Printf("Object insert response:\n%s\n", b)
|
||||
fmt.Printf("Object insert id:\n%s\n", res.Id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,16 +167,13 @@ func (d *demoLoyalty) createObject(issuerId, classSuffix, objectSuffix string) {
|
||||
// Sets the object's state to Expired. If the valid time interval is
|
||||
// already set, the pass will expire automatically up to 24 hours after.
|
||||
func (d *demoLoyalty) expireObject(issuerId, objectSuffix string) {
|
||||
patchBody := `{"state": "EXPIRED"}`
|
||||
url := fmt.Sprintf("%s/%s.%s", objectUrl, issuerId, objectSuffix)
|
||||
req, _ := http.NewRequest(http.MethodPatch, url, bytes.NewBuffer([]byte(patchBody)))
|
||||
res, err := d.httpClient.Do(req)
|
||||
|
||||
var loyaltyObject *walletobjects.LoyaltyObject = new(walletobjects.LoyaltyObject)
|
||||
loyaltyObject.State = "EXPIRED"
|
||||
res, err := d.service.Loyaltyobject.Patch(fmt.Sprintf("%s.%s", issuerId, objectSuffix), loyaltyObject).Do()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
b, _ := io.ReadAll(res.Body)
|
||||
fmt.Printf("Object expiration response:\n%s\n", b)
|
||||
fmt.Printf("Object expiration id:\n%s\n", res.Id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,107 +187,19 @@ func (d *demoLoyalty) expireObject(issuerId, objectSuffix string) {
|
||||
// created. This allows you to create multiple pass classes and objects in
|
||||
// one API call when the user saves the pass to their wallet.
|
||||
func (d *demoLoyalty) createJwtNewObjects(issuerId, classSuffix, objectSuffix string) {
|
||||
newClass := fmt.Sprintf(`
|
||||
{
|
||||
"programName": "Program name",
|
||||
"issuerName": "Issuer name",
|
||||
"reviewStatus": "UNDER_REVIEW",
|
||||
"id": "%s.%s",
|
||||
"programLogo": {
|
||||
"contentDescription": {
|
||||
"defaultValue": {
|
||||
"value": "Logo description",
|
||||
"language": "en-US"
|
||||
}
|
||||
},
|
||||
"sourceUri": {
|
||||
"uri": "http://farm8.staticflickr.com/7340/11177041185_a61a7f2139_o.jpg"
|
||||
}
|
||||
}
|
||||
}
|
||||
`, issuerId, classSuffix)
|
||||
|
||||
newObject := fmt.Sprintf(`
|
||||
{
|
||||
"classId": "%s.%s",
|
||||
"heroImage": {
|
||||
"contentDescription": {
|
||||
"defaultValue": {
|
||||
"value": "Hero image description",
|
||||
"language": "en-US"
|
||||
}
|
||||
},
|
||||
"sourceUri": {
|
||||
"uri": "https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg"
|
||||
}
|
||||
},
|
||||
"barcode": {
|
||||
"type": "QR_CODE",
|
||||
"value": "QR code"
|
||||
},
|
||||
"locations": [
|
||||
{
|
||||
"latitude": 37.424015499999996,
|
||||
"longitude": -122.09259560000001
|
||||
}
|
||||
],
|
||||
"accountName": "Account name",
|
||||
"state": "ACTIVE",
|
||||
"linksModuleData": {
|
||||
"uris": [
|
||||
{
|
||||
"id": "LINK_MODULE_URI_ID",
|
||||
"uri": "http://maps.google.com/",
|
||||
"description": "Link module URI description"
|
||||
},
|
||||
{
|
||||
"id": "LINK_MODULE_TEL_ID",
|
||||
"uri": "tel:6505555555",
|
||||
"description": "Link module tel description"
|
||||
}
|
||||
]
|
||||
},
|
||||
"imageModulesData": [
|
||||
{
|
||||
"id": "IMAGE_MODULE_ID",
|
||||
"mainImage": {
|
||||
"contentDescription": {
|
||||
"defaultValue": {
|
||||
"value": "Image module description",
|
||||
"language": "en-US"
|
||||
}
|
||||
},
|
||||
"sourceUri": {
|
||||
"uri": "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"textModulesData": [
|
||||
{
|
||||
"body": "Text module body",
|
||||
"header": "Text module header",
|
||||
"id": "TEXT_MODULE_ID"
|
||||
}
|
||||
],
|
||||
"id": "%s.%s",
|
||||
"loyaltyPoints": {
|
||||
"balance": {
|
||||
"int": 800
|
||||
},
|
||||
"label": "Points"
|
||||
},
|
||||
"accountId": "Account id"
|
||||
}
|
||||
`, issuerId, classSuffix, issuerId, objectSuffix)
|
||||
var loyaltyObject *walletobjects.LoyaltyObject = new(walletobjects.LoyaltyObject)
|
||||
loyaltyObject.Id = fmt.Sprintf("%s.%s", issuerId, objectSuffix + "_")
|
||||
loyaltyObject.ClassId = fmt.Sprintf("%s.%s", issuerId, classSuffix)
|
||||
loyaltyObject.AccountName = "Account name"
|
||||
loyaltyObject.AccountId = "Account id"
|
||||
loyaltyObject.State = "ACTIVE"
|
||||
|
||||
var payload map[string]interface{}
|
||||
json.Unmarshal([]byte(fmt.Sprintf(`
|
||||
{
|
||||
"genericClasses": [%s],
|
||||
"genericObjects": [%s]
|
||||
"loyaltyObjects": [%s]
|
||||
}
|
||||
`, newClass, newObject)), &payload)
|
||||
`, json.Marshal(loyaltyObject))), &payload)
|
||||
|
||||
claims := jwt.MapClaims{
|
||||
"iss": d.credentials.Email,
|
||||
@@ -327,7 +213,7 @@ func (d *demoLoyalty) createJwtNewObjects(issuerId, classSuffix, objectSuffix st
|
||||
key, _ := jwt.ParseRSAPrivateKeyFromPEM(d.credentials.PrivateKey)
|
||||
token, _ := jwt.NewWithClaims(jwt.SigningMethodRS256, claims).SignedString(key)
|
||||
|
||||
fmt.Println("Add to Google Wallet link")
|
||||
fmt.Println("Add to Google Wallet link for new objects")
|
||||
fmt.Println("https://pay.google.com/gp/v/save/" + token)
|
||||
}
|
||||
|
||||
@@ -340,46 +226,16 @@ func (d *demoLoyalty) createJwtNewObjects(issuerId, classSuffix, objectSuffix st
|
||||
// their wallet, the pass objects defined in the JWT are added to the
|
||||
// user's Google Wallet app. This allows the user to save multiple pass
|
||||
// objects in one API call.
|
||||
func (d *demoLoyalty) createJwtExistingObjects(issuerId string) {
|
||||
func (d *demoLoyalty) createJwtExistingObjects(issuerId string, classSuffix string, objectSuffix string) {
|
||||
var payload map[string]interface{}
|
||||
json.Unmarshal([]byte(fmt.Sprintf(`
|
||||
{
|
||||
"eventTicketObjects": [{
|
||||
"id": "%s.EVENT_OBJECT_SUFFIX",
|
||||
"classId": "%s.EVENT_CLASS_SUFFIX"
|
||||
}],
|
||||
|
||||
"flightObjects": [{
|
||||
"id": "%s.FLIGHT_OBJECT_SUFFIX",
|
||||
"classId": "%s.FLIGHT_CLASS_SUFFIX"
|
||||
}],
|
||||
|
||||
"genericObjects": [{
|
||||
"id": "%s.GENERIC_OBJECT_SUFFIX",
|
||||
"classId": "%s.GENERIC_CLASS_SUFFIX"
|
||||
}],
|
||||
|
||||
"giftCardObjects": [{
|
||||
"id": "%s.GIFT_CARD_OBJECT_SUFFIX",
|
||||
"classId": "%s.GIFT_CARD_CLASS_SUFFIX"
|
||||
}],
|
||||
|
||||
"loyaltyObjects": [{
|
||||
"id": "%s.LOYALTY_OBJECT_SUFFIX",
|
||||
"classId": "%s.LOYALTY_CLASS_SUFFIX"
|
||||
"id": "%s.%s",
|
||||
"classId": "%s.%s"
|
||||
}],
|
||||
|
||||
"offerObjects": [{
|
||||
"id": "%s.OFFER_OBJECT_SUFFIX",
|
||||
"classId": "%s.OFFER_CLASS_SUFFIX"
|
||||
}],
|
||||
|
||||
"transitObjects": [{
|
||||
"id": "%s.TRANSIT_OBJECT_SUFFIX",
|
||||
"classId": "%s.TRANSIT_CLASS_SUFFIX"
|
||||
}]
|
||||
}
|
||||
`, issuerId)), &payload)
|
||||
`, issuerId, objectSuffix, issuerId, classSuffix)), &payload)
|
||||
|
||||
claims := jwt.MapClaims{
|
||||
"iss": d.credentials.Email,
|
||||
@@ -393,7 +249,7 @@ func (d *demoLoyalty) createJwtExistingObjects(issuerId string) {
|
||||
key, _ := jwt.ParseRSAPrivateKeyFromPEM(d.credentials.PrivateKey)
|
||||
token, _ := jwt.NewWithClaims(jwt.SigningMethodRS256, claims).SignedString(key)
|
||||
|
||||
fmt.Println("Add to Google Wallet link")
|
||||
fmt.Println("Add to Google Wallet link for existing objects")
|
||||
fmt.Println("https://pay.google.com/gp/v/save/" + token)
|
||||
}
|
||||
|
||||
@@ -487,8 +343,7 @@ func (d *demoLoyalty) batchCreateObjects(issuerId, classSuffix string) {
|
||||
}
|
||||
data += "--batch_createobjectbatch--"
|
||||
|
||||
// batchUrl = 'https://walletobjects.googleapis.com/batch';
|
||||
res, err := d.httpClient.Post(batchUrl, "multipart/mixed; boundary=batch_createobjectbatch", bytes.NewBuffer([]byte(data)))
|
||||
res, err := d.credentials.Client(oauth2.NoContext).Post(batchUrl, "multipart/mixed; boundary=batch_createobjectbatch", bytes.NewBuffer([]byte(data)))
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
@@ -517,6 +372,6 @@ func main() {
|
||||
d.createObject(issuerId, classSuffix, objectSuffix)
|
||||
d.expireObject(issuerId, objectSuffix)
|
||||
d.createJwtNewObjects(issuerId, classSuffix, objectSuffix)
|
||||
d.createJwtExistingObjects(issuerId)
|
||||
d.createJwtExistingObjects(issuerId, classSuffix, objectSuffix)
|
||||
d.batchCreateObjects(issuerId, classSuffix)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user