0
# Compose Sessions
1
2
Email composition session handling including compose context, session handlers, and address annotation. This module provides functionality for managing email composition workflows and customizing the compose experience.
3
4
## Capabilities
5
6
### MEComposeSession
7
8
Manages email composition sessions. This is the primary class for working with compose sessions in Mail extensions.
9
10
```python { .api }
11
class MEComposeSession:
12
"""
13
Manages an email composition session.
14
15
Note: This class cannot be instantiated directly using init() or new().
16
Instances are provided by the Mail framework when composition begins.
17
"""
18
```
19
20
### MEComposeContext
21
22
Provides context information for email composition including encryption/signing state. Contains information about the current state and requirements for message composition.
23
24
```python { .api }
25
class MEComposeContext:
26
def isEncrypted(self) -> bool:
27
"""
28
Check if the compose context indicates encryption.
29
30
Returns:
31
bool: True if the context is encrypted
32
"""
33
34
def shouldEncrypt(self) -> bool:
35
"""
36
Check if the message should be encrypted.
37
38
Returns:
39
bool: True if the message should be encrypted
40
"""
41
42
def isSigned(self) -> bool:
43
"""
44
Check if the compose context indicates signing.
45
46
Returns:
47
bool: True if the context is signed
48
"""
49
50
def shouldSign(self) -> bool:
51
"""
52
Check if the message should be signed.
53
54
Returns:
55
bool: True if the message should be signed
56
"""
57
```
58
59
### MEAddressAnnotation
60
61
Provides annotations for email addresses during composition. Used to add additional information or context to email addresses in the compose interface.
62
63
```python { .api }
64
class MEAddressAnnotation:
65
"""
66
Provides annotations for email addresses.
67
68
Note: This class cannot be instantiated directly using init() or new().
69
Instances are created through the address annotation process.
70
"""
71
```
72
73
## Compose User Actions
74
75
Constants representing different compose user actions:
76
77
```python { .api }
78
MEComposeUserActionNewMessage: int # = 1, Creating a new message
79
MEComposeUserActionReply: int # = 2, Replying to a message
80
MEComposeUserActionReplyAll: int # = 3, Replying to all recipients
81
MEComposeUserActionForward: int # = 4, Forwarding a message
82
```
83
84
## Compose Session Error Handling
85
86
```python { .api }
87
# Error domain
88
MEComposeSessionErrorDomain: str # Error domain for compose session errors
89
90
# Error codes
91
MEComposeSessionErrorCodeInvalidRecipients: int # = 0, Invalid recipients error
92
MEComposeSessionErrorCodeInvalidHeaders: int # = 1, Invalid headers error
93
MEComposeSessionErrorCodeInvalidBody: int # = 2, Invalid body error
94
```
95
96
### Compose Session Error Types
97
98
Type definition for compose session error codes:
99
100
```python { .api }
101
MEComposeSessionErrorCode: type # Enum type for compose session error codes
102
```
103
104
## Usage Examples
105
106
### Working with Compose Context
107
108
```python
109
import MailKit
110
111
# Check compose context security settings
112
def check_compose_security(compose_context):
113
"""Check and report on compose context security settings."""
114
115
# Check current encryption state
116
if compose_context.isEncrypted():
117
print("Compose context is currently encrypted")
118
119
# Check if encryption is recommended
120
if compose_context.shouldEncrypt():
121
print("Message should be encrypted")
122
else:
123
print("Encryption not required")
124
125
# Check current signing state
126
if compose_context.isSigned():
127
print("Compose context is currently signed")
128
129
# Check if signing is recommended
130
if compose_context.shouldSign():
131
print("Message should be signed")
132
else:
133
print("Signing not required")
134
135
# Example usage with a compose context
136
# compose_context would be provided by the Mail framework
137
# check_compose_security(compose_context)
138
```
139
140
### Handling Compose User Actions
141
142
```python
143
import MailKit
144
145
# Determine compose action type
146
def get_compose_action_description(action_type):
147
"""Get a description of the compose action type."""
148
149
if action_type == MailKit.MEComposeUserActionNewMessage:
150
return "Creating a new message"
151
elif action_type == MailKit.MEComposeUserActionReply:
152
return "Replying to a message"
153
elif action_type == MailKit.MEComposeUserActionReplyAll:
154
return "Replying to all recipients"
155
elif action_type == MailKit.MEComposeUserActionForward:
156
return "Forwarding a message"
157
else:
158
return f"Unknown compose action: {action_type}"
159
160
# Example usage
161
action = MailKit.MEComposeUserActionReply
162
description = get_compose_action_description(action)
163
print(description) # Output: "Replying to a message"
164
```
165
166
### Error Handling for Compose Sessions
167
168
```python
169
import MailKit
170
171
# Handle compose session errors
172
def handle_compose_error(error_code):
173
"""Handle different types of compose session errors."""
174
175
if error_code == MailKit.MEComposeSessionErrorCodeInvalidRecipients:
176
return {
177
"error": "Invalid Recipients",
178
"description": "One or more recipients are invalid",
179
"suggestion": "Please check recipient email addresses"
180
}
181
elif error_code == MailKit.MEComposeSessionErrorCodeInvalidHeaders:
182
return {
183
"error": "Invalid Headers",
184
"description": "Message headers are invalid",
185
"suggestion": "Please check message headers and format"
186
}
187
elif error_code == MailKit.MEComposeSessionErrorCodeInvalidBody:
188
return {
189
"error": "Invalid Body",
190
"description": "Message body is invalid",
191
"suggestion": "Please check message content and formatting"
192
}
193
else:
194
return {
195
"error": "Unknown Error",
196
"description": f"Unknown error code: {error_code}",
197
"suggestion": "Please try again or contact support"
198
}
199
200
# Example usage
201
error_info = handle_compose_error(MailKit.MEComposeSessionErrorCodeInvalidRecipients)
202
print(f"Error: {error_info['error']} - {error_info['description']}")
203
print(f"Suggestion: {error_info['suggestion']}")
204
```
205
206
### Complete Compose Action Reference
207
208
```python
209
import MailKit
210
211
# All available compose actions
212
compose_actions = {
213
"new_message": MailKit.MEComposeUserActionNewMessage,
214
"reply": MailKit.MEComposeUserActionReply,
215
"reply_all": MailKit.MEComposeUserActionReplyAll,
216
"forward": MailKit.MEComposeUserActionForward
217
}
218
219
# Function to get action name from value
220
def get_action_name(action_value):
221
for name, value in compose_actions.items():
222
if value == action_value:
223
return name
224
return "unknown"
225
226
# Function to validate compose action
227
def is_valid_compose_action(action_value):
228
return action_value in compose_actions.values()
229
230
# Example usage
231
action_name = get_action_name(MailKit.MEComposeUserActionForward)
232
print(f"Action: {action_name}") # Output: "Action: forward"
233
234
if is_valid_compose_action(MailKit.MEComposeUserActionReply):
235
print("Reply action is valid")
236
```
237
238
### Security Context Analysis
239
240
```python
241
import MailKit
242
243
# Comprehensive security analysis for compose context
244
def analyze_compose_security(compose_context):
245
"""Perform comprehensive security analysis of compose context."""
246
247
analysis = {
248
"current_state": {},
249
"recommendations": {},
250
"warnings": []
251
}
252
253
# Analyze current state
254
analysis["current_state"]["encrypted"] = compose_context.isEncrypted()
255
analysis["current_state"]["signed"] = compose_context.isSigned()
256
257
# Analyze recommendations
258
analysis["recommendations"]["should_encrypt"] = compose_context.shouldEncrypt()
259
analysis["recommendations"]["should_sign"] = compose_context.shouldSign()
260
261
# Generate warnings based on mismatches
262
if compose_context.shouldEncrypt() and not compose_context.isEncrypted():
263
analysis["warnings"].append("Encryption is recommended but not currently enabled")
264
265
if compose_context.shouldSign() and not compose_context.isSigned():
266
analysis["warnings"].append("Signing is recommended but not currently enabled")
267
268
# Generate security summary
269
security_level = "basic"
270
if analysis["current_state"]["encrypted"] and analysis["current_state"]["signed"]:
271
security_level = "high"
272
elif analysis["current_state"]["encrypted"] or analysis["current_state"]["signed"]:
273
security_level = "medium"
274
275
analysis["security_level"] = security_level
276
277
return analysis
278
279
# Example usage
280
# analysis = analyze_compose_security(compose_context)
281
# print(f"Security Level: {analysis['security_level']}")
282
# for warning in analysis["warnings"]:
283
# print(f"Warning: {warning}")
284
```