当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 构建 Concept PowerShell 模块:第 2 部分

作者:精品下载站 日期:2024-12-14 06:21:06 浏览:13 分类:玩电脑

构建 Concept PowerShell 模块:第 2 部分


在之前的 Notion 教程的基础上,您学习了如何创建 Notion 集成令牌、从 Notion API 检索块以及将所有这些包装到高级 PowerShell 函数中。

与获取页面的块一样有价值,修改或更新页面上的块是构建实用工具以及与其他内容集成的垫脚石。在本教程中,学习如何通过 Notion API 添加、更新和删除块,在 PowerShell 中慢慢构建合适的 Notion API 模块!

先决条件

要按照本教程进行操作,您只需要一个 Notion 帐户和 PowerShell;这里使用的是PowerShell v7.3.7。

到处都是方块

与第一个教程一样,最好从一些精简的代码开始学习基础知识,然后再将所有内容包装成更高级的函数。要向现有页面添加新块,您将使用相同的 API 调用来检索块,但使用不同的 HTML 方法 PATCH

要告诉 Notion 您希望该块位于何处,如果您希望该块成为不同块的子级,则必须传递页面 ID 或块 ID。从下面的代码可以看出,它与检索块非常相似。差异有两点:

  1. Method 现在设置为 PATCH
  2. 有一个包含 JSON 对象的 Body 参数。标准 PowerShell 对象已创建,但使用 ConvertTo-JSON cmdlet 将最大深度设置为 100 转换为 JSON,以避免创建问题。
$APIKey     = 'secret_fMnSn52qUruc1k0M7CargoM94mgS3loo3vdVBSzq74W'
$APIURI     = 'https://api.notion.com/v1'
$APIVersion = '2022-06-28'
$GUID       = 'a2b3646d-e941-4df4-874d-56153139b618'

$Params = @{
    "Headers" = @{
        "Authorization"  = "Bearer {0}" -F $APIKey
        "Content-type"   = "application/json"
        "Notion-Version" = "{0}" -F $APIVersion
    }
    "Method"  = 'PATCH'
    "URI"     = ("{0}/blocks/{1}/children" -F $APIURI, [GUID]::new($GUID))
    "Body"    = @{
        "children" = @(
            @{
                "paragraph" = @{
                    "rich_text" = @(
                        @{
                            "text" = @{
                                "content" = "This is written by a robot!"
                            }
                        }
                    )
                }
            }
        )
    } | ConvertTo-JSON -Depth 100
}

$Result = Invoke-RestMethod @Params

使用此代码成功调用不会有任何输出,但您可以立即看到调用结果。左边是代码运行前的内容,右边是代码运行后的内容。

[玩转系统] 构建 Concept PowerShell 模块:第 2 部分

[玩转系统] 构建 Concept PowerShell 模块:第 2 部分

如果您想创建一个块作为另一个块的子块怎么办?您可以利用之前创建的 cmdlet Get-NotionBlock 来查找最后一个块 ID,并将其传递到代码中以创建新块。您要更改的代码有两行。第一个添加的代码使用先前创建的函数检索所有页面块。

接下来,您将传递 $Blocks 对象的结果,而不是传递页面 ID,但使用数组表示法通过 [-1] 表示法查找最后一个,并获取id。当您重新运行代码并进行这些更改时,最终块将有一个新的子块,如图所示。

$Blocks = Get-NotionBlock -GUID 'a2b3646de9414df4874d56153139b618'
$GUID   = $Blocks[-1].id

[玩转系统] 构建 Concept PowerShell 模块:第 2 部分

创建一个更精美的块

到目前为止,您已经创建了一个仅包含纯文本的段落块。创建一个包含其中包含的富文本对象的标注怎么样?将使用与之前相同的结构以及页面 ID,但创建一个更复杂的 JSON 对象。

使用与上面相同的代码,您将使用以下代码替换 Body 参数,这将创建标注、设置背景颜色并创建粗体初始内容。

@{
    "children" = @(
        @{
            "callout" = @{
                "rich_text" = @(
                    @{
                        "text" = @{
                            "content" = "Just a friendly reminder of the three laws of robotics."
                        }
                        "annotations" = @{
                            "bold" = $True
                        }
                    }
                )
                "color" = "blue_background"
            }
        }
    )
}

[玩转系统] 构建 Concept PowerShell 模块:第 2 部分

您可能已经注意到,其中的文本引用了机器人学三定律,但标注块在初始创建时只能支持 rich_text。值得庆幸的是,您已经学会了如何将子块附加到现有块!

要解决此问题,您将创建列表块作为标注块的子级。在此之前,您必须检索与该块关联的标注和 ID。为此,您将使用 Get-NotionBlock 函数并将结果过滤为 callout 类型,最后选择 id

$Blocks = Get-NotionBlock -GUID 'a2b3646de9414df4874d56153139b618'
$Blocks | Where-Object type -EQ 'callout' | Select-Object id

[玩转系统] 构建 Concept PowerShell 模块:第 2 部分

