Skip to content

Commit e3c2c66

Browse files
author
Chris Ballinger
committed
Initial support for Retention Messaging API
1 parent 6f73956 commit e3c2c66

12 files changed

+532
-1
lines changed

appstoreserverlibrary/api_client.py

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
from .models.TransactionHistoryRequest import TransactionHistoryRequest
3333
from .models.TransactionInfoResponse import TransactionInfoResponse
3434
from .models.UpdateAppAccountTokenRequest import UpdateAppAccountTokenRequest
35+
from .models.UploadMessageRequestBody import UploadMessageRequestBody
36+
from .models.GetMessageListResponse import GetMessageListResponse
3537

3638
T = TypeVar('T')
3739

@@ -457,10 +459,53 @@ class APIError(IntEnum):
457459
GENERAL_INTERNAL_RETRYABLE = 5000001
458460
"""
459461
An error response that indicates an unknown error occurred, but you can try again.
460-
462+
461463
https://developer.apple.com/documentation/appstoreserverapi/generalinternalretryableerror
462464
"""
463465

466+
# Retention Messaging specific errors
467+
HEADER_TOO_LONG_ERROR = 4000101
468+
"""
469+
An error that indicates the message header exceeds 66 characters.
470+
471+
https://developer.apple.com/documentation/retentionmessaging/headertoolongerror
472+
"""
473+
474+
BODY_TOO_LONG_ERROR = 4000102
475+
"""
476+
An error that indicates the message body exceeds 144 characters.
477+
478+
https://developer.apple.com/documentation/retentionmessaging/bodytoolongerror
479+
"""
480+
481+
ALT_TEXT_TOO_LONG_ERROR = 4000103
482+
"""
483+
An error that indicates the alt text exceeds 150 characters.
484+
485+
https://developer.apple.com/documentation/retentionmessaging/alttexttoolongerror
486+
"""
487+
488+
MAXIMUM_NUMBER_OF_MESSAGES_REACHED_ERROR = 4030001
489+
"""
490+
An error that indicates the maximum number of retention messages (2000) has been reached.
491+
492+
https://developer.apple.com/documentation/retentionmessaging/maximumnumberofmessagesreachederror
493+
"""
494+
495+
MESSAGE_NOT_FOUND_ERROR = 4040001
496+
"""
497+
An error that indicates the specified message was not found.
498+
499+
https://developer.apple.com/documentation/retentionmessaging/messagenotfounderror
500+
"""
501+
502+
MESSAGE_ALREADY_EXISTS_ERROR = 4090001
503+
"""
504+
An error that indicates the message identifier already exists.
505+
506+
https://developer.apple.com/documentation/retentionmessaging/messagealreadyexistserror
507+
"""
508+
464509

