[SalesForce] Use AMPScript to upload an image into Portfolio in Marketing Cloud via HTML Form

My previous post on "Use AMPScript to upload an image into Portfolio in Marketing Cloud" answered the first half of my question. Now I want to find out if it's possible to upload an image into Portfolio with AMPScript and an HTML form.

Our goal is upload an image into Portfolio. We use a Landing page that contains a Smart Capture form with the Email field (which relates to the Email field in the linked data extension). Also there is an control that allows the user to select an image file. Basically, when the user fills in the Email field, chooses a file and clicks submit, this data need to be transferred to SFMC. Email goes directly to a data extension. But I don't know (I have not found any info, honestly) how to handle the data and upload it into Portfolio.

HTML code of the landing page:

<form action="%%= RequestParameter('PAGEURL') =%%" method="POST" onsubmit="return validate()" enctype="multipart/form-data">
    <div>
        <center>
        <div>
            <div>
                <b>EMAIL</b>
            </div>
            <div>
                <input type="text" maxlength="254" name="Email" id="Email" value="" size="75"/>
            </div>
        </div>    
        <br />        
        <div>
            <p>Upload your photo</p>
            <p><input type="file" name="Image" id="Image" accept="image/png,image/jpeg"/></p>
        </div>
        <br />  
        <div>
            <input type="submit" value="Register"/>
            <br/>
        </div>
        </center>
    </div>
    <!-- AMP Processing Placeholder DO NOT REMOVE -->
    <input type="hidden" name="__successPage" id="__successPage" value="http://pages.email.../sandbox-photo-contest-status?type=success" />
    <input type="hidden" name="__errorPage" id="__errorPage" value="http://pages.email.../sandbox-photo-contest-status?type=error" />
    <input type="hidden" name="__contextName" id="__contextName" value="FormPost" />
    <input type="hidden" name="__executionContext" id="__executionContext" value="Post" />
</form>

AMPScript code on the Processing tab of the Smart Capture form:

VAR @de, @de_col, @de_statusCode, @de_statusMsg, @errorCode

SET @de = CreateObject("DataExtensionObject")
SetObjectProperty(@de, "CustomerKey", "Photo_Contest_Campaign_Questions")

SET @email = RequestParameter("Email")
SET @dateCreated = NOW()
SET @photoFileName = "Photo"


IF NOT IsNull(@email) THEN
    SET @deColumn = CreateObject("APIProperty")
    SetObjectProperty(@deColumn, "Name", "Email")
    SetObjectProperty(@deColumn, "Value", @email)
    AddObjectArrayItem(@de, "Keys", @deColumn)
    AddObjectArrayItem(@de, "Properties", @deColumn)
ENDIF

IF NOT IsNull(@dateCreated) THEN  
    SET @deColumn = CreateObject("APIProperty")
    SetObjectProperty(@deColumn, "Name", "DateCreated")
    SetObjectProperty(@deColumn, "Value", @dateCreated)
    AddObjectArrayItem(@de, "Keys", @deColumn)    
    AddObjectArrayItem(@de, "Properties", @deColumn)
ENDIF

SET @de_col = CreateObject("APIProperty")
SetObjectProperty(@de_col, "Name", "PhotoFileName")
SetObjectProperty(@de_col, "Value", @photoFileName)
AddObjectArrayItem(@de, "Properties", @de_col)

SET @de_statusCode = InvokeCreate(@de, @de_statusMsg, @errorCode)

IF @de_statusCode != "OK" THEN
    RaiseError(@de_statusMsg, 0, @de_statusCode, @errorCode)
ENDIF

/* ------------------------------------------------------------------- */
/* Upload an Image */

SET @image = RequestParameter("Image")
SET @imageName = Field(@image, "name") 

SET @portfolio = CreateObject('Portfolio')
SetObjectProperty(@portfolio, "DisplayName", "API Uploaded3")
SetObjectProperty(@portfolio, "CustomerKey", "css-grid-vs-flexbox2")
SetObjectProperty(@portfolio, "FileName", "css-grid-vs-flexbox2.png")
SetObjectProperty(@portfolio, "CategoryID", "myFolderID")

SET @ClientID = CreateObject("ClientID")
SetObjectProperty(@ClientID, "ID", "myMID")
SetObjectProperty(@portfolio, "Client", @ClientID)

SET @resourceSpecification = CreateObject('ResourceSpecification')
SetObjectProperty(@resourceSpecification, "URN", @image)
SetObjectProperty(@portfolio, "Source", @resourceSpecification)

SET @options = CreateObject("UpdateOptions")
SET @saveOption = CreateObject("SaveOption")
SetObjectProperty(@saveOption, "SaveAction", "UpdateAdd")
SetObjectProperty(@saveOption, "PropertyName", "*")
AddObjectArrayItem(@options, "SaveOptions", @saveOption)

/* Add data */
SET @statusCode = InvokeCreate(@portfolio, @statusMsg, @errorCode, @options)

IF @statusCode != "OK" THEN
    RaiseError(@statusMsg, 0, @statusCode, @errorCode)
ENDIF

I tried to follow the pattern from here, but I got an error on the line SET @imageName = Field(@image, "name")

Error Details are below:

Error code:

Error status code:

Error message: Invalid row (parameter 1) passed to Field function. Row is null or empty. Function: Field(@image, "name")

Also I am not sure this is correct SetObjectProperty(@resourceSpecification, "URN", @image)
because the URN property can take String type only.

Only one direct question was asked here in "Can ExactTarget and AMPscript use a form to upload an image?", but I didn't find a real answer on that question.

Use AMPScript to upload an image into Portfolio in Marketing Cloud
Can ExactTarget and AMPscript use a form to upload an image?

Best Answer

No. What you're trying to do won't work. A file upload requires server side processing to serialise a stream of binary data. AMPScript and SSJS have no ability to handle this binary data. The SOAP methods you're referring to take a URL or FTP location to pick a file up from and create a Portfolio item from the file in that location.

You won't be able to do the whole thing in landing pages, but the newer REST API for Content Builder does have a method for creating files you've already encoded as Assets.

Related Topic