Python and SOAP to Batch Import Delivery Templates | Community
Skip to main content
Level 2
March 17, 2025
Solved

Python and SOAP to Batch Import Delivery Templates

  • March 17, 2025
  • 2 replies
  • 1168 views

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()

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by _Manoj_Kumar_

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.

2 replies

ccg1706
Community Advisor
Community Advisor
March 17, 2025

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

 

 

 

 

 

 

HurstonAuthor
Level 2
March 17, 2025

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>

_Manoj_Kumar_
Community Advisor
Community Advisor
March 17, 2025

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
_Manoj_Kumar_
Community Advisor
_Manoj_Kumar_Community AdvisorAccepted solution
Community Advisor
March 17, 2025

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
HurstonAuthor
Level 2
March 17, 2025

Ah thank you, updating that now.