Managing Customers#

Every Customer who wants to use MOIA’s Mobility Service needs to be registered in the Trip API. The Ridepooling Service uses the Customer data to address the Customer during different parts of the Trip or to contact them if something goes wrong.

Create the Client#

customerClient := customerv1.NewCustomerServiceClient(conn)
const client = clientFactory.create(CustomerServiceDefinition, channel);

Creating a Customer#

When creating a Customer the Customer object is returned including the generated Customer id. This Customer id is essential for all further interactions related to a Customer. This includes but is not limited to updating a Customer or ordering an Offer for a Trip.

Important

There is no restriction on the uniqueness of any Customer properties except the id. And since the id is generated by the Customer Service multiple requests with the same Customer data will result in the creation of multiple Customers with different ids.

The following example details a CreateCustomerRequest to create a new Customer.

grpcurl \
  -H "authorization: Bearer ${ACCESS_TOKEN}" \
  -import-path ./protos/ \
  -proto "moia/trip/customer/v1/customer.proto" \
  -proto "google/rpc/error_details.proto" \
  -d "{\"email_address\":\"test-customer@moia.io\",\"family_name\":\"Customer\",\"given_name\":\"Test\",\"language_code\":\"en\",\"phone_number\":\"+4997259173740\"}" \
  $API_URL moia.trip.customer.v1.CustomerService/CreateCustomer
customer, err := customerClient.CreateCustomer(ctx, &customerv1.CreateCustomerRequest{
	EmailAddress: "test-customer@moia.io",
	FamilyName:   "Customer",
	GivenName:    "Test",
	LanguageCode: "en",
	PhoneNumber:  "+4997259173740",
})
if err != nil {
	log.Fatalf("Could not create customer: %v", err)
}
log.Printf("Successfully created customer: %v", jsonMarshalOptions.Format(customer))
const customer = await client.createCustomer({
  emailAddress: "test-customer@moia.io",
  familyName: "Customer",
  givenName: "Test",
  languageCode: "en",
  phoneNumber: "+4997259173740",
});
console.log(
  "Successfully created customer:",
  JSON.stringify(customer, null, 2)
);

Listing all Customers#

To get all Customers, we can request them using the ListCustomers RPC.

This method returns a paginated list of Customers. When the next_page_token is set in the response, passing this token as page_token in the next request will return the next page of Customers.

Is the next_page_token not set in the response, we have reached the last page of Customers. The next_page_token should be considered as an opaque token and should not be interpreted in any way.

The following example details a ListCustomersRequest to get existing Customers through paginated requests.

grpcurl \
  -H "authorization: Bearer ${ACCESS_TOKEN}" \
  -import-path ./protos/ \
  -proto "moia/trip/customer/v1/customer.proto" \
  -proto "google/rpc/error_details.proto" \
  -d "{\"page_size\":5}" \
  $API_URL moia.trip.customer.v1.CustomerService/ListCustomers
pageSize := int32(5)

listCustomersResponse, err := customerClient.ListCustomers(ctx, &customerv1.ListCustomersRequest{
	PageSize: &pageSize,
})
if err != nil {
	log.Fatalf("Could not list customers: %v", err)
}
log.Printf("Successfully listed %d customers", len(listCustomersResponse.Customers))
const listCustomersResponse = await client.listCustomers({
  pageSize: 5,
});
console.log(
  `Successfully listed ${listCustomersResponse.customers.length} customers`
);

Deleting a Customer#

For deleting a Customer the DeleteCustomer RPC is used.

When a Customer is deleted while having an active Trip, the Customer will be able to finish the Trip. But the Customer will not be able to order any new Trips.

The following example details a DeleteCustomerRequest to delete an existing Customer.

# export CUSTOMER_ID="<replace with customer id>"

grpcurl \
  -H "authorization: Bearer ${ACCESS_TOKEN}" \
  -import-path ./protos/ \
  -proto "moia/trip/customer/v1/customer.proto" \
  -proto "google/rpc/error_details.proto" \
  -d "{\"id\":\"${CUSTOMER_ID}\"}" \
  $API_URL moia.trip.customer.v1.CustomerService/DeleteCustomer
