Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions sentry-api-client/Public/Get-SentryFeedback.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
function Get-SentryFeedback {
<#
.SYNOPSIS
Retrieves user feedback from Sentry.

.DESCRIPTION
Fetches user feedback submissions, which are stored as issue-platform occurrences
with the 'feedback' category. Supports narrowing the results with a free-text query
(which matches the feedback message) and optionally enriches each result with the
associated event ID resolved from the feedback issue's latest event.

.PARAMETER Query
Optional free-text query appended to 'issue.category:feedback'. Matches the feedback
message, so a unique token embedded in the message can be used to locate a single
submission.

.PARAMETER StatsPeriod
Relative time period (e.g. '24h', '7d', '14d'). Default is '24h'.

.PARAMETER Limit
Maximum number of feedback submissions to return. Default is 100.

.PARAMETER Cursor
Pagination cursor for retrieving subsequent pages of results.

.PARAMETER IncludeAssociatedEvent
If specified, resolves each feedback issue's latest event and attaches an
'associatedEventId' property (from contexts.feedback.associated_event_id).

.EXAMPLE
Get-SentryFeedback -Query 'integration-test-abc123'

.EXAMPLE
Get-SentryFeedback -Query 'integration-test-abc123' -IncludeAssociatedEvent
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$Query,

[Parameter(Mandatory = $false)]
[string]$StatsPeriod = '24h',

[Parameter(Mandatory = $false)]
[int]$Limit = 100,

[Parameter(Mandatory = $false)]
[string]$Cursor,

[Parameter(Mandatory = $false)]
[switch]$IncludeAssociatedEvent
)

$QueryParts = @('issue.category:feedback')
if ($Query) {
$QueryParts += $Query
}

$QueryParams = @{
query = $QueryParts -join ' '
statsPeriod = $StatsPeriod
limit = $Limit
}

if ($Cursor) {
$QueryParams.cursor = $Cursor
}

$QueryString = Build-QueryString -Parameters $QueryParams
$Uri = Get-SentryOrganizationUrl -Resource "issues/" -QueryString $QueryString

try {
$Response = @(Invoke-SentryApiRequest -Uri $Uri -Method 'GET')
}
catch {
Write-Error "Failed to retrieve feedback - $_"
throw
}

if ($IncludeAssociatedEvent) {
foreach ($item in $Response) {
$associatedEventId = $null
try {
$LatestUri = Get-SentryOrganizationUrl -Resource "issues/$($item.id)/events/latest/"
$LatestEvent = Invoke-SentryApiRequest -Uri $LatestUri -Method 'GET'
$associatedEventId = $LatestEvent.contexts.feedback.associated_event_id
}
catch {
Write-Debug "Failed to resolve latest event for feedback $($item.id) - $_"
}
$item['associatedEventId'] = $associatedEventId
}
}

return $Response
Comment thread
cursor[bot] marked this conversation as resolved.
Resolved
}
Comment thread
cursor[bot] marked this conversation as resolved.
Resolved
1 change: 1 addition & 0 deletions sentry-api-client/SentryApiClient.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
'Get-SentryEvent',
'Get-SentryEventAttachments',
'Get-SentryEventsByTag',
'Get-SentryFeedback',
'Get-SentryLogs',
'Get-SentryLogsByAttribute',
'Get-SentryMetrics',
Expand Down
53 changes: 52 additions & 1 deletion utils/Integration.TestUtils.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -614,5 +614,56 @@ function Get-SentryTestReplayRecordingSegments {
throw "Recording segments for replay $ReplayId not found in Sentry within $TimeoutSeconds seconds: $lastError"
}

function Get-SentryTestFeedback {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$MessageContains,

[Parameter()]
[int]$TimeoutSeconds = 300
)

Write-Host "Fetching Sentry feedback matching: $MessageContains" -ForegroundColor Yellow
$progressActivity = "Waiting for Sentry feedback matching $MessageContains"

$startTime = Get-Date
$endTime = $startTime.AddSeconds($TimeoutSeconds)
$lastError = $null

try {
do {
$feedback = $null
$elapsedSeconds = [int]((Get-Date) - $startTime).TotalSeconds
$percentComplete = [math]::Min(100, ($elapsedSeconds / $TimeoutSeconds) * 100)

Write-Progress -Activity $progressActivity -Status "Elapsed: $elapsedSeconds/$TimeoutSeconds seconds" -PercentComplete $percentComplete

try {
$result = @(Get-SentryFeedback -Query $MessageContains -IncludeAssociatedEvent |
Where-Object { $_.metadata.message -like "*$MessageContains*" })
$result.Count | Should -Be 1
$feedback = $result[0]
} catch {
$lastError = $_.Exception.Message
Write-Debug "Feedback matching $MessageContains not found yet: $lastError"
}

if ($feedback) {
Write-Host "Feedback $($feedback.id) fetched from Sentry" -ForegroundColor Green
$feedback | ConvertTo-Json -Depth 10 | Out-File -FilePath (Get-OutputFilePath "feedback-$($feedback.id).json")
return $feedback
}

Start-Sleep -Milliseconds 500
$currentTime = Get-Date
} while ($currentTime -lt $endTime)
} finally {
Write-Progress -Activity $progressActivity -Completed
}

throw "Feedback matching $MessageContains not found in Sentry within $TimeoutSeconds seconds: $lastError"
}

# Export module functions
Export-ModuleMember -Function Invoke-CMakeConfigure, Invoke-CMakeBuild, Set-OutputDir, Get-OutputFilePath, Get-EventIds, Get-SentryTestEvent, Get-SentryTestEventAttachments, Get-SentryTestLog, Get-SentryTestMetric, Get-SentryTestTransaction, Get-SentryTestReplay, Get-SentryTestReplayRecordingSegments, Get-PackageAumid
Export-ModuleMember -Function Invoke-CMakeConfigure, Invoke-CMakeBuild, Set-OutputDir, Get-OutputFilePath, Get-EventIds, Get-SentryTestEvent, Get-SentryTestEventAttachments, Get-SentryTestLog, Get-SentryTestMetric, Get-SentryTestTransaction, Get-SentryTestReplay, Get-SentryTestReplayRecordingSegments, Get-SentryTestFeedback, Get-PackageAumid
Loading