This commit is contained in:
@@ -61,6 +61,15 @@
|
|||||||
.PARAMETER SkipRename
|
.PARAMETER SkipRename
|
||||||
Не выполнять миграцию имён существующих списков (только создание/колонки).
|
Не выполнять миграцию имён существующих списков (только создание/колонки).
|
||||||
|
|
||||||
|
.PARAMETER WebhookToken
|
||||||
|
Bearer-токен Microsoft (JWT, без слова «Bearer») для api.tnsu.kz. Если задан — на
|
||||||
|
КАЖДЫЙ НОВЫЙ список (и «— данные», и «— согласование») оформляется вебхук-подписка
|
||||||
|
через POST https://api.tnsu.kz/Webhook/Subscribe: бэкенд подписывается на изменения
|
||||||
|
в списке, уведомления идут на https://api.tnsu.kz/Webhook/SharePoint. Уже
|
||||||
|
существующие списки не подписываются. Не задан — списки создаются как раньше, по
|
||||||
|
каждому новому выводится предупреждение (подписать вручную). Токен живёт ~1 час —
|
||||||
|
берите свежий перед запуском. В коде и репозитории токен не хранится.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
./Provision-Lists.ps1 -SiteUrl "https://tnsukz.sharepoint.com/sites/requests" `
|
./Provision-Lists.ps1 -SiteUrl "https://tnsukz.sharepoint.com/sites/requests" `
|
||||||
-ClientId "7459c965-5ed4-4673-8140-0ab8faf9db64" -Tenant "tnsukz.onmicrosoft.com" `
|
-ClientId "7459c965-5ed4-4673-8140-0ab8faf9db64" -Tenant "tnsukz.onmicrosoft.com" `
|
||||||
@@ -70,6 +79,11 @@
|
|||||||
# Следующая пара списков под архивацию, без миграции имён.
|
# Следующая пара списков под архивацию, без миграции имён.
|
||||||
./Provision-Lists.ps1 -SiteUrl "..." -ClientId "..." -Tenant "..." -Thumbprint "..." `
|
./Provision-Lists.ps1 -SiteUrl "..." -ClientId "..." -Tenant "..." -Thumbprint "..." `
|
||||||
-ListNumber 2
|
-ListNumber 2
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
# С вебхук-подпиской новых списков.
|
||||||
|
./Provision-Lists.ps1 -SiteUrl "..." -ClientId "..." -Tenant "..." -Thumbprint "..." `
|
||||||
|
-WebhookToken "eyJ0eXAiOiJKV1Qi..."
|
||||||
#>
|
#>
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory = $true)][string]$SiteUrl,
|
[Parameter(Mandatory = $true)][string]$SiteUrl,
|
||||||
@@ -78,11 +92,16 @@ param(
|
|||||||
[Parameter(Mandatory = $true)][string]$Thumbprint,
|
[Parameter(Mandatory = $true)][string]$Thumbprint,
|
||||||
[string]$FormsRoot = "$PSScriptRoot/../src/webparts/requestPortal/forms",
|
[string]$FormsRoot = "$PSScriptRoot/../src/webparts/requestPortal/forms",
|
||||||
[ValidateRange(1, 999)][int]$ListNumber = 1,
|
[ValidateRange(1, 999)][int]$ListNumber = 1,
|
||||||
[switch]$SkipRename
|
[switch]$SkipRename,
|
||||||
|
[string]$WebhookToken
|
||||||
)
|
)
|
||||||
|
|
||||||
$ErrorActionPreference = 'Stop'
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
|
# Вебхук-подписка новых списков (см. .PARAMETER WebhookToken).
|
||||||
|
$WEBHOOK_SUBSCRIBE_URL = 'https://api.tnsu.kz/Webhook/Subscribe'
|
||||||
|
$WEBHOOK_NOTIFICATION_URL = 'https://api.tnsu.kz/Webhook/SharePoint'
|
||||||
|
|
||||||
# Экранирование значений, попадающих в XML полей (Lookup/Number с точностью).
|
# Экранирование значений, попадающих в XML полей (Lookup/Number с точностью).
|
||||||
function ConvertTo-XmlSafe {
|
function ConvertTo-XmlSafe {
|
||||||
param([string]$Value)
|
param([string]$Value)
|
||||||
@@ -306,6 +325,34 @@ function Add-ColumnToList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Оформляет вебхук-подписку на список через бэкенд api.tnsu.kz. Ошибка подписки
|
||||||
|
# провизионинг НЕ останавливает: список уже создан, подписать можно и вручную.
|
||||||
|
function Register-ListWebhook {
|
||||||
|
param([string]$ListTitle)
|
||||||
|
|
||||||
|
if (-not $WebhookToken) {
|
||||||
|
Write-Warning " [!] вебхук: «$ListTitle» не подписан — не передан -WebhookToken, подпишите список вручную"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Токен могли вставить вместе со словом «Bearer» — убираем, иначе заголовок сломается.
|
||||||
|
$token = ($WebhookToken -replace '^\s*Bearer\s+', '').Trim()
|
||||||
|
$query = @(
|
||||||
|
"listName=$([uri]::EscapeDataString($ListTitle))",
|
||||||
|
"url=$([uri]::EscapeDataString($SiteUrl.TrimEnd('/')))",
|
||||||
|
"notificationUrl=$([uri]::EscapeDataString($WEBHOOK_NOTIFICATION_URL))"
|
||||||
|
) -join '&'
|
||||||
|
|
||||||
|
try {
|
||||||
|
Invoke-RestMethod -Method Post -Uri "$($WEBHOOK_SUBSCRIBE_URL)?$query" `
|
||||||
|
-Headers @{ Authorization = "Bearer $token"; Accept = '*/*' } | Out-Null
|
||||||
|
Write-Host " [+] вебхук: подписан «$ListTitle»" -ForegroundColor Green
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Warning " [!] вебхук: «$ListTitle» не подписан — $($_.Exception.Message) (подпишите список вручную)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Write-Host "Подключение к $SiteUrl (app-only) ..." -ForegroundColor Cyan
|
Write-Host "Подключение к $SiteUrl (app-only) ..." -ForegroundColor Cyan
|
||||||
Connect-PnPOnline -Url $SiteUrl -ClientId $ClientId -Tenant $Tenant -Thumbprint $Thumbprint
|
Connect-PnPOnline -Url $SiteUrl -ClientId $ClientId -Tenant $Tenant -Thumbprint $Thumbprint
|
||||||
|
|
||||||
@@ -357,12 +404,15 @@ if ($ListNumber -eq 1 -and -not $SkipRename) {
|
|||||||
# сначала все списки, потом все колонки: к моменту разрешения любого Lookup'а
|
# сначала все списки, потом все колонки: к моменту разрешения любого Lookup'а
|
||||||
# список-источник уже существует.
|
# список-источник уже существует.
|
||||||
Write-Host "`n=== Списки ===" -ForegroundColor Cyan
|
Write-Host "`n=== Списки ===" -ForegroundColor Cyan
|
||||||
|
# Созданные В ЭТОМ запуске — только их подписываем на вебхук (см. конец скрипта).
|
||||||
|
$createdLists = [System.Collections.Generic.List[string]]::new()
|
||||||
foreach ($manifest in $manifests) {
|
foreach ($manifest in $manifests) {
|
||||||
$def = Get-Content -Path $manifest.FullName -Raw -Encoding UTF8 | ConvertFrom-Json
|
$def = Get-Content -Path $manifest.FullName -Raw -Encoding UTF8 | ConvertFrom-Json
|
||||||
$listTitle = Get-NumberedListTitle -Title $def.dataListTitle -Number $ListNumber
|
$listTitle = Get-NumberedListTitle -Title $def.dataListTitle -Number $ListNumber
|
||||||
|
|
||||||
if (-not (Get-PnPList -Identity $listTitle -ErrorAction SilentlyContinue)) {
|
if (-not (Get-PnPList -Identity $listTitle -ErrorAction SilentlyContinue)) {
|
||||||
New-PnPList -Title $listTitle -Template GenericList -EnableVersioning | Out-Null
|
New-PnPList -Title $listTitle -Template GenericList -EnableVersioning | Out-Null
|
||||||
|
$createdLists.Add($listTitle)
|
||||||
Write-Host " [+] создан список «$listTitle»" -ForegroundColor Green
|
Write-Host " [+] создан список «$listTitle»" -ForegroundColor Green
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -393,5 +443,14 @@ foreach ($manifest in $manifests) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Проход 3: вебхуки — ПОСЛЕ колонок, чтобы бэкенд подписывался на уже готовый список.
|
||||||
|
# Только новые списки: существующие подписаны раньше (или вручную).
|
||||||
|
if ($createdLists.Count -gt 0) {
|
||||||
|
Write-Host "`n=== Вебхуки новых списков ===" -ForegroundColor Cyan
|
||||||
|
foreach ($listTitle in $createdLists) {
|
||||||
|
Register-ListWebhook -ListTitle $listTitle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Write-Host "`nГотово." -ForegroundColor Cyan
|
Write-Host "`nГотово." -ForegroundColor Cyan
|
||||||
Disconnect-PnPOnline
|
Disconnect-PnPOnline
|
||||||
|
|||||||
+16
-1
@@ -21,7 +21,7 @@
|
|||||||
| `Text` | однострочный текст | — |
|
| `Text` | однострочный текст | — |
|
||||||
| `Note` | многострочный текст| — |
|
| `Note` | многострочный текст| — |
|
||||||
| `Number` | число | `decimals` (знаков после запятой) |
|
| `Number` | число | `decimals` (знаков после запятой) |
|
||||||
| `Choice` | выбор из вариантов | `choices` (массив) |
|
| `Choice` | выбор из вариантов | `choices` (массив), `allowMultiple` (множественный выбор — колонка MultiChoice; тип существующей колонки скрипт не меняет) |
|
||||||
| `DateTime` | дата/время | — |
|
| `DateTime` | дата/время | — |
|
||||||
| `Boolean` | да/нет | — |
|
| `Boolean` | да/нет | — |
|
||||||
| `User` | пользователь | — |
|
| `User` | пользователь | — |
|
||||||
@@ -72,6 +72,21 @@ cd provisioning
|
|||||||
|
|
||||||
Лог: `[+]` — создано, `[=]` — уже существовало, `[~]` — переименовано, `[!]` — предупреждение.
|
Лог: `[+]` — создано, `[=]` — уже существовало, `[~]` — переименовано, `[!]` — предупреждение.
|
||||||
|
|
||||||
|
### Вебхук-подписка новых списков
|
||||||
|
|
||||||
|
Если передать `-WebhookToken "<JWT>"` (bearer-токен Microsoft для api.tnsu.kz, без
|
||||||
|
слова «Bearer»), то на каждый список, СОЗДАННЫЙ в этом запуске («— данные» и
|
||||||
|
«— согласование»), скрипт в конце отправит:
|
||||||
|
|
||||||
|
```
|
||||||
|
POST https://api.tnsu.kz/Webhook/Subscribe?listName=<список>&url=<сайт>¬ificationUrl=https://api.tnsu.kz/Webhook/SharePoint
|
||||||
|
```
|
||||||
|
|
||||||
|
Бэкенд подписывается на изменения в списке, уведомления приходят на
|
||||||
|
`/Webhook/SharePoint`. Существующие списки не подписываются. Без токена или при
|
||||||
|
ошибке запроса — предупреждение `[!] вебхук: … не подписан` (подписать вручную),
|
||||||
|
провизионинг при этом не останавливается. Токен живёт ~1 час — берите свежий.
|
||||||
|
|
||||||
## Важно про имена колонок
|
## Важно про имена колонок
|
||||||
|
|
||||||
В манифесте у колонки два имени:
|
В манифесте у колонки два имени:
|
||||||
|
|||||||
Reference in New Issue
Block a user