_, err = customerClient.DeleteCustomer(ctx, &customerv1.DeleteCustomerRequest{
	Id: customer.Customer.Id,
})
if err != nil {
	log.Fatalf("Could not delete customer: %v", err)
}
log.Printf("Successfully removed customer with id %s", customer.Customer.Id)
await client.deleteCustomer({ id: customer.customer?.id });
console.log(`Successfully removed customer with id ${customer.customer?.id}`);

Managing Customer Flags#

The flags of a Customer can be managed through the AddCustomerFlag RPC and RemoveCustomerFlag RPC. A Customer’s currently set flags are returned by the ListCustomerFlags RPC.

For more information about Customer flags, please refer to the Customer flags fundamentals.

The following example details an AddCustomerFlagRequest to attach a flag to an existing Customer.

# export CUSTOMER_ID="<replace with customer id>"
# export CUSTOMER_FLAG="<replace with customer flag>"

grpcurl \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -import-path ./protos/ \
  -proto "moia/trip/customer/v1/customer.proto" \
  -proto "google/rpc/error_details.proto" \
  -d "{\"customer_id\":\"${CUSTOMER_ID}\",\"flag\":\"${CUSTOMER_FLAG}\"}" \
  $API_URL moia.trip.customer.v1.CustomerService/AddCustomerFlag
addCustomerFlagResponse, err := customerClient.AddCustomerFlag(ctx, &customerv1.AddCustomerFlagRequest{
	CustomerId: customer.Customer.Id,
	// replace `customerFlag` with the customer flag to be added to the customer
	Flag: customerFlag,
})
if err != nil {
	log.Fatalf("Could not add customer flag: %v", err)
}
log.Printf("Successfully added customer flag: %v", jsonMarshalOptions.Format(addCustomerFlagResponse))
const addCustomerFlagResponse = await client.addCustomerFlag({
  customerId: customer.customer?.id,
  // replace `customerFlag` with the customer flag to be added to the customer
  flag: customerFlag,
});
console.log(
  "Successfully added customer flag:",
  JSON.stringify(addCustomerFlagResponse, null, 2)
);

The following example details a RemoveCustomerFlagRequest to remove a flag from an existing Customer.

# export CUSTOMER_ID="<replace with customer id>"
# export CUSTOMER_FLAG="<replace with customer flag>"

grpcurl \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -import-path ./protos/ \
  -proto "moia/trip/customer/v1/customer.proto" \
  -proto "google/rpc/error_details.proto" \
  -d "{\"customer_id\":\"${CUSTOMER_ID}\",\"flag\":\"${CUSTOMER_FLAG}\"}" \
  $API_URL moia.trip.customer.v1.CustomerService/RemoveCustomerFlag
_, err = customerClient.RemoveCustomerFlag(ctx, &customerv1.RemoveCustomerFlagRequest{
	CustomerId: customer.Customer.Id,
	// replace `customerFlag` with the customer flag to be removed from the customer
	Flag: customerFlag,
})
if err != nil {
	log.Fatalf("Could not remove customer flag: %v", err)
}
log.Printf("Successfully removed customer flag: %s", customerFlag)
await client.removeCustomerFlag({
  customerId: customer.customer?.id,
  // replace `customerFlag` with the customer flag to be removed from the customer
  flag: customerFlag,
});
console.log("Successfully removed customer flag:", customerFlag);

The following example details a ListCustomerFlagsRequest to read the flags of an existing Customer.

# export CUSTOMER_ID="<replace with customer id>"

grpcurl \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -import-path ./protos/ \
  -proto "moia/trip/customer/v1/customer.proto" \
  -proto "google/rpc/error_details.proto" \
  -d "{\"customer_id\":\"${CUSTOMER_ID}\",\"page_size\":5}" \
  $API_URL moia.trip.customer.v1.CustomerService/ListCustomerFlags
listCustomerFlagsResponse, err := customerClient.ListCustomerFlags(ctx, &customerv1.ListCustomerFlagsRequest{
	CustomerId: customer.Customer.Id,
})
if err != nil {
	log.Fatalf("Could not list customer flags: %v", err)
}
log.Printf("Successfully listed %d customer flags", len(listCustomerFlagsResponse.Flags))
const listCustomerFlagResponse = await client.listCustomerFlags({
  customerId: customer.customer?.id,
});
console.log(
  `Successfully listed ${listCustomerFlagResponse.flags.length} customer flags`
);