Skip to content

Instantly share code, notes, and snippets.

@MartinMiles
Last active April 20, 2024 17:28
Show Gist options
  • Save MartinMiles/353fbe7cd1b10dd200f9e525b37d03a3 to your computer and use it in GitHub Desktop.
Save MartinMiles/353fbe7cd1b10dd200f9e525b37d03a3 to your computer and use it in GitHub Desktop.
Demo of uploading a media item to XM Cloud using Authoring GraphQL API
# before starting, make sure env variable "Sitecore_GraphQL_ExposePlayground" is set to "true"
$FileToUpload = "C:\Users\Martin\Pictures\man2x.png"
$MediaDestination = "Default Website/new media"
$Hostname = "xmc-perficient-introduction-158.sitecorecloud.io"
# First, obtain TWT using authorized data from user.json
$JWT = .\Request-Token.ps1
# Next, get the upload URL from Authoring GraphQL endpoint
$Url = .\Get-MedaUploadUrl.ps1 -UploadPath $MediaDestination -JWT $JWT -EndpointUrl "https://$Hostname/sitecore/api/authoring/graphql/v1/"
# Finally, upload the media files using upload URL and JWT
$Media = .\Upload-Media.ps1 -UploadUrl $Url -JWT $JWT -FilePath $FileToUpload
# Get the result
$Media
<#
.SYNOPSIS
Generates a pre-signed URL for uploading a file to a specified endpoint using a JWT token.
.DESCRIPTION
This function generates a pre-signed URL for uploading a file to a specified endpoint using a JWT token.
.PARAMETER EndpointUrl
The URL of the endpoint where the file will be uploaded. Example https://some-part.sitecorecloud.io/sitecore/api/authoring/graphql/v1/
.PARAMETER JWT
The JWT token to use for authentication. Call Request-Token.ps1 for obtaining the one
.PARAMETER UploadPath
The Sitecore path of the file to be uploaded, relative to /sitecore/media library item (ie. "Default Website/new media")
.OUTPUTS
It returns the URL as a string value.
.AUTHOR
Martin Miles
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true, HelpMessage="The URL of the endpoint where the file will be uploaded.")]
[string]$EndpointUrl,
[Parameter(Mandatory=$true, HelpMessage="The JWT token to use for authentication.")]
[string]$JWT,
[Parameter(Mandatory=$true, HelpMessage="The path of the file to be uploaded.")]
[string]$UploadPath
)
$query = @"
mutation
{
uploadMedia(input: { itemPath: "$UploadPath" }) {
presignedUploadUrl
}
}
"@
$body = @{ query = $query} | ConvertTo-Json
$headers = @{
"Content-Type" = "application/json"
"Authorization" = "Bearer $JWT"
}
# Invoke the GraphQL endpoint using Invoke-RestMethod and pass in the query and headers
$response = Invoke-RestMethod -Method POST -Uri $EndpointUrl -Headers $headers -Body $body
$result = $response.data.uploadMedia
return $result.presignedUploadUrl
<#
.SYNOPSIS
Get organiztion client ID and secret from user.json and generates JWT token.
.EXAMPLE
$JWT = Get-JWTToken
.AUTHOR
Martin Miles
#>
[CmdletBinding()]
Param()
$userJson = "$PSScriptRoot/../../.sitecore/user.json"
if (-not (Test-Path $userJson)) {
Write-Error "The specified file '$userJson' does not exist."
return
}
$userJson = Get-Content $userJson | ConvertFrom-Json
$clientId = $userJson.endpoints.xmCloud.clientId
$clientSecret = $userJson.endpoints.xmCloud.clientSecret
$authorityUrl = $userJson.endpoints.xmCloud.authority
$audience = $userJson.endpoints.xmCloud.audience
$grantType = "client_credentials"
$body = @{
client_id = $clientId
client_secret = $clientSecret
audience = $audience
grant_type = $grantType
}
$response = Invoke-RestMethod -Uri "${authorityUrl}oauth/token" -Method Post -ContentType "application/x-www-form-urlencoded" -Body $body
return $response.access_token
<#
.SYNOPSIS
Uploads the media from a local file using a JWT token for authentication, the actual path is dictated from $url
.DESCRIPTION
This function uploads a file to the specified URL using a JWT token for authentication. It returns an object containing the Id, name and path of uploaded media.
.PARAMETER UploadUrl
The URL to upload the file to.
.PARAMETER JWT
The JWT token to use for authentication.
.PARAMETER FilePath
The path to the file to be uploaded.
.OUTPUTS
An object containing the Id, name and path of uploaded media.
.AUTHOR
Martin Miles
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true, HelpMessage="The URL to upload the file to.")]
[string]$UploadUrl,
[Parameter(Mandatory=$true, HelpMessage="The JWT token to use for authentication.")]
[string]$JWT,
[Parameter(Mandatory=$true, HelpMessage="The path to the file to be uploaded.")]
[string]$FilePath
)
if (-not (Test-Path $FilePath)) {
Write-Error "The specified file '$FilePath' does not exist."
return
}
$result = & curl.exe --request POST $UploadUrl --header "Authorization: Bearer $JWT" --form =@"$FilePath" -s
$result = $result | ConvertFrom-Json
return $result
@theShiva
Copy link

Hi @MartinMiles

Thank you for the demo scripts!!

I used most of this, with some modifications for our use case, to try and migrate existing media library items from Sitecore XP 9.3 to XM Cloud.

I'm running into an issue wherein I'm not able to specify an Item Id for the Media Library items that is being uploaded into XM Cloud.

The use case, is that we are migrating from XP 9.3 to XM Cloud.

As such, we need to maintain the same Item Id that an item in XP 9.3 has, in the corresponding item that is being uploaded to XM Cloud.

The UploadMedia mutation's Input object does not have any property to specify DesiredItemId (i.e. an existing itemId).

I've demo-ed this problem in this short screencast, hope you can look at it and provide some solutions if you know of it.

Sitecore XM Cloud - Upload Media Library Item with a Specific Item Id

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment