> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.qonversion.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Handle Automation Result

> 🚧 Testing Automation
>
> Make sure you have set the environment to [Sandbox](/docs/debug-mode) when testing Automated Push Notifications.\
> **Do not forget to remove this setting for the production build.**

## Automation Delegate

Using the Automation Delegate, you can handle callbacks from Qonversion No-code Screens or Automated Notifications and adjust their behaviour.

## Set Automation delegate

To override default logic or handle callbacks, call the `setDelegate` SDK method and implement the following functions.

```swift theme={null}
Qonversion.Automations.shared().setDelegate(self)
```

```objectivec theme={null}
[[QONAutomations sharedInstance] setDelegate:self];
```

```kotlin theme={null}
Automations.shared.setDelegate(object : AutomationsDelegate {
     // Override functions here
})
```

```java theme={null}
Automations.getSharedInstance().setDelegate(new AutomationsDelegate() {
   // Override functions here
});
```

```javascript Flutter theme={null}
// This method is not relevant for Flutter
```

```javascript React Native theme={null}
Automations.getSharedInstance().setDelegate({
  // Override functions here
});
```

```csharp Unity theme={null}
Automations.GetSharedInstance().SetDelegate(delegate);
```

## Implement `AutomationsDelegate` functions

### 1. Controller for navigation (optional to implement)

This function will return a controller for IOS navigation and context for Android screen intent.

```swift theme={null}
func controllerForNavigation() -> UIViewController {
    // return controller for automations flow presentation
}
```

```objectivec theme={null}
- (UIViewController * _Nonnull)controllerForNavigation {
    // return controller for automations flow presentation
}
```

```kotlin theme={null}
override fun contextForScreenIntent(): Context {
   // Provide the context for screen intent
}
```

```java theme={null}
@NotNull
@Override
public Context contextForScreenIntent() {
    // Provide the context for screen intent
}
```

```javascript Flutter theme={null}
// This method is not relevant for Flutter
```

```javascript React Native theme={null}
// This method is not relevant for React Native
```

```csharp Unity theme={null}
// This method is not relevant for Unity
```

### 2. Automation callbacks (optional to implement)

You can handle the function that notifies you that a No-code screen is shown. You can do additional logic or track an event here:

```swift theme={null}
func automationsDidShowScreen(_ screenID: String) {
    // do some logic or track event
}
```

```objectivec theme={null}
- (void)automationsDidShowScreen:(NSString * _Nonnull)screenID {
    // do some logic or track event
}
```

```java theme={null}
@Override
public void automationsDidShowScreen(@NotNull String screenId) {
  // do some logic or track event
}
```

```kotlin theme={null}
override fun automationsDidShowScreen(screenId: String) {
		// do some logic or track event
}
```

```javascript Flutter theme={null}
StreamSubscription<String> _shownScreensStream;
_shownScreensStream = Automations.getSharedInstance().shownScreensStream.listen((event) {
  // do any logic you need
});
```

```javascript React Native theme={null}
automationsDidShowScreen(screen) {
  // do some logic or track event
}
```

```csharp Unity theme={null}
public override void OnAutomationsScreenShown(string screenId)
{
    // do some logic or track event
}
```

Then, you can handle when a No-code screen starts, fails or finishes the execution of an <a href="/docs/actions" target="_blank" rel="noopener">action</a> (same as in the previous step, you can do additional logic or just track events here):

#### 2.1. Start:

```swift theme={null}
func automationsDidStartExecuting(actionResult: Qonversion.ActionResult) {
    // do some logic or track event
}
```

```objectivec theme={null}
- (void)automationsDidStartExecutingActionResult:(QONActionResult * _Nonnull)actionResult {
    // do some logic or track event
}
```

```java theme={null}
@Override
public void automationsDidStartExecuting(@NotNull QActionResult actionResult) {
       // Ddo some logic or track event
}
```

```kotlin theme={null}
override fun automationsDidStartExecuting(actionResult: QActionResult) {
       // Do some logic or track event
 }
```

```javascript Flutter theme={null}
StreamSubscription<ActionResult> _startedActionsStream;
_startedActionsStream = Automations.getSharedInstance().startedActionsStream.listen((event) {
  // do any logic you need or track event
});
```

```javascript React Native theme={null}
automationsDidStartExecuting(actionResult) {
  // do some logic or track event
}
```

```csharp Unity theme={null}
public override void OnAutomationsActionStarted(ActionResult actionResult)
{
    // do some logic or track event  
}
```

#### 2.2. Fail

```swift theme={null}
func automationsDidFailExecuting(actionResult: Qonversion.ActionResult) {
    // do some logic or track event
}
```

```objectivec theme={null}
- (void)automationsDidFailExecutingActionResult:(QONActionResult * _Nonnull)actionResult {
    // do some logic or track event
}
```

```java theme={null}
@Override
public void automationsDidFailExecuting(@NotNull QActionResult actionResult) {
 		// Do some logic or track event
}
```

```kotlin theme={null}
override fun automationsDidFailExecuting(actionResult: QActionResult) {
     // Do some logic or track event
}
```

```javascript Flutter theme={null}
StreamSubscription<ActionResult> _failedActionsStream;
_failedActionsStream = Automations.getSharedInstance().failedActionsStream.listen((event) {
  // do any logic you need or track event
});
```

```javascript React Native theme={null}
automationsDidFailExecuting(actionResult) {
  // do some logic or track event
}
```

