|
| 1 | +--- |
| 2 | +plugin: add-to-gallery |
| 3 | +--- |
| 4 | + |
| 5 | +# Integrate MailChimp Campaigns API with SPO to create wiki pages based on email sent from MailChimp |
| 6 | + |
| 7 | + |
| 8 | +## Summary |
| 9 | + |
| 10 | +This PowerShell script automates the integration of MailChimp and SharePoint by connecting to SharePoint using PnP PowerShell, retrieving MailChimp campaigns based on specified date ranges, extracting and cleaning HTML content from these campaigns, downloading and uploading images to SharePoint, creating and publishing a SharePoint Wiki page with the cleaned HTML content, and updating bulletin links on a designated SharePoint page. The script handles various tasks, including removing unwanted scripts and styles from the HTML, moving published pages to a specified folder, and ensuring that all image URLs in the HTML content are updated to point to the images stored in SharePoint. |
| 11 | + |
| 12 | +# [PnP PowerShell](#tab/pnpps) |
| 13 | + |
| 14 | +```powershell |
| 15 | +
|
| 16 | +$mailChimpApiKey = "" |
| 17 | +$siteUrl = "https://<your-sharepoint-site-url>" |
| 18 | +$relativeUrl = "/sites/<your-site-name>" |
| 19 | +$wikiFolder = "$relativeUrl/SitePages/WikiFolder/" |
| 20 | +$wikiPageUrl = "$relativeUrl/SitePages/" |
| 21 | +$apiEndpoint = "https://<DC>.api.mailchimp.com/3.0/campaigns" |
| 22 | +#On line 85, replace the search string for your campaign - NOTE LINE NUMBERS MAY CHANGE |
| 23 | +#On line 101, provide the local path to where the images should be stored for later upload to SPO |
| 24 | +#On line 107 and 110, replace WikiDocLib with the existing document library on SPO to store images |
| 25 | +function Connect-ToSharePoint { |
| 26 | + param ( |
| 27 | + [string]$siteUrl |
| 28 | + ) |
| 29 | + #The sample uses a certificate to connect. You can also use -WebLogin but -Interactive is no longer supported |
| 30 | + $connectToSP = Connect-PnPOnline -Url $siteUrl -ClientId "<your-client-id>" -Thumbprint "<your-thumbprint>" -Tenant "<your-tenant-id>" -ReturnConnection |
| 31 | + return $connectToSP |
| 32 | +} |
| 33 | +
|
| 34 | +function Get-MailChimpCampaigns { |
| 35 | + param ( |
| 36 | + [string]$mailChimpApiKey, |
| 37 | + [string]$sinceSendTime, |
| 38 | + [string]$beforeSendTime |
| 39 | + ) |
| 40 | + $headers = @{ |
| 41 | + "Authorization" = "Bearer $mailChimpApiKey" |
| 42 | + } |
| 43 | + $apiEndpoint = "$apiEndpoint?since_send_time=$sinceSendTime&before_send_time=$beforeSendTime&sort_field=send_time&sort_dir=DESC&status=sent" |
| 44 | + $response = Invoke-RestMethod -Uri $apiEndpoint -Headers $headers -Method Get |
| 45 | + return $response |
| 46 | +} |
| 47 | +
|
| 48 | +function Extract-HTMLContent { |
| 49 | + param ( |
| 50 | + [string]$mailChimpUrl, |
| 51 | + [object]$headers |
| 52 | + ) |
| 53 | + $response = Invoke-RestMethod -Uri $mailChimpUrl -Headers $headers -Method Get |
| 54 | + return $response.html |
| 55 | +} |
| 56 | +
|
| 57 | +function Clean-HTMLContent { |
| 58 | + param ( |
| 59 | + [string]$htmlContent |
| 60 | + ) |
| 61 | + $pattern = '<body[^>]*>([\s\S]*?)<\/body>' |
| 62 | + if ($htmlContent -match $pattern) { |
| 63 | + $bodyContent = $matches[1] |
| 64 | + $bodyContent = $bodyContent -replace '<script[^>]*>[\s\S]*?<\/script>', '' |
| 65 | + $bodyContent = $bodyContent -replace '<style[^>]*>[\s\S]*?<\/style>', '' |
| 66 | + $bodyContent = $bodyContent -replace '<!--[\s\S]*?-->', '' |
| 67 | + } else { |
| 68 | + $bodyContent = "No body content found" |
| 69 | + } |
| 70 | + return $bodyContent |
| 71 | +} |
| 72 | +
|
| 73 | +function Create-PublishWikiPage { |
| 74 | + param ( |
| 75 | + [object]$connectToSP, |
| 76 | + [string]$pageTitle, |
| 77 | + [string]$bodyContent |
| 78 | + ) |
| 79 | + $pageName = $pageTitle |
| 80 | + Add-PnPWikiPage -ServerRelativePageUrl "$wikiPageUrl$pageName" -Content $bodyContent -Connection $connectToSP |
| 81 | + Move-PnPFile -SourceUrl "SitePages/$pageName" -TargetUrl "$wikiFolder$pageName" -Overwrite -Force -Connection $connectToSP |
| 82 | +
|
| 83 | + $mContext = Get-PnPContext -Connection $connectToSP |
| 84 | + $newPageAsListItem = Get-PnPFile -Url "$wikiFolder$pageName" -AsListItem -Connection $connectToSP |
| 85 | + $newPageAsFile = $newPageAsListItem.File |
| 86 | + $mContext.Load($newPageAsFile) |
| 87 | + $mContext.ExecuteQuery() |
| 88 | + $newPageAsFile.Publish("Published via PowerShell script to automate") |
| 89 | + $mContext.ExecuteQuery() |
| 90 | +} |
| 91 | +
|
| 92 | +
|
| 93 | +$connectToSP = Connect-ToSharePoint -siteUrl $siteUrl |
| 94 | +$currentYear = (Get-Date).Year |
| 95 | +$currentMonth = (Get-Date).Month |
| 96 | +$sinceSendTime = (Get-Date -Year $currentYear -Month $currentMonth -Day 1).ToString("yyyy-MM-ddTHH:mm:ssZ") |
| 97 | +$beforeSendTime = (Get-Date).ToString("yyyy-MM-ddT23:59:59Z") |
| 98 | +$jsonCampaignResponse = Get-MailChimpCampaigns -mailChimpApiKey $mailChimpApiKey -sinceSendTime $sinceSendTime -beforeSendTime $beforeSendTime |
| 99 | +
|
| 100 | +if ($jsonCampaignResponse.campaigns[0].settings.subject_line.Contains("<REPLACE WITH STRING TO FIND ON MC>")) { |
| 101 | + Write-Host $jsonCampaignResponse.campaigns[0].settings.subject_line |
| 102 | + $campaignId = $jsonCampaignResponse.campaigns[0].Id |
| 103 | +} |
| 104 | +
|
| 105 | +$pageTitle = "{0}.{1}" -f $jsonCampaignResponse.campaigns[0].settings.subject_line, "aspx" |
| 106 | +$mailChimpUrl = "$apiEndpoint/$campaignId/content" |
| 107 | +$htmlContent = Extract-HTMLContent -mailChimpUrl $mailChimpUrl -headers $headers |
| 108 | +$bodyContent = Clean-HTMLContent -htmlContent $htmlContent |
| 109 | +
|
| 110 | +$imageSrcMatches = [regex]::Matches($bodyContent, '<img[^>]+src="([^">]+)"') |
| 111 | +$imageSrcs = foreach ($match in $imageSrcMatches) { $match.Groups[1].Value } |
| 112 | +
|
| 113 | +$imagePaths = @() |
| 114 | +foreach ($src in $imageSrcs) { |
| 115 | + $fileName = [System.IO.Path]::GetFileName($src) |
| 116 | + $filePath = "C:\users\<your-user-name>\downloads\TESTIMG\$filename" |
| 117 | + Invoke-WebRequest -Uri $src -OutFile $filePath |
| 118 | + $imagePaths += $filePath |
| 119 | +} |
| 120 | +
|
| 121 | +$newFolderName = $jsonCampaignResponse.campaigns[0].settings.subject_line |
| 122 | +Add-PnpFolder -Name $newFolderName -Folder "WikiDocLib" -ErrorAction Continue -Connection $connectToSP |
| 123 | +$newImageUrls = @() |
| 124 | +foreach ($imagePath in $imagePaths) { |
| 125 | + $uploadedFile = Add-PnPFile -Path $imagePath -Folder "WikiDocLib/$newFolderName" -Connection $connectToSP |
| 126 | + $newImageUrls += $uploadedFile.ServerRelativeUrl |
| 127 | +} |
| 128 | +
|
| 129 | +$updatedHtml = $bodyContent |
| 130 | +for ($i = 0; $i -lt $imageSrcs.Count; $i++) { |
| 131 | + $oldSrc = [regex]::Escape($imageSrcs[$i]) |
| 132 | + $newSrc = $newImageUrls[$i] |
| 133 | + $updatedHtml = [regex]::Replace($updatedHtml, "(<img[^>]*src=[""'])$oldSrc([""'][^>]*>)", "`$1$newSrc`$2") |
| 134 | +} |
| 135 | +
|
| 136 | +$bodyContent = $updatedHtml |
| 137 | +
|
| 138 | +Create-PublishWikiPage -connectToSP $connectToSP -pageTitle $pageTitle -bodyContent $bodyContent |
| 139 | +
|
| 140 | +``` |
| 141 | +[!INCLUDE [More about PnP PowerShell](../../docfx/includes/MORE-PNPPS.md)] |
| 142 | +*** |
| 143 | + |
| 144 | + |
| 145 | +## Contributors |
| 146 | + |
| 147 | +| Author(s) | |
| 148 | +|-----------| |
| 149 | +| R. Ali | |
| 150 | + |
| 151 | +[!INCLUDE [DISCLAIMER](../../docfx/includes/DISCLAIMER.md)] |
| 152 | +<img src="https://m365-visitor-stats.azurewebsites.net/script-samples/scripts/spo-mailchimp-integration" aria-hidden="true" /> |
0 commit comments