mirror of
https://github.com/googleapis/googleapis.git
synced 2026-08-17 13:06:47 +02:00
659 lines
22 KiB
Protocol Buffer
659 lines
22 KiB
Protocol Buffer
// Copyright 2025 Google LLC
|
||
//
|
||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||
// you may not use this file except in compliance with the License.
|
||
// You may obtain a copy of the License at
|
||
//
|
||
// http://www.apache.org/licenses/LICENSE-2.0
|
||
//
|
||
// Unless required by applicable law or agreed to in writing, software
|
||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
// See the License for the specific language governing permissions and
|
||
// limitations under the License.
|
||
|
||
syntax = "proto3";
|
||
|
||
package google.cloud.visionai.v1alpha1;
|
||
|
||
import "google/protobuf/struct.proto";
|
||
import "google/protobuf/timestamp.proto";
|
||
|
||
option csharp_namespace = "Google.Cloud.VisionAI.V1Alpha1";
|
||
option go_package = "cloud.google.com/go/visionai/apiv1alpha1/visionaipb;visionaipb";
|
||
option java_multiple_files = true;
|
||
option java_outer_classname = "AnnotationsProto";
|
||
option java_package = "com.google.cloud.visionai.v1alpha1";
|
||
option php_namespace = "Google\\Cloud\\VisionAI\\V1alpha1";
|
||
option ruby_package = "Google::Cloud::VisionAI::V1alpha1";
|
||
|
||
// Enum describing all possible types of a stream annotation.
|
||
enum StreamAnnotationType {
|
||
// Type UNSPECIFIED.
|
||
STREAM_ANNOTATION_TYPE_UNSPECIFIED = 0;
|
||
|
||
// active_zone annotation defines a polygon on top of the content from an
|
||
// image/video based stream, following processing will only focus on the
|
||
// content inside the active zone.
|
||
STREAM_ANNOTATION_TYPE_ACTIVE_ZONE = 1;
|
||
|
||
// crossing_line annotation defines a polyline on top of the content from an
|
||
// image/video based Vision AI stream, events happening across the line will
|
||
// be captured. For example, the counts of people who goes acroos the line
|
||
// in Occupancy Analytic Processor.
|
||
STREAM_ANNOTATION_TYPE_CROSSING_LINE = 2;
|
||
}
|
||
|
||
// Output format for Personal Protective Equipment Detection Operator.
|
||
message PersonalProtectiveEquipmentDetectionOutput {
|
||
// The entity info for annotations from person detection prediction result.
|
||
message PersonEntity {
|
||
// Entity id.
|
||
int64 person_entity_id = 1;
|
||
}
|
||
|
||
// The entity info for annotations from PPE detection prediction result.
|
||
message PPEEntity {
|
||
// Label id.
|
||
int64 ppe_label_id = 1;
|
||
|
||
// Human readable string of the label (Examples: helmet, glove, mask).
|
||
string ppe_label_string = 2;
|
||
|
||
// Human readable string of the super category label (Examples: head_cover,
|
||
// hands_cover, face_cover).
|
||
string ppe_supercategory_label_string = 3;
|
||
|
||
// Entity id.
|
||
int64 ppe_entity_id = 4;
|
||
}
|
||
|
||
// Bounding Box in the normalized coordinates.
|
||
message NormalizedBoundingBox {
|
||
// Min in x coordinate.
|
||
float xmin = 1;
|
||
|
||
// Min in y coordinate.
|
||
float ymin = 2;
|
||
|
||
// Width of the bounding box.
|
||
float width = 3;
|
||
|
||
// Height of the bounding box.
|
||
float height = 4;
|
||
}
|
||
|
||
// PersonIdentified box contains the location and the entity info of the
|
||
// person.
|
||
message PersonIdentifiedBox {
|
||
// An unique id for this box.
|
||
int64 box_id = 1;
|
||
|
||
// Bounding Box in the normalized coordinates.
|
||
NormalizedBoundingBox normalized_bounding_box = 2;
|
||
|
||
// Confidence score associated with this box.
|
||
float confidence_score = 3;
|
||
|
||
// Person entity info.
|
||
PersonEntity person_entity = 4;
|
||
}
|
||
|
||
// PPEIdentified box contains the location and the entity info of the PPE.
|
||
message PPEIdentifiedBox {
|
||
// An unique id for this box.
|
||
int64 box_id = 1;
|
||
|
||
// Bounding Box in the normalized coordinates.
|
||
NormalizedBoundingBox normalized_bounding_box = 2;
|
||
|
||
// Confidence score associated with this box.
|
||
float confidence_score = 3;
|
||
|
||
// PPE entity info.
|
||
PPEEntity ppe_entity = 4;
|
||
}
|
||
|
||
// Detected Person contains the detected person and their associated
|
||
// ppes and their protecting information.
|
||
message DetectedPerson {
|
||
// The id of detected person.
|
||
int64 person_id = 1;
|
||
|
||
// The info of detected person identified box.
|
||
PersonIdentifiedBox detected_person_identified_box = 2;
|
||
|
||
// The info of detected person associated ppe identified boxes.
|
||
repeated PPEIdentifiedBox detected_ppe_identified_boxes = 3;
|
||
|
||
// Coverage score for each body part.
|
||
// Coverage score for face.
|
||
optional float face_coverage_score = 4;
|
||
|
||
// Coverage score for eyes.
|
||
optional float eyes_coverage_score = 5;
|
||
|
||
// Coverage score for head.
|
||
optional float head_coverage_score = 6;
|
||
|
||
// Coverage score for hands.
|
||
optional float hands_coverage_score = 7;
|
||
|
||
// Coverage score for body.
|
||
optional float body_coverage_score = 8;
|
||
|
||
// Coverage score for feet.
|
||
optional float feet_coverage_score = 9;
|
||
}
|
||
|
||
// Current timestamp.
|
||
google.protobuf.Timestamp current_time = 1;
|
||
|
||
// A list of DetectedPersons.
|
||
repeated DetectedPerson detected_persons = 2;
|
||
}
|
||
|
||
// Prediction output format for Generic Object Detection.
|
||
message ObjectDetectionPredictionResult {
|
||
// The entity info for annotations from object detection prediction result.
|
||
message Entity {
|
||
// Label id.
|
||
int64 label_id = 1;
|
||
|
||
// Human readable string of the label.
|
||
string label_string = 2;
|
||
}
|
||
|
||
// Identified box contains location and the entity of the object.
|
||
message IdentifiedBox {
|
||
// Bounding Box in the normalized coordinates.
|
||
message NormalizedBoundingBox {
|
||
// Min in x coordinate.
|
||
float xmin = 1;
|
||
|
||
// Min in y coordinate.
|
||
float ymin = 2;
|
||
|
||
// Width of the bounding box.
|
||
float width = 3;
|
||
|
||
// Height of the bounding box.
|
||
float height = 4;
|
||
}
|
||
|
||
// An unique id for this box.
|
||
int64 box_id = 1;
|
||
|
||
// Bounding Box in the normalized coordinates.
|
||
NormalizedBoundingBox normalized_bounding_box = 2;
|
||
|
||
// Confidence score associated with this box.
|
||
float confidence_score = 3;
|
||
|
||
// Entity of this box.
|
||
Entity entity = 4;
|
||
}
|
||
|
||
// Current timestamp.
|
||
google.protobuf.Timestamp current_time = 1;
|
||
|
||
// A list of identified boxes.
|
||
repeated IdentifiedBox identified_boxes = 2;
|
||
}
|
||
|
||
// Prediction output format for Image Object Detection.
|
||
message ImageObjectDetectionPredictionResult {
|
||
// The resource IDs of the AnnotationSpecs that had been identified, ordered
|
||
// by the confidence score descendingly. It is the id segment instead of full
|
||
// resource name.
|
||
repeated int64 ids = 1;
|
||
|
||
// The display names of the AnnotationSpecs that had been identified, order
|
||
// matches the IDs.
|
||
repeated string display_names = 2;
|
||
|
||
// The Model's confidences in correctness of the predicted IDs, higher value
|
||
// means higher confidence. Order matches the Ids.
|
||
repeated float confidences = 3;
|
||
|
||
// Bounding boxes, i.e. the rectangles over the image, that pinpoint
|
||
// the found AnnotationSpecs. Given in order that matches the IDs. Each
|
||
// bounding box is an array of 4 numbers `xMin`, `xMax`, `yMin`, and
|
||
// `yMax`, which represent the extremal coordinates of the box. They are
|
||
// relative to the image size, and the point 0,0 is in the top left
|
||
// of the image.
|
||
repeated google.protobuf.ListValue bboxes = 4;
|
||
}
|
||
|
||
// Prediction output format for Image and Text Classification.
|
||
message ClassificationPredictionResult {
|
||
// The resource IDs of the AnnotationSpecs that had been identified.
|
||
repeated int64 ids = 1;
|
||
|
||
// The display names of the AnnotationSpecs that had been identified, order
|
||
// matches the IDs.
|
||
repeated string display_names = 2;
|
||
|
||
// The Model's confidences in correctness of the predicted IDs, higher value
|
||
// means higher confidence. Order matches the Ids.
|
||
repeated float confidences = 3;
|
||
}
|
||
|
||
// Prediction output format for Image Segmentation.
|
||
message ImageSegmentationPredictionResult {
|
||
// A PNG image where each pixel in the mask represents the category in which
|
||
// the pixel in the original image was predicted to belong to. The size of
|
||
// this image will be the same as the original image. The mapping between the
|
||
// AnntoationSpec and the color can be found in model's metadata. The model
|
||
// will choose the most likely category and if none of the categories reach
|
||
// the confidence threshold, the pixel will be marked as background.
|
||
string category_mask = 1;
|
||
|
||
// A one channel image which is encoded as an 8bit lossless PNG. The size of
|
||
// the image will be the same as the original image. For a specific pixel,
|
||
// darker color means less confidence in correctness of the cateogry in the
|
||
// categoryMask for the corresponding pixel. Black means no confidence and
|
||
// white means complete confidence.
|
||
string confidence_mask = 2;
|
||
}
|
||
|
||
// Prediction output format for Video Action Recognition.
|
||
message VideoActionRecognitionPredictionResult {
|
||
// Each IdentifiedAction is one particular identification of an action
|
||
// specified with the AnnotationSpec id, display_name and the associated
|
||
// confidence score.
|
||
message IdentifiedAction {
|
||
// The resource ID of the AnnotationSpec that had been identified.
|
||
string id = 1;
|
||
|
||
// The display name of the AnnotationSpec that had been identified.
|
||
string display_name = 2;
|
||
|
||
// The Model's confidence in correction of this identification, higher
|
||
// value means higher confidence.
|
||
float confidence = 3;
|
||
}
|
||
|
||
// The beginning, inclusive, of the video's time segment in which the
|
||
// actions have been identified.
|
||
google.protobuf.Timestamp segment_start_time = 1;
|
||
|
||
// The end, inclusive, of the video's time segment in which the actions have
|
||
// been identified. Particularly, if the end is the same as the start, it
|
||
// means the identification happens on a specific video frame.
|
||
google.protobuf.Timestamp segment_end_time = 2;
|
||
|
||
// All of the actions identified in the time range.
|
||
repeated IdentifiedAction actions = 3;
|
||
}
|
||
|
||
// Prediction output format for Video Object Tracking.
|
||
message VideoObjectTrackingPredictionResult {
|
||
// Boundingbox for detected object. I.e. the rectangle over the video frame
|
||
// pinpointing the found AnnotationSpec. The coordinates are relative to the
|
||
// frame size, and the point 0,0 is in the top left of the frame.
|
||
message BoundingBox {
|
||
// The leftmost coordinate of the bounding box.
|
||
float x_min = 1;
|
||
|
||
// The rightmost coordinate of the bounding box.
|
||
float x_max = 2;
|
||
|
||
// The topmost coordinate of the bounding box.
|
||
float y_min = 3;
|
||
|
||
// The bottommost coordinate of the bounding box.
|
||
float y_max = 4;
|
||
}
|
||
|
||
// Each DetectedObject is one particular identification of an object
|
||
// specified with the AnnotationSpec id and display_name, the bounding box,
|
||
// the associated confidence score and the corresponding track_id.
|
||
message DetectedObject {
|
||
// The resource ID of the AnnotationSpec that had been identified.
|
||
string id = 1;
|
||
|
||
// The display name of the AnnotationSpec that had been identified.
|
||
string display_name = 2;
|
||
|
||
// Boundingbox.
|
||
BoundingBox bounding_box = 3;
|
||
|
||
// The Model's confidence in correction of this identification, higher
|
||
// value means higher confidence.
|
||
float confidence = 4;
|
||
|
||
// The same object may be identified on muitiple frames which are typical
|
||
// adjacent. The set of frames where a particular object has been detected
|
||
// form a track. This track_id can be used to trace down all frames for an
|
||
// detected object.
|
||
int64 track_id = 5;
|
||
}
|
||
|
||
// The beginning, inclusive, of the video's time segment in which the
|
||
// current identifications happens.
|
||
google.protobuf.Timestamp segment_start_time = 1;
|
||
|
||
// The end, inclusive, of the video's time segment in which the current
|
||
// identifications happen. Particularly, if the end is the same as the start,
|
||
// it means the identifications happen on a specific video frame.
|
||
google.protobuf.Timestamp segment_end_time = 2;
|
||
|
||
// All of the objects detected in the specified time range.
|
||
repeated DetectedObject objects = 3;
|
||
}
|
||
|
||
// Prediction output format for Video Classification.
|
||
message VideoClassificationPredictionResult {
|
||
// Each IdentifiedClassification is one particular identification of an
|
||
// classification specified with the AnnotationSpec id and display_name,
|
||
// and the associated confidence score.
|
||
message IdentifiedClassification {
|
||
// The resource ID of the AnnotationSpec that had been identified.
|
||
string id = 1;
|
||
|
||
// The display name of the AnnotationSpec that had been identified.
|
||
string display_name = 2;
|
||
|
||
// The Model's confidence in correction of this identification, higher
|
||
// value means higher confidence.
|
||
float confidence = 3;
|
||
}
|
||
|
||
// The beginning, inclusive, of the video's time segment in which the
|
||
// classifications have been identified.
|
||
google.protobuf.Timestamp segment_start_time = 1;
|
||
|
||
// The end, inclusive, of the video's time segment in which the
|
||
// classifications have been identified. Particularly, if the end is the same
|
||
// as the start, it means the identification happens on a specific video
|
||
// frame.
|
||
google.protobuf.Timestamp segment_end_time = 2;
|
||
|
||
// All of the classifications identified in the time range.
|
||
repeated IdentifiedClassification classifications = 3;
|
||
}
|
||
|
||
// The prediction result proto for occupancy counting.
|
||
message OccupancyCountingPredictionResult {
|
||
// The entity info for annotations from occupancy counting operator.
|
||
message Entity {
|
||
// Label id.
|
||
int64 label_id = 1;
|
||
|
||
// Human readable string of the label.
|
||
string label_string = 2;
|
||
}
|
||
|
||
// Identified box contains location and the entity of the object.
|
||
message IdentifiedBox {
|
||
// Bounding Box in the normalized coordinates.
|
||
message NormalizedBoundingBox {
|
||
// Min in x coordinate.
|
||
float xmin = 1;
|
||
|
||
// Min in y coordinate.
|
||
float ymin = 2;
|
||
|
||
// Width of the bounding box.
|
||
float width = 3;
|
||
|
||
// Height of the bounding box.
|
||
float height = 4;
|
||
}
|
||
|
||
// An unique id for this box.
|
||
int64 box_id = 1;
|
||
|
||
// Bounding Box in the normalized coordinates.
|
||
NormalizedBoundingBox normalized_bounding_box = 2;
|
||
|
||
// Confidence score associated with this box.
|
||
float score = 3;
|
||
|
||
// Entity of this box.
|
||
Entity entity = 4;
|
||
|
||
// An unique id to identify a track. It should be consistent across frames.
|
||
// It only exists if tracking is enabled.
|
||
int64 track_id = 5;
|
||
}
|
||
|
||
// The statistics info for annotations from occupancy counting operator.
|
||
message Stats {
|
||
// The object info and instant count for annotations from occupancy counting
|
||
// operator.
|
||
message ObjectCount {
|
||
// Entity of this object.
|
||
Entity entity = 1;
|
||
|
||
// Count of the object.
|
||
int32 count = 2;
|
||
}
|
||
|
||
// The object info and accumulated count for annotations from occupancy
|
||
// counting operator.
|
||
message AccumulatedObjectCount {
|
||
// The start time of the accumulated count.
|
||
google.protobuf.Timestamp start_time = 1;
|
||
|
||
// The object count for the accumulated count.
|
||
ObjectCount object_count = 2;
|
||
}
|
||
|
||
// Message for Crossing line count.
|
||
message CrossingLineCount {
|
||
// Line annotation from the user.
|
||
StreamAnnotation annotation = 1;
|
||
|
||
// The direction that follows the right hand rule.
|
||
repeated ObjectCount positive_direction_counts = 2;
|
||
|
||
// The direction that is opposite to the right hand rule.
|
||
repeated ObjectCount negative_direction_counts = 3;
|
||
|
||
// The accumulated positive count.
|
||
repeated AccumulatedObjectCount accumulated_positive_direction_counts = 4;
|
||
|
||
// The accumulated negative count.
|
||
repeated AccumulatedObjectCount accumulated_negative_direction_counts = 5;
|
||
}
|
||
|
||
// Message for the active zone count.
|
||
message ActiveZoneCount {
|
||
// Active zone annotation from the user.
|
||
StreamAnnotation annotation = 1;
|
||
|
||
// Counts in the zone.
|
||
repeated ObjectCount counts = 2;
|
||
}
|
||
|
||
// Counts of the full frame.
|
||
repeated ObjectCount full_frame_count = 1;
|
||
|
||
// Crossing line counts.
|
||
repeated CrossingLineCount crossing_line_counts = 2;
|
||
|
||
// Active zone counts.
|
||
repeated ActiveZoneCount active_zone_counts = 3;
|
||
}
|
||
|
||
// The track info for annotations from occupancy counting operator.
|
||
message TrackInfo {
|
||
// An unique id to identify a track. It should be consistent across frames.
|
||
string track_id = 1;
|
||
|
||
// Start timestamp of this track.
|
||
google.protobuf.Timestamp start_time = 2;
|
||
}
|
||
|
||
// The dwell time info for annotations from occupancy counting operator.
|
||
message DwellTimeInfo {
|
||
// An unique id to identify a track. It should be consistent across frames.
|
||
string track_id = 1;
|
||
|
||
// The unique id for the zone in which the object is dwelling/waiting.
|
||
string zone_id = 2;
|
||
|
||
// The beginning time when a dwelling object has been identified in a zone.
|
||
google.protobuf.Timestamp dwell_start_time = 3;
|
||
|
||
// The end time when a dwelling object has exited in a zone.
|
||
google.protobuf.Timestamp dwell_end_time = 4;
|
||
}
|
||
|
||
// Current timestamp.
|
||
google.protobuf.Timestamp current_time = 1;
|
||
|
||
// A list of identified boxes.
|
||
repeated IdentifiedBox identified_boxes = 2;
|
||
|
||
// Detection statistics.
|
||
Stats stats = 3;
|
||
|
||
// Track related information. All the tracks that are live at this timestamp.
|
||
// It only exists if tracking is enabled.
|
||
repeated TrackInfo track_info = 4;
|
||
|
||
// Dwell time related information. All the tracks that are live in a given
|
||
// zone with a start and end dwell time timestamp
|
||
repeated DwellTimeInfo dwell_time_info = 5;
|
||
}
|
||
|
||
// message about annotations about Vision AI stream resource.
|
||
message StreamAnnotation {
|
||
oneof annotation_payload {
|
||
// Annotation for type ACTIVE_ZONE
|
||
NormalizedPolygon active_zone = 5;
|
||
|
||
// Annotation for type CROSSING_LINE
|
||
NormalizedPolyline crossing_line = 6;
|
||
}
|
||
|
||
// ID of the annotation. It must be unique when used in the certain context.
|
||
// For example, all the annotations to one input streams of a Vision AI
|
||
// application.
|
||
string id = 1;
|
||
|
||
// User-friendly name for the annotation.
|
||
string display_name = 2;
|
||
|
||
// The Vision AI stream resource name.
|
||
string source_stream = 3;
|
||
|
||
// The actual type of Annotation.
|
||
StreamAnnotationType type = 4;
|
||
}
|
||
|
||
// A wrapper of repeated StreamAnnotation.
|
||
message StreamAnnotations {
|
||
// Multiple annotations.
|
||
repeated StreamAnnotation stream_annotations = 1;
|
||
}
|
||
|
||
// Normalized Polygon.
|
||
message NormalizedPolygon {
|
||
// The bounding polygon normalized vertices. Top left corner of the image
|
||
// will be [0, 0].
|
||
repeated NormalizedVertex normalized_vertices = 1;
|
||
}
|
||
|
||
// Normalized Pplyline, which represents a curve consisting of connected
|
||
// straight-line segments.
|
||
message NormalizedPolyline {
|
||
// A sequence of vertices connected by straight lines.
|
||
repeated NormalizedVertex normalized_vertices = 1;
|
||
}
|
||
|
||
// A vertex represents a 2D point in the image.
|
||
// NOTE: the normalized vertex coordinates are relative to the original image
|
||
// and range from 0 to 1.
|
||
message NormalizedVertex {
|
||
// X coordinate.
|
||
float x = 1;
|
||
|
||
// Y coordinate.
|
||
float y = 2;
|
||
}
|
||
|
||
// Message of essential metadata of App Platform.
|
||
// This message is usually attached to a certain processor output annotation for
|
||
// customer to identify the source of the data.
|
||
message AppPlatformMetadata {
|
||
// The application resource name.
|
||
string application = 1;
|
||
|
||
// The instance resource id. Instance is the nested resource of application
|
||
// under collection 'instances'.
|
||
string instance_id = 2;
|
||
|
||
// The node name of the application graph.
|
||
string node = 3;
|
||
|
||
// The referred processor resource name of the application node.
|
||
string processor = 4;
|
||
}
|
||
|
||
// For any cloud function based customer processing logic, customer's cloud
|
||
// function is expected to receive AppPlatformCloudFunctionRequest as request
|
||
// and send back AppPlatformCloudFunctionResponse as response.
|
||
// Message of request from AppPlatform to Cloud Function.
|
||
message AppPlatformCloudFunctionRequest {
|
||
// A general annotation message that uses struct format to represent different
|
||
// concrete annotation protobufs.
|
||
message StructedInputAnnotation {
|
||
// The ingestion time of the current annotation.
|
||
int64 ingestion_time_micros = 1;
|
||
|
||
// The struct format of the actual annotation.
|
||
google.protobuf.Struct annotation = 2;
|
||
}
|
||
|
||
// The metadata of the AppPlatform for customer to identify the source of the
|
||
// payload.
|
||
AppPlatformMetadata app_platform_metadata = 1;
|
||
|
||
// The actual annotations to be processed by the customized Cloud Function.
|
||
repeated StructedInputAnnotation annotations = 2;
|
||
}
|
||
|
||
// Message of the response from customer's Cloud Function to AppPlatform.
|
||
message AppPlatformCloudFunctionResponse {
|
||
// A general annotation message that uses struct format to represent different
|
||
// concrete annotation protobufs.
|
||
message StructedOutputAnnotation {
|
||
// The struct format of the actual annotation.
|
||
google.protobuf.Struct annotation = 1;
|
||
}
|
||
|
||
// The modified annotations that is returned back to AppPlatform.
|
||
// If the annotations fields are empty, then those annotations will be dropped
|
||
// by AppPlatform.
|
||
repeated StructedOutputAnnotation annotations = 2;
|
||
|
||
// If set to true, AppPlatform will use original annotations instead of
|
||
// dropping them, even if it is empty in the annotations filed.
|
||
bool annotation_passthrough = 3;
|
||
|
||
// The event notifications that is returned back to AppPlatform. Typically it
|
||
// will then be configured to be consumed/forwared to a operator that handles
|
||
// events, such as Pub/Sub operator.
|
||
repeated AppPlatformEventBody events = 4;
|
||
}
|
||
|
||
// Message of content of appPlatform event
|
||
message AppPlatformEventBody {
|
||
// Human readable string of the event like "There are more than 6 people in
|
||
// the scene". or "Shelf is empty!".
|
||
string event_message = 1;
|
||
|
||
// For the case of Pub/Sub, it will be stored in the message attributes.
|
||
// pubsub.proto
|
||
google.protobuf.Struct payload = 2;
|
||
|
||
// User defined Event Id, used to classify event, within a delivery interval,
|
||
// events from the same application instance with the same id will be
|
||
// de-duplicated & only first one will be sent out. Empty event_id will be
|
||
// treated as "".
|
||
string event_id = 3;
|
||
}
|