```csharp Unity theme={null}
public override void OnAutomationsActionFailed(ActionResult actionResult)
{
    // do some logic or track event
}
```

#### 2.3. Finish

You can use this function to get information if a user launches a purchase within the No-code screens flow. In this case, you need to check the user's entitlements ('checkEntitlements') to unlock access to your app's premium content.

```swift theme={null}
func automationsDidFinishExecuting(actionResult: Qonversion.ActionResult) {
    if actionResult.type == .purchase {
        Qonversion.shared().checkEntitlements { (resul, error) in
            // handle new entitlements here
        }
    }
}
```

```objectivec theme={null}
- (void)automationsDidFinishExecutingActionResult:(QONActionResult * _Nonnull)actionResult {
    if (actionResult.type == QONActionResultTypePurchase) {
        [[Qonversion sharedInstance] checkEntitlements:^(NSDictionary<NSString *,QONEntitlement *> * _Nonnull result, NSError * _Nullable error) {
            // handle new entitlements here
        }];
    }
}
```

```java theme={null}
@Override
public void automationsDidFinishExecuting(@NotNull QActionResult actionResult) {
  	if (actionResult.getType() == QActionResultType.Purchase) {
				Qonversion.getSharedInstance().checkEntitlements(new QonversionEntitlementsCallback() {
				    @Override
				    public void onSuccess(@NotNull Map<String, QEntitlement> entitlements) {
					      // Handle new permissions here
            }
        });
    }
}
```

```kotlin theme={null}
override fun automationsDidFinishExecuting(actionResult: QActionResult) {
  if (actionResult.type == QActionResultType.Purchase) {
		Qonversion.shared.checkEntitlements(object: QonversionEntitlementsCallback {
    	override fun onSuccess(entitlements: Map<String, QEntitlement>) {
        // Handle new entitlements here
      }
    })
  }
}
```

```javascript Flutter theme={null}
StreamSubscription<ActionResult> _finishedActionsStream;
_finishedActionsStream = Automations.getSharedInstance().finishedActionsStream.listen((event) {
  if (event.type == ActionResultType.purchase) {
    // do any logic you need
  }
});
```

```javascript React Native theme={null}
automationsDidFinishExecuting(actionResult) {
  if (actionResult.type === ActionResultType.PURCHASE) {
    Qonversion.getSharedInstance().checkEntitlements().then(entitlements => {
      // Handle new entitlements here
    });
  }
}
```

```csharp Unity theme={null}
public override void OnAutomationsActionFinished(ActionResult actionResult)
{
    // do some logic or track event
}
```

#### 2.4. Automations finished

This function is called after a No-code screen is closed.

```swift theme={null}
func automationsFinished() {
    // do any logic you needed
}
```

```objectivec theme={null}
- (void)automationsFinished {
    // do any logic you needed
}
```

```java theme={null}
@Override
 public void automationsFinished() {
		// Do any logic you needed
 }
```

```kotlin theme={null}
override fun automationsFinished() {
    // Do any logic you needed
 }
```

```javascript Flutter theme={null}
StreamSubscription<Null> _finishedAutomationsStream;
_finishedAutomationsStream =
    Automations.getSharedInstance().finishedAutomationsStream.listen((event) {
      // do any logic you need or track event
});
```

```javascript React Native theme={null}
automationsFinished() {
  // do some logic or track event
}
```

```csharp Unity theme={null}
public override void OnAutomationsFinished()
{
    // do some logic or track event
}
```

### 3. Automated push notifications events (optional to implement)

This function lets you identify the event type that triggered the push notification.

Override this method and return *false* if you want to handle the corresponding push notification click by yourself. Otherwise, Qonversion handles the event and shows linked No-code screen (if configured).

If you want to handle push notification's click result and show your screen, you need to process the Automation event, check the event type, and show the required screen. Learn more with  <a href="/docs/handling-push-notifications-on-device" target="_blank" rel="noopener">Handling Qonversion Notifications guide</a>.

```swift Swift theme={null}
func shouldHandle(_ event: QONAutomationsEvent, payload: [String : Any]) -> Bool {
    // check event.type here
    // return false if you want to handle event yourself
  
    // for example
    if event.type == .subscriptionCanceled {
        return false
    } else {
        return true
    }
}
```

```objectivec Objective-C theme={null}
- (BOOL)shouldHandleEvent:(QONAutomationsEvent *)event payload:(NSDictionary<NSString *,id> *)payload {
    // check event.type here
    // return false if you want to handle event yourself
  
    // for example
    if (event.type == QONAutomationsEventTypeSubscriptionCanceled) {
        return false;
    } else {
        return true;
    }
}
```

```kotlin Kotlin theme={null}
override fun shouldHandleEvent(
    event: AutomationsEvent,
    payload: MutableMap<String, String>
): Boolean {
    // check event.type here
    // return false if you want to handle the event on your side
  
    // for example
    if (event.type == AutomationsEventType.SubscriptionCanceled) {
        return false
    } else {
        return true
    }
}
```

```java Java theme={null}
@Override
public Boolean shouldHandleEvent(@NotNull AutomationsEvent event, @NotNull Map<String, String> payload) {
    // check event.type here
    // return false if you want to handle the event on your side
  
    // for example
    if (event.getType() == AutomationsEventType.SubscriptionCanceled) {
        return false;
    } else {
        return true;
    }
}
```

```javascript Flutter theme={null}
// Will be available soon
```

```javascript React Native theme={null}
// Will be available soon
```

```csharp Unity theme={null}
// Will be available soon
```