掌握 ID 后,制作新块,将 $GUID 值更改为您之前找到的 ID。运行代码,您将看到以下结果。

"Body" = @{
    "children" = @(
        @{
            "bulleted_list_item" = @{
                "rich_text" = @(
                    @{
                        "text" = @{
                            "content" = "A robot may not injure a human being or, through inaction, allow a human being to come to harm."
                        }
                    }
                )                
            }
        }
        @{
            "bulleted_list_item" = @{
                "rich_text" = @(  
                    @{
                        "text" = @{
                            "content" = "A robot must obey the orders given it by human beings except where such orders would conflict with the First Law."
                        }
                    }
                )
            }
        }
        @{
            "bulleted_list_item" = @{
                "rich_text" = @(  
                    @{
                        "text" = @{
                            "content" = "A robot must protect its own existence as long as such protection does not conflict with the First or Second Law."
                        }
                    }
                )
            }
        }
    )
} | ConvertTo-JSON -Depth 100

[玩转系统] 构建 Concept PowerShell 模块:第 2 部分

更新现有块

随着所有区块的创建,有必要对这三项法律提出更直接的警告。可以更新标注的内容,而不是删除和重新创建。

更改是针对 API URL 和正文代码。将 API 更改为:("{0}/blocks/{1}" -F $APIURI, [GUID]::new($GUID)),这会删除子项 从末尾开始。此 API 调用也使用 PATCH 方法。

"Body"    = @{
    "callout" = @{
        "rich_text" = @(
            @{
                "text" = @{
                    "content" = "A strong reminder of the three laws of robotics."
                }
                "annotations" = @{
                    "bold" = $True
                    "color" = 'red_background'
                }
            }
        )
    }
} | ConvertTo-JSON -Depth 100

[玩转系统] 构建 Concept PowerShell 模块:第 2 部分

移除块

完成所有这些更改后,您可能需要删除其中一项。执行此操作与之前的 API 调用类似。这次,您将使用 DELETE 方法,该方法将块(或页面)设置为存档并放入垃圾箱(使内容可恢复)。

运行以下命令以删除之前找到的 callout 块。这会将其从页面中删除。

$APIKey     = 'secret_fMnSn52qUruc1k0M7CargoM94mgS3loo3vdVBSzq74W'
$APIURI     = 'https://api.notion.com/v1'
$APIVersion = '2022-06-28'
$GUID       = '97b47389-befa-43d5-a2ee-b08f3ae602f9'

$Params = @{
    "Headers" = @{
        "Authorization"  = "Bearer {0}" -F $APIKey
        "Content-type"   = "application/json"
        "Notion-Version" = "{0}" -F $APIVersion
    }
    "Method"  = 'DELETE'
    "URI"     = ("{0}/blocks/{1}" -F $APIURI, [GUID]::new($GUID))
}

$Result = Invoke-RestMethod @Params

[玩转系统] 构建 Concept PowerShell 模块:第 2 部分

将所有内容整合在一起

与之前的教程一样,要继续构建此 PowerShell Notion 模块,需要将代码包装到高级函数中并添加到模块中。您正在创建的三个不同的函数是:

  • 创建一个新块 - New-NotionBlock
  • 更新现有块 - Set-NotionBlock
  • 删除现有块 - Remove-NotionBlock

通过New-NotionBlock函数创建新的Block

与您创建的原始高级函数类似,这里是 New-NotionBlock 函数的全部优点。重大变化是增加了对以下内容的支持:

  • What If - 将 SupportsShouldProcess=$True 添加到 CmdletBinding 声明中,允许将操作包装在 If 语句中$PSCmdlet.ShouldProcess 查看首先发生的操作。
  • 管道输入 - 对于$GUID参数,支持通过[Parameter(ValueFromPipelineByPropertyName=$True)]声明进行管道输入。
  • 管道别名 - 为了确保传入的对象 ID 传递到正确的位置,请为 $GUID 参数指定别名 ID 与管道值结合使用。

完成所有这些后,该函数现在根据页面或父块的 GUID 以及声明的内容创建一个新块。这将输出创建的块以供以后在管道中使用。

Function New-NotionBlock {
  [CmdletBinding(SupportsShouldProcess = $True)]

  Param(
    [String]$APIKey,
    [String]$APIVersion,
    [ValidateScript( { [System.URI]::IsWellFormedUriString( $_ ,[System.UriKind]::Absolute ) } )][String]$APIURI,

    [Parameter(ValueFromPipelineByPropertyName = $True)]
    [Alias("ID")]
    [ValidateScript( { Try { If ( [GUID]::Parse( $_ ) ) { $True } } Catch { $False } } )][String]$GUID,

    $Content
  )

  Process {
    $Params = @{
      "Headers" = @{
        "Authorization"  = "Bearer {0}" -F $APIKey
        "Content-type"   = "application/json"
        "Notion-Version" = "{0}" -F $APIVersion
      }
      "Method" = 'PATCH'
      "URI"    = ("{0}/blocks/{1}/children" -F $APIURI, [GUID]::new($GUID))
      "Body"   = $Content | ConvertTo-JSON -Depth 100
    }

    Write-Verbose "[Process] Params: $($Params | Out-String)"

    If ($PSCmdlet.ShouldProcess($GUID,"Adding Block")) {
      Try {
        $Result = Invoke-RestMethod @Params -ErrorAction 'Stop'
      } Catch {
        $Message = ($Error[0].ErrorDetails.Message | ConvertFrom-JSON).message

        Write-Error "Command Failed to Run: $Message"
      }

      If ($Result) {
        $Result.results
      }
    }
  }
}

