Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 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
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@

## Unreleased

### Breaking Changes

- User feedback API reworked:
- Feedback no longer needs to be associated with a specific event - the only required parameter is the user message
- `SentryUserFeedback` class replaced with `SentryFeedback`
- `CaptureUserFeedback` function in `SentrySubsystem` replaced with `CaptureFeedback`
- `CreateSentryUserFeedback` function in `SentryLibrary` replaced with `CreateSentryFeedback`
- On Windows and Linux, `ToString` function of `SentryId` class now returns the ID without dashes

### Features

- Added new API for capturing user feedback ([#1051](https://github.com/getsentry/sentry-unreal/pull/1051))

### Dependencies

- Bump CLI from v2.51.1 to v2.52.0 ([#1049](https://github.com/getsentry/sentry-unreal/pull/1049))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (c) 2025 Sentry. All Rights Reserved.

#include "AndroidSentryFeedback.h"

#include "AndroidSentryId.h"

#include "Infrastructure/AndroidSentryJavaClasses.h"

FAndroidSentryFeedback::FAndroidSentryFeedback(const FString& message)
: FSentryJavaObjectWrapper(SentryJavaClasses::Feedback, "(Ljava/lang/String;)V",
*GetJString(message))
{
SetupClassMethods();
}

void FAndroidSentryFeedback::SetupClassMethods()
{
GetMessageMethod = GetMethod("getMessage", "()Ljava/lang/String;");
SetNameMethod = GetMethod("setName", "(Ljava/lang/String;)V");
GetNameMethod = GetMethod("getName", "()Ljava/lang/String;");
SetContactEmailMethod = GetMethod("setContactEmail", "(Ljava/lang/String;)V");
GetContactEmailMethod = GetMethod("getContactEmail", "()Ljava/lang/String;");
SetAssociatedEventMethod = GetMethod("setAssociatedEventId", "(Lio/sentry/protocol/SentryId;)V");
GetAssociatedEventMethod = GetMethod("getAssociatedEventId", "()Lio/sentry/protocol/SentryId;");
}

FString FAndroidSentryFeedback::GetMessage() const
{
return CallMethod<FString>(GetMessageMethod);
}

void FAndroidSentryFeedback::SetName(const FString& name)
{
CallMethod<void>(SetNameMethod, *GetJString(name));
}

FString FAndroidSentryFeedback::GetName() const
{
return CallMethod<FString>(GetNameMethod);
}

void FAndroidSentryFeedback::SetContactEmail(const FString& email)
{
CallMethod<void>(SetContactEmailMethod, *GetJString(email));
}

FString FAndroidSentryFeedback::GetContactEmail() const
{
return CallMethod<FString>(GetContactEmailMethod);
}

void FAndroidSentryFeedback::SetAssociatedEvent(const FString& eventId)
{
TSharedPtr<FAndroidSentryId> idAndroid = MakeShareable(new FAndroidSentryId(eventId));
CallMethod<void>(SetAssociatedEventMethod, idAndroid->GetJObject());
}

FString FAndroidSentryFeedback::GetAssociatedEvent() const
{
auto idAndroid = CallObjectMethod<jobject>(GetAssociatedEventMethod);
if (!idAndroid)
{
return FString();
}

TSharedPtr<FAndroidSentryId> eventId = MakeShareable(new FAndroidSentryId(*idAndroid));
return eventId->ToString();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) 2025 Sentry. All Rights Reserved.

#pragma once

#include "Interface/SentryFeedbackInterface.h"

#include "Infrastructure/AndroidSentryJavaObjectWrapper.h"

class ISentryId;

class FAndroidSentryFeedback : public ISentryFeedback, public FSentryJavaObjectWrapper
{
public:
FAndroidSentryFeedback(const FString& message);

void SetupClassMethods();

virtual FString GetMessage() const override;
virtual void SetName(const FString& name) override;
virtual FString GetName() const override;
virtual void SetContactEmail(const FString& email) override;
virtual FString GetContactEmail() const override;
virtual void SetAssociatedEvent(const FString& eventId) override;
virtual FString GetAssociatedEvent() const override;

private:
FSentryJavaMethod GetMessageMethod;
FSentryJavaMethod SetNameMethod;
FSentryJavaMethod GetNameMethod;
FSentryJavaMethod SetContactEmailMethod;
FSentryJavaMethod GetContactEmailMethod;
FSentryJavaMethod SetAssociatedEventMethod;
FSentryJavaMethod GetAssociatedEventMethod;
};

typedef FAndroidSentryFeedback FPlatformSentryFeedback;
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
#include "AndroidSentryAttachment.h"
#include "AndroidSentryBreadcrumb.h"
#include "AndroidSentryEvent.h"
#include "AndroidSentryFeedback.h"
#include "AndroidSentryId.h"
#include "AndroidSentryTransaction.h"
#include "AndroidSentryTransactionContext.h"
#include "AndroidSentryTransactionOptions.h"
#include "AndroidSentryUser.h"
#include "AndroidSentryUserFeedback.h"

#include "SentryBeforeSendHandler.h"
#include "SentryDefines.h"
Expand Down Expand Up @@ -200,12 +200,12 @@ TSharedPtr<ISentryId> FAndroidSentrySubsystem::CaptureEnsure(const FString& type
return MakeShareable(new FAndroidSentryId(*id));
}

void FAndroidSentrySubsystem::CaptureUserFeedback(TSharedPtr<ISentryUserFeedback> userFeedback)
void FAndroidSentrySubsystem::CaptureFeedback(TSharedPtr<ISentryFeedback> feedback)
{
TSharedPtr<FAndroidSentryUserFeedback> userFeedbackAndroid = StaticCastSharedPtr<FAndroidSentryUserFeedback>(userFeedback);
TSharedPtr<FAndroidSentryFeedback> feedbackAndroid = StaticCastSharedPtr<FAndroidSentryFeedback>(feedback);

FSentryJavaObjectWrapper::CallStaticMethod<void>(SentryJavaClasses::Sentry, "captureUserFeedback", "(Lio/sentry/UserFeedback;)V",
userFeedbackAndroid->GetJObject());
FSentryJavaObjectWrapper::CallStaticObjectMethod<jobject>(SentryJavaClasses::Sentry, "captureFeedback", "(Lio/sentry/protocol/Feedback;)Lio/sentry/protocol/SentryId;",
feedbackAndroid->GetJObject());
}

void FAndroidSentrySubsystem::SetUser(TSharedPtr<ISentryUser> user)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class FAndroidSentrySubsystem : public ISentrySubsystem
virtual TSharedPtr<ISentryId> CaptureEvent(TSharedPtr<ISentryEvent> event) override;
virtual TSharedPtr<ISentryId> CaptureEventWithScope(TSharedPtr<ISentryEvent> event, const FSentryScopeDelegate& onConfigureScope) override;
virtual TSharedPtr<ISentryId> CaptureEnsure(const FString& type, const FString& message) override;
virtual void CaptureUserFeedback(TSharedPtr<ISentryUserFeedback> userFeedback) override;
virtual void CaptureFeedback(TSharedPtr<ISentryFeedback> feedback) override;
virtual void SetUser(TSharedPtr<ISentryUser> user) override;
virtual void RemoveUser() override;
virtual void SetContext(const FString& key, const TMap<FString, FSentryVariant>& values) override;
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const FSentryJavaClass SentryJavaClasses::SentryId = FSentryJavaClass { "io/s
const FSentryJavaClass SentryJavaClasses::Scope = FSentryJavaClass { "io/sentry/IScope", ESentryJavaClassType::External };
const FSentryJavaClass SentryJavaClasses::ScopeImpl = FSentryJavaClass { "io/sentry/Scope", ESentryJavaClassType::External };
const FSentryJavaClass SentryJavaClasses::User = FSentryJavaClass { "io/sentry/protocol/User", ESentryJavaClassType::External };
const FSentryJavaClass SentryJavaClasses::UserFeedback = FSentryJavaClass { "io/sentry/UserFeedback", ESentryJavaClassType::External };
const FSentryJavaClass SentryJavaClasses::Feedback = FSentryJavaClass { "io/sentry/protocol/Feedback", ESentryJavaClassType::External };
const FSentryJavaClass SentryJavaClasses::Message = FSentryJavaClass { "io/sentry/protocol/Message", ESentryJavaClassType::External };
const FSentryJavaClass SentryJavaClasses::SentryLevel = FSentryJavaClass { "io/sentry/SentryLevel", ESentryJavaClassType::External };
const FSentryJavaClass SentryJavaClasses::SentryHint = FSentryJavaClass { "io/sentry/Hint", ESentryJavaClassType::External };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ struct SentryJavaClasses
const static FSentryJavaClass Scope;
const static FSentryJavaClass ScopeImpl;
const static FSentryJavaClass User;
const static FSentryJavaClass UserFeedback;
const static FSentryJavaClass Feedback;
const static FSentryJavaClass Message;
const static FSentryJavaClass SentryLevel;
const static FSentryJavaClass SentryHint;
Expand Down
70 changes: 70 additions & 0 deletions plugin-dev/Source/Sentry/Private/Apple/AppleSentryFeedback.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c) 2025 Sentry. All Rights Reserved.

#include "AppleSentryFeedback.h"

#include "AppleSentryId.h"

#include "Convenience/AppleSentryInclude.h"
#include "Convenience/AppleSentryMacro.h"

FAppleSentryFeedback::FAppleSentryFeedback(const FString& message)
: Message(message)
{
}

FAppleSentryFeedback::~FAppleSentryFeedback()
{
// Put custom destructor logic here if needed
}

FString FAppleSentryFeedback::GetMessage() const
{
return Message;
}

void FAppleSentryFeedback::SetName(const FString& name)
{
Name = name;
}

FString FAppleSentryFeedback::GetName() const
{
return Name;
}

void FAppleSentryFeedback::SetContactEmail(const FString& email)
{
Email = email;
}

FString FAppleSentryFeedback::GetContactEmail() const
{
return Email;
}

void FAppleSentryFeedback::SetAssociatedEvent(const FString& eventId)
{
EventId = eventId;
}

FString FAppleSentryFeedback::GetAssociatedEvent() const
{
return EventId;
}

SentryFeedback* FAppleSentryFeedback::CreateSentryFeedback(TSharedPtr<FAppleSentryFeedback> feedback)
{
SentryId* id = nil;
if (!feedback->EventId.IsEmpty())
{
TSharedPtr<FAppleSentryId> idIOS = MakeShareable(new FAppleSentryId(feedback->EventId));
id = idIOS->GetNativeObject();
}

return [[SENTRY_APPLE_CLASS(SentryFeedback) alloc] initWithMessage:feedback->Message.GetNSString()
name:feedback->Name.GetNSString()
email:feedback->Email.GetNSString()
source:SentryFeedbackSourceCustom
associatedEventId:id
attachments:nil];
}
32 changes: 32 additions & 0 deletions plugin-dev/Source/Sentry/Private/Apple/AppleSentryFeedback.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) 2025 Sentry. All Rights Reserved.

#pragma once

#include "Interface/SentryFeedbackInterface.h"

@class SentryFeedback;

class FAppleSentryFeedback : public ISentryFeedback
{
public:
FAppleSentryFeedback(const FString& message);
virtual ~FAppleSentryFeedback() override;

virtual FString GetMessage() const override;
virtual void SetName(const FString& name) override;
virtual FString GetName() const override;
virtual void SetContactEmail(const FString& email) override;
virtual FString GetContactEmail() const override;
virtual void SetAssociatedEvent(const FString& eventId) override;
virtual FString GetAssociatedEvent() const override;

static SentryFeedback* CreateSentryFeedback(TSharedPtr<FAppleSentryFeedback> feedback);

private:
FString Message;
FString Name;
FString Email;
FString EventId;
};

typedef FAppleSentryFeedback FPlatformSentryFeedback;
Loading
Loading