syntax = "proto3"; package notify.v1; import "buf/validate/validate.proto"; import "google/protobuf/timestamp.proto"; import "notify/v1/types.proto"; message SendNotificationRequest { Payload payload = 1 [(buf.validate.field).required = true]; Resource resource = 2 [(buf.validate.field).required = true]; } // SendAttachmentResponse is sent when message is successful. message SendNotificationResponse { // notification_id is the id of the notification. // // Guaranteed to be unique even on distributed environment. // // notification_id can be used in `SendAttachment` rpc to // attach binary data to the message. string notification_id = 1; // upload_url is https url to upload the attachment. The endpoint // already has the notification_id embedded in the url so attachments // send to this url are automatically associated with the notification id. // // Use this url if the `SendAttachment` rpc is hard to implement or unspported. // // The endpoint requires Content-Type header to be set // and the behavior of the endpoint depends on the Content-Type // value. // // If Content-Type is `multipart/form-data`, the endpoint will // each part of the form must come with Content-Disposition header, // and in that header,`filename` (without asterisk (*)) field must be set. // // See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#as_a_header_for_a_multipart_body // // If Content-Type is not `multipart/form-data`, the request must // contain header `X-File-Name`. // // Filenames are sanitized and unsupported characters are replaced with underscores `_`. // // Each filenames must be unique. Not doing so will result in undefined behavior. string upload_url = 2; } message Payload { // message is the content of the notification. // // message should be short and concise since they are // intended as forefront information. // // details should go to the `details` field. string message = 1 [(buf.validate.field).required = true]; // level is the severity of the message. // // current implementation treats LEVEL_UNSPECIFIED as LEVEL_INFO, // but it's recommended to set the level explicitly to avoid // surprises in the future. Level level = 2; // code is the error code of the message. string code = 3; // details adds context to the message. // // like invalid inputs, // request payloads, backend response, etc. // // Anything that can enrich why this message // appears will help. // // DO NOT INCLUDE BINARIES LIKE IMAGES, PDFS, DOCS, IN // THIS PAYLOAD. USE `SendAttachment` rpc // to attach binary values instead since they are designed // for streaming. Server and Client RAM // can be eaten alive if you ignore this predicament since GRPC // handles via whole messages. oneof details { // Sends JSON as details. // // In the report page, this will be rendered with JSONGrid. bytes d_json = 4; // Sends text as details. // // Markdown syntax is supported and markdown will be rendered // on the report page. string d_text = 5; } // error is the error message that is sent. oneof error { // sends error details as JSON. // // like details, do not include binaries in this field. // // In the report page, this will be rendered with JSONGrid. bytes e_json = 6; // sends error details as text. // // Markdown syntax is supported and markdown will be rendered // on the report page. string e_text = 7; } // id is the unique identifier of the message. // // message with same id is considered as the same message // even if the content is different. string id = 8; // trace_id is the trace id of the message. // // trace_id is used to trace the message across services. // // Leave this empty/unset if no traces are available. string trace_id = 9; // span_id is the span id of the message. // // span_id is used to trace the message within the service/scope. // // Leave this empty/unset if no spans are available. string span_id = 10; // timestamp is the timestamp of the message. // // if unset or zero, the server will use the current time. google.protobuf.Timestamp timestamp = 11; } // Resource contains information about who is sending the notification. // // Resourcd values be the same as long the same instance is up. // // for frontends, it's recommended to treat Resource like a user session data. // // for backends, resource refers to the service that is sending the notification. message Resource { // The name of the service that is sending the notification. // // This is used to identify the service that is sending the notification. // // The value of name should be related to the product or service. // e.g. `sbn`, `superapp`, `hyperion`, `robo`. // // `name`, `type`, and `environment` combination are used to select which channel the // discord notification is sent. string name = 1 [(buf.validate.field).string.min_len = 1]; // type refers to the type of the service provided. // // e.g. `frontend`, `cron-job`, `consumer` // // `name`, `type`, and `environment` combination are used to select which channel the // discord notification is sent. string type = 2 [(buf.validate.field).string.min_len = 1]; // environment refers to the environment of the service. // // Environment must be one of the following: // // - ENVIRONMENT_DEVELOPMENT // - ENVIRONMENT_STAGING // - ENVIRONMENT_PRODUCTION // - ENVIRONMENT_TESTING // // `name`, `type`, and `environment` combination are used to select which channel the // discord notification is sent. Environment environment = 3 [(buf.validate.field).enum = { in: [ 1, // ENVIRONMENT_DEVELOPMENT 2, // ENVIRONMENT_STAGING 3, // ENVIRONMENT_PRODUCTION 4 // ENVIRONMENT_TESTING ] }]; optional string version = 4; // domain specifies whose message this belongs to. // // It's very recommended for this service to be set. // // This will help zen to categorize messages when building // reports. ServiceDomain domain = 5; // attributes are informations that enriches the service. // // like Session ID, Region, User-Agent, etc. map attributes = 6; } enum ServiceDomain { SERVICE_DOMAIN_UNSPECIFIED = 0; SERVICE_DOMAIN_FRONTEND = 1; SERVICE_DOMAIN_BACKEND = 2; }