使用 Set-NotionBlock 函数更新块

与创建块类似,Set-NotionBlock 函数将块的现有内容替换为您定义的新内容。该函数的结构几乎相同,唯一的变化是 API 调用本身。

Function Set-NotionBlock {
  [CmdletBinding(SupportsShouldProcess = $True)]

  Param(
    [String]$APIKey,
    [String]$APIVersion,
    [ValidateScript( { [System.URI]::IsWellFormedUriString( $_ ,[System.UriKind]::Absolute ) } )][String]$APIURI,

    [Parameter(ValueFromPipelineByPropertyName = $True)]
    [Alias("ID")]
    [ValidateScript( { Try { If ( [GUID]::Parse( $_ ) ) { $True } } Catch { $False } } )][String]$GUID,

    $Content
  )

  Process {
    $Params = @{
      "Headers" = @{
        "Authorization"  = "Bearer {0}" -F $APIKey
        "Content-type"   = "application/json"
        "Notion-Version" = "{0}" -F $APIVersion
      }
      "Method" = 'PATCH'
      "URI"    = ("{0}/blocks/{1}" -F $APIURI, [GUID]::new($GUID))
      "Body"   = $Content | ConvertTo-JSON -Depth 100
    }

    Write-Verbose "[Process] Params: $($Params | Out-String)"

    If ($PSCmdlet.ShouldProcess($GUID,"Updating Block")) {
      Try {
        $Result = Invoke-RestMethod @Params -ErrorAction 'Stop'
      } Catch {
        $Message = ($Error[0].ErrorDetails.Message | ConvertFrom-JSON).message

        Write-Error "Command Failed to Run: $Message"
      }
    }

    $Result
  }
}

使用 Remove-NotionBlock 函数删除旧块

最后,Remove-NotionBlock 函数完善了具有删除块功能的函数,但同样具有与先前函数类似的结构。主要区别在于,不输出操作结果,因为没有结果。

Function Remove-NotionBlock {
  [CmdletBinding(SupportsShouldProcess = $True)]

  Param(
    [String]$APIKey,
    [String]$APIVersion,
    [ValidateScript( { [System.URI]::IsWellFormedUriString( $_ ,[System.UriKind]::Absolute ) } )][String]$APIURI,

    [Parameter(ValueFromPipelineByPropertyName = $True)]
    [Alias("ID")]
    [ValidateScript( { Try { If ( [GUID]::Parse( $_ ) ) { $True } } Catch { $False } } )][String]$GUID
  )

  Process {
    $Params = @{
      "Headers" = @{
        "Authorization"  = "Bearer {0}" -F $APIKey
        "Content-type"   = "application/json"
        "Notion-Version" = "{0}" -F $APIVersion
      }
      "Method" = 'DELETE'
      "URI"    = ("{0}/blocks/{1}" -F $APIURI, [GUID]::new($GUID))
    }

    Write-Verbose "[Process] Params: $($Params | Out-String)"

    If ($PSCmdlet.ShouldProcess($GUID,"Removing Block")) {
      Try {
        $Result = Invoke-RestMethod @Params -ErrorAction 'Stop'
      } Catch {
        $Message = ($Error[0].ErrorDetails.Message | ConvertFrom-JSON).message

        Write-Error "Command Failed to Run: $Message"
      }
    }
  }
}

看到这一切在行动

当你把所有东西一起使用时,会是什么样子?您可以通过将内容传送到每个函数来创建块、更新块并最终删除块。在这里,在更新操作后休眠几秒钟以查看删除操作是有帮助的。

$Block = New-NotionBlock -GUID 'a2b3646de9414df4874d56153139b618' -Content @{
    "children" = @(
        @{
            "paragraph" = @{
                "rich_text" = @(
                    @{
                        "text" = @{
                            "content" = "This is written by a robot!"
                        }
                    }
                )
            }
        }
    )
} | Set-NotionBlock -Content @{
    "paragraph" = @{
        "rich_text" = @(
            @{
                "text" = @{
                    "content" = "This is UPDATED by a robot!"
                }
            }
        )
    }
}

Start-Sleep -Seconds 3

$Block | Remove-NotionBlock

下次构建 PowerShell 概念模块

通过添加这三个函数和之前创建的函数,您现在拥有一整套函数来根据需要操作块。在本系列的下一篇文章中,您将学习如何使用数据库和页面!

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