Expand my Community achievements bar.

SOLVED

Python and SOAP to Batch Import Delivery Templates

Avatar

Level 2

Any ideas why this returns with no errors, yet delivery templates are not created anywhere?

 

I'm trying to batch import my emails (htm files) from a previous ESP into Adobe Campaign as Delivery Templates. I created a new I/O API project and confirmed I can get that to work with single pushes from our Stensul application into Adobe Campaign as Delivery Templates. So I created a second I/O API Project and tried doing the following, and it seems to all run smoothly no errors output, but I do not see any Delivery Templates created. 

 

The folder ID for <folder _operation="none" name="1186"/> I am using is one I got from our instance that looks like: domain-for-adobe.com/acc/folders/folder/1186/nmsDeliveryModel

 

import os
import requests
import time
import glob
from lxml import etree

# Adobe OAuth Credentials
ACCESS_TOKEN = "AT"
SERVER_URL = 'domain.com/nl/jsp/soaprouter.jsp'

# mcapi Session Token (use this instead of generating it)
SESSION_TOKEN = "ST"

# Folder path for *.htm files
FOLDER_PATH = os.path.expanduser('/Users/my_computer/Desktop/files_folder')

# Function to push HTML as delivery template
def push_html(file_path):
file_name = os.path.basename(file_path)
with open(file_path, 'r', encoding='utf-8') as file:
html_content = file.read()

subject = f"Template for {file_name}"
template_name = file_name.replace('.htm', '')
folder_name = 'Delivery Templates'
delivery_operation = 'insertOrUpdate'

body = f"""
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:urn="urn:xtk:session">
<soapenv:Header/>
<soapenv:Body>
<urn:Write>
<urn:sessiontoken>{SESSION_TOKEN}</urn:sessiontoken>
<urn:domDoc>
<delivery _operation="{delivery_operation}" xtkschema="nms:delivery"
internalName="{template_name}" deliveryMode="4" messageType="0"
isModel="1" label="{template_name}">
<mailParameters>
<subject><![CDATA[{subject}]]></subject>
</mailParameters>
<content>
<html>
<source><![CDATA[{html_content}]]></source>
</html>
<text>
<source><![CDATA[Text version not provided]]></source>
</text>
</content>
<tracking enabled="false" openEnabled="false"/>
<advancedParameters forceCodepage="false"/>
<folderProcess _operation="none" name="nmsRootDelivery"/>
<folder _operation="none" name="1186"/>
</delivery>
</urn:domDoc>
</urn:Write>
</soapenv:Body>
</soapenv:Envelope>
"""

headers = {
'Authorization': f'Bearer {ACCESS_TOKEN}',
'Content-Type': 'text/xml; charset=UTF-8',
'SOAPAction': 'urn:xtk:session#Write'
}

# Encode the body to UTF-8
encoded_body = body.encode('utf-8')

response = requests.post(SERVER_URL, data=encoded_body, headers=headers)

if response.status_code == 200:
print(f" Successfully imported {file_name}")
else:
print(f" Failed to import {file_name}: {response.content.decode('utf-8', errors='ignore')}")

# Main Function
def main():
try:
# Get all .htm files recursively
files = glob.glob(os.path.join(FOLDER_PATH, '**', '*.htm'), recursive=True)
if not files:
print(" No .htm files found in the specified folder.")
return

for file_path in files:
print(f" Importing {file_path}...")
push_html(file_path)
time.sleep(1) # Adding a small delay to avoid API throttling

print("\n All files imported successfully.")

except Exception as e:
print(f" Error: {e}")

if __name__ == "__main__":
main()

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hello @Hurston Do you see any error when the API call is posted? Also, try changing the operation from insertOrUpdate to insert. insertOrUpdate requires a primary key to update the existing record.


     Manoj
     Find me on LinkedIn

View solution in original post

7 Replies

Avatar

Community Advisor

Hi @Hurston,

 

I do believe that you have done it, but please verify that your authentication tokens are valid and the folder paths are right. You can print the response body for hidden errors and you can also in this way verify the XML structure.

Also, try with insert to see if the deliveries are being created somewhere else.

 

Please, check the following documentation to help yourself:

SOAP API Methods 

Managing deliveries 

Adobe Campaign Folder Management 

API Troubleshooting 

 

Hope it suits you, let me know if you need more help.

 

Best regards, 

Celia

 

 

 

 

 

 

Avatar

Level 2

Thank you, change "insertOrUpdate" to "insert" and added the following after my requests.posts

 

print(" RAW RESPONSE:")
print(response.content.decode('utf-8', errors='ignore')) # Output the response for debugging

 

Ending up getting this error so looks like I may have some issue with my auth token maybe.

 

<?xml version='1.0'?><SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Client</faultcode><faultstring xsi:type='xsd:string'>SOP-330007 Error while reading parameters of method 'Write' of service 'urn:xtk:session'</faultstring><detail xsi:type='xsd:string'>XSV-350114 Unknown error during '/ims/profile/v1' IMS call, HTTP response code is 401</detail></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>

Avatar

Community Advisor

Hello @Hurston  The response is 401 and that means the token is invalid or expired. The token expires every hour and you will have refresh it.


     Manoj
     Find me on LinkedIn

Avatar

Level 2

Thank you seems I have something else to troubleshoot now. I added token refresh to my python script and I get a confirmation that the token is refreshed, but I get a new error about 

 

Failed to get session token: XAV-350375 Operator '[blah]@techacct.adobe.com' does not have access to product context 'dma_campaign_classic'. Please check the product context in the external account.
XAV-350374 Operator '[blah]@techacct.adobe.com' does not belong to organization '[blah]@AdobeOrg'. Please check the organization ID in the external account.

 

I went through my steps again to confirm the Adobe Campaign and I/O API in my project have the Product Profiles needed, I checked in Admin Console and added the techacct to our user group and product. I tried creating an external account and new product profile for 'dma_campaign_classic' but seems like there is something I am still missing.

Avatar

Community Advisor

Hello @Hurston  Make sure that correct product profile are assigned to the s2s integration in Developer console and all the credential given there matches with your code.


     Manoj
     Find me on LinkedIn

Avatar

Correct answer by
Community Advisor

Hello @Hurston Do you see any error when the API call is posted? Also, try changing the operation from insertOrUpdate to insert. insertOrUpdate requires a primary key to update the existing record.


     Manoj
     Find me on LinkedIn

Avatar

Level 2

Ah thank you, updating that now.