Sending Secure Messages
One of the most common asks we get is how to send a secure message to an end user from the SDK. What we recommend is using the Q2API’s SendSecureMessageAsXML endpoint. We recommend this one because it is the most robust and configurable messaging endpoint and also offers attachment support for your messages
Note
There are several Q2API endpoints for secure messaging and you may not need all the features of this one. Feel free to use any of the other ones if they suit your needs better
One very important thing to note is that, unlike the other Q2API endpoints, this one only has one parameter other than logger, a fully formatted XML string. Building XML by hand is frustrating even for experienced developers. Luckily for everyone, we have a built-in helper to construct this XML string
- class q2_sdk.hq.api_helpers.build_secure_message_xml(source_id, target_id, message_subject, message_body, sender_type='Administrator', target_type='AdministratorGroup', creation_time=None, expiration_time=None, attachment=None)[source]
Builds an xml_payload for use with HQ’s SendSecureMessageAsXML
- Parameters:
source_id (
int
) – “from” group idtarget_id (
int
) – recipient IDmessage_subject (
str
) – Subject of the secure messagemessage_body (
str
) – Body of the secure messagesender_type (
Optional
[SecureMessengerType
]) – Optional choice fromSecureMessengerType
. Defaults to Administratortarget_type (
Optional
[SecureMessengerType
]) – Optional choice fromSecureMessengerType
. Defaults to AdministratorGroupcreation_time (
Optional
[datetime
]) – Time message was generatedexpiration_time (
Optional
[datetime
]) – Timestamp at which message will expireattachment (
Optional
[SecureMessageAttachment
]) – Optional choice fromSecureMessageAttachment
.
- Returns:
Already escaped xml_payload
Building XML by hand is frustrating even for experienced developers, especially when having to navigate the intricacies of the Q2 System.
Note
The ids you need refer to different entities depending on the SecureMessengerType:
For AdminGroup, the ids refer to entries in the
Q2_MessageRecipientGroup
table and can be accessed using the matching db objectFor EndUser, the ids refer to entries in the
Q2_User
table and can be accessed using the matching db objectFor Administrator, the ids refer to entries in the
Q2_AdminUsers
table. There’s no matching db object for this, but if you know the admin login name, you can get theiradmin_id
via theUserLogon
DbObject
Below is a fully functional code snippet and the import statements to send a secure message with an
attachment. It shows an example message with how to open and add a file as an attachment as well as how to get
target_id
and source_id
programmatically using db objects
import os
from datetime import datetime, timedelta
from q2_sdk.hq.api_helpers import build_secure_message_xml
from q2_sdk.hq.models.secure_messenger_type import SecureMessengerType
from q2_sdk.hq.models.secure_message_attachment import SecureMessageAttachment
from q2_sdk.hq.hq_api.q2_api import SendSecureMessageAsXml
async def default(self):
# Init db objects
# Returns a list of users that match the criteria. Only one has login retail0
# Use whatever identifier you want to find the customer
user_id = (await self.db.user.get(login_name='retail0'))[0].UserID
message_group_id = (await self.db.message_recipient_group.get_by_name("Customer Service")).GroupID
directory = os.path.dirname(os.path.realpath(__file__)) # Get directory where this python code is located
path = os.path.join(directory, 'file.txt') # Change this to wherever you want to load your file from
with open(path, 'rb') as file:
data = file.read()
attachment = SecureMessageAttachment("file.txt", data)
## NOTE:
# Some of these parameters are passed as positional (user_id) while others
# are passed as a keyword (creation_time=)
# In Python, it's normally possible to do either, but the convention is to pass
# parameters that have defaults in the underlying function as a keyword, which required
# parameters are passed as positional. The build_secure_message_xml function here takes
# 4 required parameters, then the rest are optional. As such, we pass the first 4 as
# positional, then define the keyword variant on the remainder.
xml_str = build_secure_message_xml(
message_group_id, # source_id
user_id, # target_id
'TestXMLBuilder', # message_subject
'Message Body', # message_body
sender_type=SecureMessengerType.AdministratorGroup,
target_type=SecureMessengerType.EndUser,
creation_time=datetime.now(),
expiration_time=datetime.now()+timedelta(7),
attachment=attachment
)
params = SendSecureMessageAsXml.ParamsObj(self.logger, xml_str, hq_credentials=self.hq_credentials)
await SendSecureMessageAsXml.execute(params)
return "Success"