-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New API preview version for ACS Email Inline Attachment feature #29699
Merged
natekimball-msft
merged 16 commits into
Azure:main
from
natekimball-msft:natekimball/2024-07-01-preview
Aug 9, 2024
Merged
Changes from 13 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
bb5edbc
adding new API version for inline attachment support
natekimball-msft 1518d1a
Updating readme
natekimball-msft 936f4ca
Updating sample api versions
natekimball-msft eefe77d
Updating readme
natekimball-msft 4397af6
Merge branch 'main' into natekimball/2024-07-01-preview
natekimball-msft 87e4921
fixing new package tag
natekimball-msft d941a1d
Merge branch 'natekimball/2024-07-01-preview' of https://github.com/n…
natekimball-msft fa6e7aa
updating examples with string values
natekimball-msft a67e12a
updating sendemail examples
natekimball-msft b9dbabf
Merge branch 'main' into natekimball/2024-07-01-preview
natekimball-msft 3ff8983
Merge branch 'main' into natekimball/2024-07-01-preview
natekimball-msft a5076d2
Merge branch 'main' into natekimball/2024-07-01-preview
natekimball-msft 1a44c19
Merge branch 'main' into natekimball/2024-07-01-preview
natekimball-msft 81fbe60
Merge branch 'main' into natekimball/2024-07-01-preview
natekimball-msft 12d5a6d
Merge branch 'main' into natekimball/2024-07-01-preview
natekimball-msft e64ad69
Merge branch 'main' into natekimball/2024-07-01-preview
natekimball-msft File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
390 changes: 390 additions & 0 deletions
390
...communication/data-plane/Email/preview/2024-07-01-preview/CommunicationServicesEmail.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,390 @@ | ||
{ | ||
"swagger": "2.0", | ||
"info": { | ||
"title": "EmailClient", | ||
"description": "Azure Communication Email Service", | ||
"version": "2024-07-01-preview" | ||
}, | ||
"paths": { | ||
"/emails/operations/{operationId}": { | ||
"get": { | ||
"tags": [ | ||
"EmailGetSendResult" | ||
], | ||
"summary": "Gets the status of the email send operation.", | ||
"operationId": "Email_GetSendResult", | ||
"produces": [ | ||
"application/json" | ||
], | ||
"parameters": [ | ||
{ | ||
"in": "path", | ||
"name": "operationId", | ||
"description": "ID of the long running operation (GUID) returned from a previous call to send email", | ||
"required": true, | ||
"type": "string" | ||
}, | ||
{ | ||
"$ref": "#/parameters/ApiVersionParameter" | ||
} | ||
], | ||
"responses": { | ||
"default": { | ||
"description": "Error", | ||
"headers": { | ||
"x-ms-error-code": { | ||
"description": "Error code - this will be the same as the code in the error property in the response body.", | ||
"type": "string" | ||
} | ||
}, | ||
"schema": { | ||
"$ref": "../../../../../common-types/data-plane/v1/types.json#/definitions/ErrorResponse" | ||
} | ||
}, | ||
"200": { | ||
"description": "Message status was successfully retrieved.", | ||
"headers": { | ||
"retry-after": { | ||
"description": "This header will only be present when the status is a non-terminal status. It indicates the minimum amount of time in seconds to wait before polling for operation status again.", | ||
"type": "integer", | ||
"format": "int32" | ||
} | ||
}, | ||
"schema": { | ||
"$ref": "#/definitions/EmailSendResult" | ||
} | ||
} | ||
}, | ||
"x-ms-examples": { | ||
"Get Message Status FailedTerminalStatus": { | ||
"$ref": "./examples/GetOperationStatusReturnsFailedTerminalStatus.json" | ||
}, | ||
"Get Message Status NonTerminalStatus": { | ||
"$ref": "./examples/GetOperationStatusReturnsNonTerminalStatus.json" | ||
}, | ||
"Get Message Status SuccessTerminalStatus": { | ||
"$ref": "./examples/GetOperationStatusReturnsSuccessTerminalStatus.json" | ||
} | ||
} | ||
} | ||
}, | ||
"/emails:send": { | ||
"post": { | ||
"tags": [ | ||
"EmailSend" | ||
], | ||
"summary": "Queues an email message to be sent to one or more recipients", | ||
"operationId": "Email_Send", | ||
"consumes": [ | ||
"application/json" | ||
], | ||
"produces": [ | ||
"application/json" | ||
], | ||
"parameters": [ | ||
{ | ||
"in": "header", | ||
"name": "Operation-Id", | ||
"description": "This is the ID provided by the customer to identify the long running operation. If an ID is not provided by the customer, the service will generate one.", | ||
"type": "string", | ||
"required": false, | ||
"format": "uuid" | ||
}, | ||
{ | ||
"in": "header", | ||
"name": "x-ms-client-request-id", | ||
"description": "Tracking ID sent with the request to help with debugging.", | ||
"type": "string", | ||
"required": false, | ||
"format": "uuid", | ||
"x-ms-client-name": "ClientRequestId" | ||
}, | ||
{ | ||
"$ref": "#/parameters/ApiVersionParameter" | ||
}, | ||
{ | ||
"in": "body", | ||
"name": "emailMessage", | ||
"description": "Message payload for sending an email", | ||
"required": true, | ||
"x-ms-client-name": "message", | ||
"schema": { | ||
"$ref": "#/definitions/EmailMessage" | ||
} | ||
} | ||
], | ||
"responses": { | ||
"default": { | ||
"description": "Error", | ||
"headers": { | ||
"x-ms-error-code": { | ||
"description": "Error code - this will be the same as the code in the error property in the response body.", | ||
"type": "string" | ||
} | ||
}, | ||
"schema": { | ||
"$ref": "../../../../../common-types/data-plane/v1/types.json#/definitions/ErrorResponse" | ||
} | ||
}, | ||
"202": { | ||
"description": "The service has accepted the request and will start processing the message later. It will return 'Accepted' immediately and include an 'Operation-Location' header. Client side should further query the operation/message status using the URL specified in 'Operation-Location' header. Once the send operation has succeeded, you can get additional status about email delivery through either Azure Monitor or Event Grid events (for events reference, please refer to: https://learn.microsoft.com/en-us/azure/event-grid/communication-services-email-events)", | ||
"headers": { | ||
"Operation-Location": { | ||
"description": "Location url of where to poll the status of this operation from.", | ||
"type": "string" | ||
}, | ||
"retry-after": { | ||
"description": "This header will only be present when the operation status is a non-terminal status. It indicates the minimum amount of time in seconds to wait before polling for operation status again.", | ||
"type": "integer", | ||
"format": "int32" | ||
} | ||
}, | ||
"schema": { | ||
"$ref": "#/definitions/EmailSendResult" | ||
} | ||
} | ||
}, | ||
"x-ms-long-running-operation": true, | ||
"x-ms-long-running-operation-options": { | ||
"final-state-via": "azure-async-operation" | ||
}, | ||
"x-ms-examples": { | ||
"Send Email": { | ||
"$ref": "./examples/SendEmail.json" | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
"definitions": { | ||
"EmailSendResult": { | ||
"description": "Status of the long running operation", | ||
"required": [ | ||
"id", | ||
"status" | ||
], | ||
"type": "object", | ||
"properties": { | ||
"id": { | ||
"description": "The unique id of the operation. Use a UUID.", | ||
"type": "string", | ||
"example": "8540c0de-899f-5cce-acb5-3ec493af3800" | ||
}, | ||
"status": { | ||
"description": "Status of operation.", | ||
"enum": [ | ||
"NotStarted", | ||
"Running", | ||
"Succeeded", | ||
"Failed", | ||
"Canceled" | ||
], | ||
"type": "string", | ||
"x-ms-enum": { | ||
"name": "EmailSendStatus", | ||
"modelAsString": true | ||
} | ||
}, | ||
"error": { | ||
"description": "Error details when status is a non-success terminal state.", | ||
"$ref": "../../../../../common-types/data-plane/v1/types.json#/definitions/ErrorDetail" | ||
} | ||
} | ||
}, | ||
"EmailMessage": { | ||
"description": "Message payload for sending an email", | ||
"required": [ | ||
"senderAddress", | ||
"content", | ||
"recipients" | ||
], | ||
"type": "object", | ||
"properties": { | ||
"headers": { | ||
"description": "Custom email headers to be passed.", | ||
"type": "object", | ||
"additionalProperties": { | ||
"type": "string" | ||
} | ||
}, | ||
"senderAddress": { | ||
"description": "Sender email address from a verified domain.", | ||
"type": "string", | ||
"example": "[email protected]" | ||
}, | ||
"content": { | ||
"description": "Email content to be sent.", | ||
"$ref": "#/definitions/EmailContent" | ||
}, | ||
"recipients": { | ||
"description": "Recipients for the email.", | ||
"$ref": "#/definitions/EmailRecipients" | ||
}, | ||
"attachments": { | ||
"description": "List of attachments. Please note that we limit the total size of an email request (which includes both regular and inline attachments) to 10MB.", | ||
"type": "array", | ||
"items": { | ||
"$ref": "#/definitions/EmailAttachment" | ||
} | ||
}, | ||
"replyTo": { | ||
"description": "Email addresses where recipients' replies will be sent to.", | ||
"type": "array", | ||
"items": { | ||
"$ref": "#/definitions/EmailAddress" | ||
} | ||
}, | ||
"userEngagementTrackingDisabled": { | ||
"description": "Indicates whether user engagement tracking should be disabled for this request if the resource-level user engagement tracking setting was already enabled in the control plane.", | ||
"type": "boolean" | ||
} | ||
} | ||
}, | ||
"EmailAddress": { | ||
"description": "An object representing the email address and its display name", | ||
"type": "object", | ||
"required": [ | ||
"address" | ||
], | ||
"properties": { | ||
"address": { | ||
"description": "Email address.", | ||
"type": "string", | ||
"example": "[email protected]" | ||
}, | ||
"displayName": { | ||
"description": "Email display name.", | ||
"type": "string", | ||
"example": "abc" | ||
} | ||
} | ||
}, | ||
"EmailContent": { | ||
"description": "Content of the email.", | ||
"type": "object", | ||
"required": [ | ||
"subject" | ||
], | ||
"properties": { | ||
"subject": { | ||
"description": "Subject of the email message", | ||
"type": "string", | ||
"example": "An exciting offer especially for you!" | ||
}, | ||
"plainText": { | ||
"description": "Plain text version of the email message.", | ||
"type": "string", | ||
"example": "This exciting offer was created especially for you, our most loyal customer." | ||
}, | ||
"html": { | ||
"description": "Html version of the email message.", | ||
"type": "string", | ||
"example": "<html><head><title>Exciting offer!</title></head><body><h1>This exciting offer was created especially for you, our most loyal customer.</h1></body></html>" | ||
} | ||
} | ||
}, | ||
"EmailAttachment": { | ||
"description": "Attachment to the email.", | ||
"type": "object", | ||
"required": [ | ||
"name", | ||
"contentType", | ||
"contentInBase64" | ||
], | ||
"properties": { | ||
"name": { | ||
"description": "Name of the attachment", | ||
"type": "string", | ||
"example": "attachment.pdf" | ||
}, | ||
"contentType": { | ||
"description": "MIME type of the content being attached.", | ||
"type": "string", | ||
"example": "text/plain" | ||
}, | ||
"contentInBase64": { | ||
"description": "Base64 encoded contents of the attachment", | ||
"type": "string", | ||
"format": "byte", | ||
"example": "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ=" | ||
}, | ||
"contentId": { | ||
"description": "Unique identifier (CID) to reference an inline attachment.", | ||
"type": "string", | ||
"example": "inline_image_id" | ||
} | ||
} | ||
}, | ||
"EmailRecipients": { | ||
"description": "Recipients of the email", | ||
"type": "object", | ||
"required": [ | ||
"to" | ||
], | ||
"properties": { | ||
"to": { | ||
"description": "Email To recipients", | ||
"type": "array", | ||
"items": { | ||
"$ref": "#/definitions/EmailAddress" | ||
} | ||
}, | ||
"cc": { | ||
"description": "Email CC recipients", | ||
"type": "array", | ||
"x-ms-client-name": "CC", | ||
"items": { | ||
"$ref": "#/definitions/EmailAddress" | ||
} | ||
}, | ||
"bcc": { | ||
"description": "Email BCC recipients", | ||
"type": "array", | ||
"x-ms-client-name": "BCC", | ||
"items": { | ||
"$ref": "#/definitions/EmailAddress" | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
"parameters": { | ||
"ApiVersionParameter": { | ||
"in": "query", | ||
"name": "api-version", | ||
"description": "Version of API to invoke.", | ||
"required": true, | ||
"type": "string", | ||
"x-ms-parameter-location": "client" | ||
} | ||
}, | ||
"securityDefinitions": { | ||
"Authorization": { | ||
"type": "apiKey", | ||
"name": "Authorization", | ||
"in": "header", | ||
"description": "An authentication string containing a signature generated using HMAC-SHA256 scheme." | ||
} | ||
}, | ||
"security": [ | ||
{ | ||
"Authorization": [] | ||
} | ||
], | ||
"x-ms-parameterized-host": { | ||
"hostTemplate": "{endpoint}", | ||
"useSchemePrefix": false, | ||
"parameters": [ | ||
{ | ||
"name": "endpoint", | ||
"description": "The communication resource, for example https://my-resource.communication.azure.com", | ||
"required": true, | ||
"type": "string", | ||
"format": "url", | ||
"in": "path", | ||
"x-ms-skip-url-encoding": true, | ||
"x-ms-parameter-location": "client" | ||
} | ||
] | ||
} | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure this should be
integer
instead ofstring
? The HTTP spec seems to requirestring
to support date-based values.https://www.rfc-editor.org/rfc/rfc9110#field.retry-after
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can check the historical reasoning of this choice with the team and get back to you. That being said, I have a couple of follow up questions here:
If it's the spec that is incorrect, I'm curious as to why these errors are only manifesting in our builds now, despite using the same version of autorest? It appears that it wasn't caught in our team's previous PRs. Examples: Add base64 formatting to contentInBase64 property by kagbakpem · Pull Request #24617 · Azure/azure-rest-api-specs (github.com), Azure Communication Services Email API for GA by apattath · Pull Request #22979 · Azure/azure-rest-api-specs (github.com).
If I make changes to the older specs retroactively, are there any considerations here with introducing breaking changes? It seems like in our most recent PR, a tag was added to approve a breaking change (unsure if it was for the same reason). Is that appropriate here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For breaking changes, we regard the service behavior as the "source of truth". If the API definition changes to more accurately describe the service behavior, we allow this and actually encourage it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The check also failed in PR 22979. For PR 24617, the check was bypassed using label
Approved-BreakingChange
, and we no longer have the build log, but I suspect it also failed with the same error.I think the first question here, is how should
retry-after
be expressed in services, specs, and examples? Always astring
, or can each service decide betweenstring
andinteger
?For instance, even though the HTTP spec allows string dates, if a service has decided it will ever only send integer seconds in the header, would it be appropriate for the service and spec to use
integer
?@mikekistler: Do you know the answer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We always want the value of
retry-after
to be "delay-seconds" and not a date, and RFC 7231 says:So
integer
is the appropriate type for this header value.Furthermore, it is common that string and integer values are serialized in headers in the same way, so it might be possible to change the API description from
type: string
totype: integer
in a non-breaking way (i.e. without changing the behavior of the service). As long as the service does not wrap the value in quotes, e.g.but most services will not do this so it might be fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mikekistler: Can you elaborate on this? Is this an Azure guideline above the HTTP spec (which allows either)? Why wouldn't we want to give services the option to send either seconds or a date?
I understand it's valid for a service to choose to always send
delay-seconds
, and we may have reasons to prefer it (e.g. performance generating the response). But putting this restriction in the spec seems like overkill to me.The guidance was changed recently in this PR (microsoft/api-guidelines#517), but even here it says SHOULD (not MUST) use delay-seconds:
Though it does use MUST in another place:
One more question, is the guidance to always use
delay-seconds
specific to 200 responses, or should it also apply to 202 responses? The spec in this PR has a retry-after example for both response codes.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Retry-after
should always specifydelay-seconds
in any response.