465510
@define
466511
class APIException(Exception):
@@ -758,6 +803,37 @@ def set_app_account_token(self, original_transaction_id: str, update_app_account
758803
"""
759804
self._make_request("/inApps/v1/transactions/" + original_transaction_id + "/appAccountToken", "PUT", {}, update_app_account_token_request, None)
760805

806+
def upload_retention_message(self, message_identifier: str, retention_message_request: UploadMessageRequestBody) -> None:
807+
"""
808+
Upload a message to use for retention messaging.
809+
https://developer.apple.com/documentation/retentionmessaging/upload-message
810+
811+
:param message_identifier: A UUID you provide to uniquely identify the message you upload.
812+
:param retention_message_request: The request body containing the message text and optional image reference.
813+
:raises APIException: If a response was returned indicating the request could not be processed
814+
"""
815+
self._make_request("/inApps/v1/messaging/message/" + message_identifier, "PUT", {}, retention_message_request, None)
816+
817+
def get_retention_message_list(self) -> GetMessageListResponse:
818+
"""
819+
Get the message identifier and state of all uploaded messages.
820+
https://developer.apple.com/documentation/retentionmessaging/get-message-list
821+
822+
:return: A response that contains status information for all messages.
823+
:raises APIException: If a response was returned indicating the request could not be processed
824+
"""
825+
return self._make_request("/inApps/v1/messaging/message/list", "GET", {}, None, GetMessageListResponse)
826+
827+
def delete_retention_message(self, message_identifier: str) -> None:
828+
"""
829+
Delete a previously uploaded message.
830+
https://developer.apple.com/documentation/retentionmessaging/delete-message
831+
832+
:param message_identifier: The identifier of the message to delete.
833+
:raises APIException: If a response was returned indicating the request could not be processed
834+
"""
835+
self._make_request("/inApps/v1/messaging/message/" + message_identifier, "DELETE", {}, None, None)
836+
761837
class AsyncAppStoreServerAPIClient(BaseAppStoreServerAPIClient):
762838
def __init__(self, signing_key: bytes, key_id: str, issuer_id: str, bundle_id: str, environment: Environment):
763839
super().__init__(signing_key=signing_key, key_id=key_id, issuer_id=issuer_id, bundle_id=bundle_id, environment=environment)
@@ -970,3 +1046,34 @@ async def set_app_account_token(self, original_transaction_id: str, update_app_a
9701046
:raises APIException: If a response was returned indicating the request could not be processed
9711047
"""
9721048
await self._make_request("/inApps/v1/transactions/" + original_transaction_id + "/appAccountToken", "PUT", {}, update_app_account_token_request, None)
1049+
1050+
async def upload_retention_message(self, message_identifier: str, retention_message_request: UploadMessageRequestBody) -> None:
1051+
"""
1052+
Upload a message to use for retention messaging.
1053+
https://developer.apple.com/documentation/retentionmessaging/upload-message
1054+
1055+
:param message_identifier: A UUID you provide to uniquely identify the message you upload.
1056+
:param retention_message_request: The request body containing the message text and optional image reference.
1057+
:raises APIException: If a response was returned indicating the request could not be processed
1058+
"""
1059+
await self._make_request("/inApps/v1/messaging/message/" + message_identifier, "PUT", {}, retention_message_request, None)
1060+
1061+
async def get_retention_message_list(self) -> GetMessageListResponse:
1062+
"""
1063+
Get the message identifier and state of all uploaded messages.
1064+
https://developer.apple.com/documentation/retentionmessaging/get-message-list
1065+
1066+
:return: A response that contains status information for all messages.
1067+
:raises APIException: If a response was returned indicating the request could not be processed
1068+
"""
1069+
return await self._make_request("/inApps/v1/messaging/message/list", "GET", {}, None, GetMessageListResponse)
1070+
1071+
async def delete_retention_message(self, message_identifier: str) -> None:
1072+
"""
1073+
Delete a previously uploaded message.
1074+
https://developer.apple.com/documentation/retentionmessaging/delete-message
1075+
1076+
:param message_identifier: The identifier of the message to delete.
1077+
:raises APIException: If a response was returned indicating the request could not be processed
1078+
"""
1079+
await self._make_request("/inApps/v1/messaging/message/" + message_identifier, "DELETE", {}, None, None)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright (c) 2023 Apple Inc. Licensed under MIT License.
2+
3+
from typing import Optional, List
4+
from attr import define
5+
import attr
6+
from .GetMessageListResponseItem import GetMessageListResponseItem
7+
8+
@define
9+
class GetMessageListResponse:
10+
"""
11+
A response that contains status information for all messages.
12+
13+
https://developer.apple.com/documentation/retentionmessaging/getmessagelistresponse
14+
"""
15+
16+
messageIdentifiers: Optional[List[GetMessageListResponseItem]] = attr.ib(default=None)
17+
"""
18+
An array of all message identifiers and their message states.
19+
20+
https://developer.apple.com/documentation/retentionmessaging/getmessagelistresponseitem
21+
"""
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Copyright (c) 2023 Apple Inc. Licensed under MIT License.
2+
3+
from typing import Optional
4+
from attr import define
5+
import attr
6+
from .RetentionMessageState import RetentionMessageState
7+
from .LibraryUtility import AttrsRawValueAware
8+
9+
@define
10+
class GetMessageListResponseItem(AttrsRawValueAware):
11+
"""
12+
A message identifier and status information for a message.
13+
14+
https://developer.apple.com/documentation/retentionmessaging/getmessagelistresponseitem
15+
"""
16+
17+
messageIdentifier: Optional[str] = attr.ib(default=None)
18+
"""
19+
The identifier of the message.
20+
21+
https://developer.apple.com/documentation/retentionmessaging/messageidentifier
22+
"""
23+
24+
messageState: Optional[RetentionMessageState] = RetentionMessageState.create_main_attr('rawMessageState')
25+
"""
26+
The current state of the message.
27+
28+
https://developer.apple.com/documentation/retentionmessaging/messagestate
29+
"""
30+
31+
rawMessageState: Optional[str] = RetentionMessageState.create_raw_attr('messageState')
32+
"""
33+
See messageState
34+
"""
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Copyright (c) 2023 Apple Inc. Licensed under MIT License.
2+
3+
from enum import Enum
4+
from .LibraryUtility import AppStoreServerLibraryEnumMeta
5+
6+
class RetentionMessageState(Enum, metaclass=AppStoreServerLibraryEnumMeta):
7+
"""
8+
The approval state of the message.
9+
10+
https://developer.apple.com/documentation/retentionmessaging/messagestate
11+
"""
12+
13+
PENDING = "PENDING"
14+
"""
15+
The message is awaiting approval.
16+
"""
17+
18+
APPROVED = "APPROVED"
19+
"""
20+
The message is approved.
21+
"""
22+
23+
REJECTED = "REJECTED"
24+
"""
25+
The message is rejected.
26+
"""
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright (c) 2023 Apple Inc. Licensed under MIT License.
2+
3+
from typing import Optional
4+
from attr import define
5+
import attr
6+
7+
@define
8+
class UploadMessageImage:
9+
"""
10+
The definition of an image with its alternative text.
11+
12+
https://developer.apple.com/documentation/retentionmessaging/uploadmessageimage
13+
"""
14+
15+
imageIdentifier: Optional[str] = attr.ib(default=None)
16+
"""
17+
The unique identifier of an image.
18+
19+
https://developer.apple.com/documentation/retentionmessaging/imageidentifier
20+
"""
21+
22+
altText: Optional[str] = attr.ib(default=None)
23+
"""
24+
The alternative text you provide for the corresponding image.
25+
Maximum length: 150
26+
27+
https://developer.apple.com/documentation/retentionmessaging/alttext
28+
"""
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright (c) 2023 Apple Inc. Licensed under MIT License.
2+
3+
from typing import Optional
4+
from attr import define
5+
import attr
6+
from .UploadMessageImage import UploadMessageImage
7+
8+
@define
9+
class UploadMessageRequestBody:
10+
"""
11+
The request body for uploading a message, which includes the message text and an optional image reference.
12+
13+
https://developer.apple.com/documentation/retentionmessaging/uploadmessagerequestbody
14+
"""
15+
16+
header: Optional[str] = attr.ib(default=None)
17+
"""
18+
The header text of the retention message that the system displays to customers.
19+
Maximum length: 66
20+
21+
https://developer.apple.com/documentation/retentionmessaging/header
22+
"""
23+
24+
body: Optional[str] = attr.ib(default=None)
25+
"""
26+
The body text of the retention message that the system displays to customers.
27+
Maximum length: 144
28+
29+
https://developer.apple.com/documentation/retentionmessaging/body
30+
"""
31+
32+
image: Optional[UploadMessageImage] = attr.ib(default=None)
33+
"""
34+
The optional image identifier and its alternative text to appear as part of a text-based message with an image.
35+
36+
https://developer.apple.com/documentation/retentionmessaging/uploadmessageimage
37+
"""
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"messageIdentifiers": [
3+
{
4+
"messageIdentifier": "test-message-1",
5+
"messageState": "APPROVED"
6+
},
7+
{
8+
"messageIdentifier": "test-message-2",
9+
"messageState": "PENDING"
10+
},
11+
{
12+
"messageIdentifier": "test-message-3",
13+
"messageState": "REJECTED"
14+
}
15+
]
16+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"errorCode": 4090001,
3+
"errorMessage": "An error that indicates the message identifier already exists."
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"errorCode": 4000101,
3+
"errorMessage": "An error that indicates the message header exceeds 66 characters."
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"errorCode": 4040001,
3+
"errorMessage": "An error that indicates the specified message was not found."
4+
}

0 commit comments

Comments
 (0)