Попытка скопировать POST канала Teams в другой канал и не получается скопировать hostedContent.

Вопрос или проблема

У меня есть канал Teams, где мне нужно скопировать сообщения в другой канал. Я использую MS Graph API. Попытка скопировать HostedContent (3 встроенных тега img) вызывает ошибку. В совокупности они превышают предел размера потока в 4194304.

Создание сообщения без размещенного контента, а затем обновление этого сообщения 3 раза с каждым содержимым не работает.

Как мне скопировать размещенные материалы?
(было бы здорово, если бы я мог сделать новый пост от имени оригинального пользователя)

    $val="$value"
    $quot="""

    $msgbody = $msg.body.content

    $uri = "$url/teams/$srcteamid/channels/$srcchannelid/messages/$($msg.id)/hostedContents"
    $hostedContents = (Invoke-MgGraphRequest -Uri $uri -Method GET).value
    if ($hostedContents -ne $null) {
        ForEach ($hc in $hostedContents) {
            $uri = "$url/teams/$srcteamid/channels/$srcchannelid/messages/$($msg.id)/hostedContents/$($hc.id)/$val"
            Invoke-MgGraphRequest -Uri $uri -Method GET -OutputFilePath "$($hc.id).png"
        }

        $HostedContentArray = @()
        $img = 0
        $totsize = 0
        $idx = 1
        While ($idx -lt $hostedContents.Length) {
            $hc = $hostedContents[$idx]
            $contentid = $hc.id
            $imgsize = (Get-Item "$contentid.png").Length
            if ($totsize + $imgsize -le 4194304) {
                $totsize += $imgsize
                $img++
                $txt = "$url/teams/$srcteamid/channels/$srcchannelid/messages/$($msg.id)/hostedContents/$contentid/$val"
                $txt = $txt.replace(".", "\.").replace("/", "\/").replace("$", "\$")
                $patt = "src=$quot$txt$quot"
                $msgbody = $msgbody -replace $patt, "src=$quot../hostedContents/$img/$val$quot"

                $obj = @{
                    "@microsoft.graph.temporaryId" = "$img"
                    contentBytes = [System.Convert]::ToBase64String([IO.File]::ReadAllBytes("$contentid.png"))
                    contentType = "image/png"
                }
                $HostedContentArray += $obj
            }
            $idx++
        }
    }

    $msg_datetime = [TimeZoneInfo]::ConvertTimeBySystemTimeZoneId($msg.createdDateTime, 'Eastern Standard Time')
    $msg_subject = "ON $msg_datetime, $($msg.from.user.displayName) posted: $($msg.subject)"
    $uri = "$url/teams/$destteamid/channels/$destchannelid/messages"
    $params = @{
        subject = $msg_subject
        body = @{
            contentType = $msg.body.contentType
            content = $msgbody
        }
        importance = $msg.importance
        mentions = $msg.mentions
        from = $msg.from
    }
    if ($HostedContentArray.length -gt 0) {
        $params.hostedContents = $HostedContentArray
    }

    $dest_msg = Invoke-MgGraphRequest -Uri $uri -Method POST -Body $params

            $msgbody = $dest_msg.body.content
            $img = 0
            $idx = 0
            $HostedContentArray = @()
            $hc = $hostedContents[$idx]
            $contentid = $hc.id
                $img++
                $txt = "$url/teams/$srcteamid/channels/$srcchannelid/messages/$($msg.id)/hostedContents/$contentid/$val"
                $txt = $txt.replace(".", "\.").replace("/", "\/").replace("$", "\$")
                $patt = "src=$quot$txt$quot"
                $msgbody = $msgbody -replace $patt, "src=$quot../hostedContents/$img/$val$quot"

                $obj = @{
                    "@microsoft.graph.temporaryId" = "$img"
                    contentBytes = [System.Convert]::ToBase64String([IO.File]::ReadAllBytes("$contentid.png"))
                    contentType = "image/png"
                }
                $HostedContentArray += $obj

            $params = @{
                subject = $msg_subject
                body = @{
                    contentType = $msg.body.contentType
                    content = $msgbody
                }
                hostedContents = $HostedContentArray
            }
            $uri = "$url/teams/$destteamid/channels/$destchannelid/messages/$($dest_msg.id)"
            Invoke-MgGraphRequest -Uri $uri -Method PATCH -Body $params


Ответ или решение

Когда вы пытаетесь скопировать POST сообщения из одного канала Teams в другой с помощью Microsoft Graph API, могут возникнуть проблемы, связанные с ограничением размера для вложенного содержимого, особенно если у вас есть несколько изображений, которые в сумме превышают 4,194,304 байт. Давайте разберемся, как вы можете успешно перенести эти данные.

Проблема копирования HostedContent в Teams

Ваша основная проблема заключается в том, что при попытке копирования всех изображений (HostedContent) вы выходите за установленный предел размера. В данном случае это может быть связано с тем, что не удается успешно обновить POST-сообщение несколько раз, чтобы добавить все изображения.

Решение проблемы

Вот шаги, которые вы можете предпринять, чтобы облегчить процесс копирования HostedContent:

  1. Разделение содержимого: Если у вас несколько изображений, попробуйте разбить их на группы и отправлять каждую группу по отдельности, так чтобы общая длина не превышала максимальный размер потока. Например, вы можете отправлять по два изображения за раз в новом сообщении, а если вы хотите, чтобы все контенты были вместе, то создавайте новый пост с меньшим количеством изображений.

  2. Использование временного идентификатора: Убедитесь, что вы присваиваете временные идентификаторы (temporaryId) каждому изображению и что ссылки на изображения обновлены правильно в теле сообщения. Это важно для обеспечения корректного отображения изображений в новом сообщении.

  3. Контент, созданный пользователем: Чтобы сделать новый пост от имени оригинального пользователя, вы можете включить объект from в ваши параметры при отправке нового сообщения. Убедитесь, что вы используете правильные идентификаторы и данные пользователя.

Пример кода

В вашем коде уже используется подход с получением ссылок на изображения и обработкой их перед отправкой. Однако, необходимо убедиться, что отдельные запросы на изменение не превышают лимита.

Вот некоторый рефактированный код, который можно использовать:

# Начальная инициализация
$val = "$value"
$quot = """"
$msgbody = $msg.body.content

# Получение HostedContents
$uri = "$url/teams/$srcteamid/channels/$srcchannelid/messages/$($msg.id)/hostedContents"
$hostedContents = (Invoke-MgGraphRequest -Uri $uri -Method GET).value

if ($hostedContents -ne $null) {
    $HostedContentArray = @()
    $totsize = 0
    $img = 1

    foreach ($hc in $hostedContents) {
        $imgSize = (Invoke-MgGraphRequest -Uri "$url/teams/$srcteamid/channels/$srcchannelid/messages/$($msg.id)/hostedContents/$($hc.id)/$val" -Method GET -OutputFilePath "$($hc.id).png").Length
        if ($totsize + $imgSize -gt 4194304) {
            # Отправка сообщений с текущим набором изображений перед добавлением новых
            SendMessageToTeams $msgbody $HostedContentArray
            $HostedContentArray = @()  # Очистка массива для новых изображений
            $totsize = 0  # Сброс общего размера
        }

        # Добавление изображения в массив
        $totsize += $imgSize
        $contentBytes = [System.Convert]::ToBase64String([IO.File]::ReadAllBytes("$($hc.id).png"))
        $HostedContentArray += @{
            "@microsoft.graph.temporaryId" = "$img"
            contentBytes = $contentBytes
            contentType = "image/png"
        }
        $img++
    }

    # Отправка оставшихся изображений
    if ($HostedContentArray.Count -gt 0) {
        SendMessageToTeams $msgbody $HostedContentArray
    }
}

# Функция для отправки сообщения в Teams
function SendMessageToTeams($msgbody, $HostedContentArray) {
    $msg_subject = "ON $($msg.createdDateTime), $($msg.from.user.displayName) posted: $($msg.subject)"
    $uri = "$url/teams/$destteamid/channels/$destchannelid/messages"
    $params = @{
        subject = $msg_subject
        body = @{
            contentType = $msg.body.contentType
            content = $msgbody
        }
        hostedContents = $HostedContentArray
        importance = $msg.importance
        mentions = $msg.mentions
        from = $msg.from
    }

    Invoke-MgGraphRequest -Uri $uri -Method POST -Body $params
}

Заключение

Описанный подход должен помочь вам успешно перенести содержимое сообщений, сохраняя порядок и оформление. Следите за размерами и при наличии необходимости разбивайте ваши запросы. Это улучшит совместимость с ограничениями Microsoft Graph API и обеспечит корректную передачу данных.

Если у вас возникнут дополнительные вопросы или потребуется более подробная помощь, не стесняйтесь обращаться!

Оцените материал
Добавить комментарий

Капча загружается...