Source: https://developers.woosmap.com/products/geofencing-sdk/integration/batch/

> For clean Markdown of any page, append `.md` to the page URL.

> For a complete documentation index, see https://developers.woosmap.com/llms.txt

# Batch integration



Woosmap Geofencing SDK can send events to [Batch](https://batch.com/) from different context types:
Geofences, POI, Visits and ZOI.

Whenever location events trigger, you can send custom events with associated properties to your App via a listener
method. Your App can then pass them to the Batch SDK and use the *Custom Event* trigger in the Automation and Journey composers.

## Batch Integration

### Requirements

- **Batch SDK**: Download the latest stable SDK from
   [appropriate platform page](https://doc.batch.com/download).

### Configuration

To configure your app with the Batch SDK follow the instructions on the dedicated *SDK Integration* guide on <https://doc.batch.com/>.

## Send Batch Custom events
Custom events let you track user activities and key conversions in your mobile app, and tie them back to corresponding push messaging campaigns. 

**iOS Example**

```swift
import WoosmapGeofencing
import Batch

public class DataRegion: RegionsServiceDelegate {

    // the didEnterPOIRegion() is called when a user enters in the geofence 
    public func didEnterPOIRegion(POIregion: Region) {
        
        // if you want only push to batch geofence event related to POI,
        // check first if the POIregion.origin is equal to "POI" 
        if POIregion.origin == "POI"
        {
            if let POI = POIs.getPOIbyIdStore(idstore: POIregion.identifier ?? "") as POI? {

                // Event with custom attributes
                BatchProfile.trackEvent(name: "woos_geofence_entered_event", attributes: BatchEventAttributes { data in
                  data.put(POI.idstore ?? "", forKey: "identifier")
                  data.put(POI.name ?? "", forKey: "name")
                })
            }
            else {
                // error: Related POI doesn't exist
            }
        }
    }
```

**Android Example**

```java
public class WoosRegionLogReadyListener implements Woosmap.RegionLogReadyListener {
    public void RegionLogReadyCallback(RegionLog regionLog) {

        POI poi = WoosmapDb.getInstance(getApplicationContext()).getPOIsDAO().getPOIbyStoreId(regionLog.idStore);

        String eventName = "woos_geofence_exited_event";

        if(regionLog.didEnter) {
            eventName = "woos_geofence_entered_event";
        }

        // Event with custom attributes
        BatchEventAttributes attributes = BatchEventAttributes()
          .put("identifier", poi.idStore)
          .put("name", poi.name);
        Batch.Profile.trackEvent(eventName, attributes);
    }
}
```

### Geofences Events

- Enter eventName: `woos_geofence_entered_event`
- Exit eventName: `woos_geofence_exited_event`

**Event data specification**

| Field name                         | Type     | Only if the region is a POI |
| ---------------------------------- |:---------|:---------------------------:|
| `date`                             | Datetime |                             |
| `id`                               | String   |                             |
| `latitude`                         | Double   |                             |
| `longitude`                        | Double   |                             |
| `radius`                           | Double   |                             |
| `name`                             | String   |              •              |
| `idStore`                          | String   |              •              |
| `city`                             | String   |              •              |
| `zipCode`                          | String   |              •              |
| `distance`                         | String   |              •              |
| `country_code`                     | String   |              •              |
| `address`                          | String   |              •              |
| `tags`                             | String   |              •              |
| `types`                            | String   |              •              |
| `user_properties.[field_name]`     | String   |              •              |

## React Native Integration: Send Batch Custom events from `react-native-plugin-geofencing`

[React Example project](/assets/archive/connector_react.zip)

#### Batch Integration

Follow the [Batch Implementation](https://doc.batch.com/react-native/sdk-integration/) guide in order to add Batch plugin to your project.

#### Receiving Woosmap Geofencing Region events using iOS Notification

Follow the steps below in order to capture events of geofencing SDK

***&#x31;.*** Add a new Swift class file, `GeofencingEventsReceiver.swift`, and include it in your iOS workspace with the following code.

``` swift
import Foundation
import WoosmapGeofencing
import react_native_plugin_geofencing

extension Notification.Name {
  static let updateRegions = Notification.Name("updateRegions")
  static let didEventPOIRegion = Notification.Name("didEventPOIRegion")
}

@objc(GeofencingEventsReceiver)
class GeofencingEventsReceiver: NSObject {
  @objc public func startReceivingEvent() {
    NotificationCenter.default.addObserver(self, selector: #selector(POIRegionReceivedNotification),
                                           name: .didEventPOIRegion,
                                           object: nil)
  }
  @objc func POIRegionReceivedNotification(notification: Notification) {
    if let POIregion = notification.userInfo?["Region"] as? Region{
      // YOUR CODE HERE
      if POIregion.didEnter {
        NSLog("didEnter")
        
        // if you want only push to batch geofence event related to POI,
        // check first if the POIregion.origin is equal to "POI"
        if POIregion.origin == "POI"
        {
          if let POI = POIs.getPOIbyIdStore(idstore: POIregion.identifier) as POI? {
            // Event with custom attributes
            BatchProfile.trackEvent(name: "woos_geofence_entered_event", attributes: BatchEventAttributes { data in
              data.put(POI.idstore ?? "", forKey: "identifier")
              data.put(POI.name ?? "", forKey: "name")
            })
          }
          else {
            // error: Related POI doesn't exist
          }
        }
      }
    }
  }
  // Stop receiving notification
  @objc public func stopReceivingEvent() {
    NotificationCenter.default.removeObserver(self, name: .didEventPOIRegion, object: nil)
  }
  
}
```

***&#x32;.*** Update `AppDelegate.mm` as following

``` java
GeofencingEventsReceiver * objWoosmapReceiver;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  self.moduleName = @"MarketingConnector";
  // You can add your custom initial props in the dictionary below.
  // They will be passed down to the ViewController used by React Native.
  self.initialProps = @{};

  objWoosmapReceiver = [GeofencingEventsReceiver new];
  [objWoosmapReceiver startReceivingEvent];
  
  
  ....
  ....
  ....
  
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
```

#### Receiving Woosmap Geofencing Region events using Android Broadcasts

Geofencing SDK triggers an action `com.woosmap.action.GEOFENCE_TRIGGERED` and broadcasts `regionLog` in the intent extra. The format of the data will always be as follows:

``` json
{
  "longitude": -0.1337,
  "latitude": 51.50998,
  "date": 1700824501480,
  "didenter": true,
  "identifier": "custom-region1",
  "radius": 100,
  "frompositiondetection": false,
  "eventname": "woos_geofence_exited_event",
  "spenttime": 75
}
```

Follow the steps below in order to listen to the broadcasts sent by the Woosmap Geofencing Plugin

***&#x31;.***  Add following dependencies in the `build.gradle` file of your main project.

  {% tabs react android/build.gradle %}

  {:title="Config" }
  ``` java
  repositories {
          ...
          ....
          maven { url 'https://jitpack.io' }
      }
  ```

  {% endtabs %}

***&#x32;.*** Add following dependencies in the `app/build.gradle` file of your main project.

  {% tabs react android/app/build.gradle %}

  {:title="Config" }

  ```java
    dependencies {
        ...
        ...
        implementation "androidx.room:room-runtime:2.+"
        implementation "com.batch.android:batch-sdk:2.+"
        implementation "woosmap:geofencing-core-android-sdk:core_geofence_2.+"
        implementation "com.webgeoservices.woosmapgeofencing:woosmap-mobile-sdk:4.+"
    }
  ```
  {% endtabs %}

***&#x33;.*** Add a new class GeofencingEventsReceiver.java/kt and add following code in it.

  {% tabs rect GeofencingEventsReceiver.java/kt %}

  ``` kotlin
  
  import android.content.BroadcastReceiver
  import android.content.Context
  import android.content.Intent
  import android.util.Log
  import com.batch.android.Batch
  import com.batch.android.BatchEventAttributes
  import com.webgeoservices.woosmapgeofencingcore.database.WoosmapDb
  import org.json.JSONObject
  import java.util.concurrent.ExecutorService
  import java.util.concurrent.Executors

  class GeofencingBroadcastReceiver: BroadcastReceiver() {
      val TAG: String = "GeofencingReceiver"
      private val executorService: ExecutorService = Executors.newSingleThreadExecutor()

      override fun onReceive(context: Context?, intent: Intent?) {
          Log.d(TAG, "Received broadcast")
          executorService.execute {
              try {
                  // Get region data from the intent
                  val regionData = intent?.getStringExtra("regionLog")?.let { JSONObject(it) }
                  // Fetch the POI from the db based on the identifier
                  val poi = WoosmapDb.getInstance(context).poIsDAO.getPOIbyStoreId(regionData!!.getString("identifier"))

                  if (poi != null) { //poi could be null if the entered/exited region is a custom region.

                      // Event with custom attributes
                      val attributes = BatchEventAttributes()
                          .put("identifier", poi.idStore)
                          .put("name", poi.name)
                      Batch.Profile.trackEvent(
                          regionData.getString("eventname"),
                          attributes
                      )
                  }
              } catch (ex: Exception) {
                  Log.e(TAG, ex.toString())
              }
          }
      }
  }
  ```

  ```java
  import android.content.BroadcastReceiver;
  import android.content.Context;
  import android.content.Intent;
  import android.util.Log;

  import com.batch.android.Batch;
  import com.batch.android.BatchEventAttributes;
  import com.webgeoservices.woosmapgeofencingcore.database.POI;
  import com.webgeoservices.woosmapgeofencingcore.database.WoosmapDb;

  import org.json.JSONObject;

  import java.util.concurrent.ExecutorService;
  import java.util.concurrent.Executors;

  public class GeofencingEventsReceiver extends BroadcastReceiver {
      private static final String TAG = "GeofencingReceiver";
      private final ExecutorService executorService = Executors.newSingleThreadExecutor();
      @Override
      public void onReceive(Context context, Intent intent) {
          Log.d(TAG, "Received broadcast");
          executorService.execute(() -> {
              try{
                  // Get region data from the intent
                  JSONObject regionData = new JSONObject(intent.getStringExtra("regionLog"));
                  // Fetch the POI from the db based on the identifier
                  POI poi;
                  poi = WoosmapDb.getInstance(context).getPOIsDAO().getPOIbyStoreId(regionData.getString("identifier"));
                  if (poi != null){ //poi could be null if the entered/exited region is a custom region.

                      // Event with custom attributes
                      BatchEventAttributes attributes = new BatchEventAttributes()
                              .put("identifier", poi.idStore)
                              .put("name", poi.name);
                      Batch.Profile.trackEvent(regionData.getString("eventname"), attributes);
                  }
              }
              catch (Exception ex){
                  Log.e(TAG, ex.toString());
              }
          });
      }
  }

  ```
  {% endtabs %}

***&#x34;.*** Register the newly created Broadcast Receiver from Application class.

  {% tabs react android/app/src/main/java/Your App Namespace/MainApplication.kt %}
  {:title="MainApplication.kt" }
  ``` kotlin
  class MainApplication : Application(), ReactApplication {
    lateinit var geofencingEventsReceiver: GeofencingEventsReceiver
    
    override fun onCreate() {
      super.onCreate()
      ...
      ...

        // Register the receiver with the filter
        geofencingEventsReceiver = GeofencingEventsReceiver()
        val filter = IntentFilter("com.woosmap.action.GEOFENCE_TRIGGERED")
        registerReceiver(geofencingEventsReceiver, filter, RECEIVER_EXPORTED)
    }
  }
  ```

  {% endtabs %}

### Expo Integration

*React-Native 0.60+ and Expo 43+ are required.*

If you are using Expo, skip the above steps and integrate the `@woosmap/expo-plugin-geofencing-batch` plugin. This plugin can be integrated with Expo in bare and managed workflows.

#### Installation

Start installing the `@woosmap/expo-plugin-geofencing-batch` with the package manager of your choice :

``` sh
npm install @woosmap/expo-plugin-geofencing-batch
```

``` sh
yarn install @woosmap/expo-plugin-geofencing-batch
```

Then, in your `app.json`, add the `@woosmap/expo-plugin-geofencing-batch` Expo Plugin. 

You can provide the following configuration options:

**Configurable properties**

| configuration                          | Type     | Description                 |
| -------------------------------------- |:---------|:---------------------------|
| locationAlwaysAndWhenInUsePermission   |String    | Only for ![Apple](/assets/images/geofencing-sdk/apple.png):<br/>A string to set the `NSLocationAlwaysAndWhenInUseUsageDescription` permission message.|
| locationAlwaysPermission               |String    | Only for ![Apple](/assets/images/geofencing-sdk/apple.png):<br/>A string to set the `NSLocationAlwaysUsageDescription` permission message.|
| locationWhenInUsePermission            |String    | Only for ![Apple](/assets/images/geofencing-sdk/apple.png):<br/>A string to set the `NSLocationWhenInUseUsageDescription` permission message.|
| useAndroidBackgroundLocation            |Boolean    | Only for ![Android](/assets/images/geofencing-sdk/android.png):<br/>Added `ACCESS_BACKGROUND_LOCATION` permission to manifest. This is required in case of you are using passiveTracking profile. By default this set to true|
| useAndroidBluetooth            |Boolean    | Only for ![Android](/assets/images/geofencing-sdk/android.png):<br/>Added `BLUETOOTH`, `BLUETOOTH_ADMIN` and `BLUETOOTH_SCAN`. This is required in case of you are using beaconTracking profile. By default this set to true|

Example configuration:

``` json
"plugins": [
      ...,
      [
        "@woosmap/expo-plugin-geofencing-batch",
        {
          "locationAlwaysAndWhenInUsePermission": "Allow $(PRODUCT_NAME) to use your location.",
          "locationAlwaysPermission": "Allow $(PRODUCT_NAME) to use your location.",
          "locationWhenInUsePermission": "Allow $(PRODUCT_NAME) to use your location.",
          "useAndroidBackgroundLocation": true,
          "useAndroidBluetooth": true,
        }
      ]
    ]
```

#### Build and run your application

Prebuilding your application will generate the native files necessary to create geofencing events and push them to the Batch platform.

``` sh
expo prebuild
```

Follow the steps for Batch and Woosmap Geofencing implementation in your React application to capture events for batch. 

Run your application as specified in the [Expo docs](https://docs.expo.dev/workflow/customizing/) . Note that making any changes to the configuration options will require you to prebuild and run the application again.

## Flutter Integration: Send Batch Custom events from `geofencing_flutter_plugin`

[Flutter Example project](/assets/archive/connector_flutter.zip)

#### Batch Integration

Follow the [Flutter Batch Implementation](https://doc.batch.com/flutter/sdk-integration/) guide to add the Batch plugin to your project.

#### Receiving Woosmap Geofencing Region events using iOS Notification

Follow the steps below to capture events of geofence SDK

***&#x31;.*** Add a new Swift class file, GeofencingEventsReceiver.swift and include it in your iOS workspace with the following code.

  {% tabs flutter ios/Runner/GeofencingEventsReceiver.swift %}

  ``` swift
  import Foundation
  import WoosmapGeofencing

  extension Notification.Name {
    static let updateRegions = Notification.Name("updateRegions")
    static let didEventPOIRegion = Notification.Name("didEventPOIRegion")
  }

  @objc(GeofencingEventsReceiver)
  class GeofencingEventsReceiver: NSObject {
    @objc public func startReceivingEvent() {
      NotificationCenter.default.addObserver(self, selector: #selector(POIRegionReceivedNotification),
                                            name: .didEventPOIRegion,
                                            object: nil)
    }
    @objc func POIRegionReceivedNotification(notification: Notification) {
      if let POIregion = notification.userInfo?["Region"] as? Region{
        // YOUR CODE HERE
        if POIregion.didEnter {
          NSLog("didEnter")
          
          // if you want only push to batch geofence event related to POI,
          // check first if the POIregion.origin is equal to "POI"
          if POIregion.origin == "POI"
          {
            if let POI = POIs.getPOIbyIdStore(idstore: POIregion.identifier) as POI? {
              
              // Event with custom attributes
              BatchProfile.trackEvent(name: "woos_geofence_entered_event", attributes: BatchEventAttributes { data in
                data.put(POI.idstore ?? "", forKey: "identifier")
                data.put(POI.name ?? "", forKey: "name")
              })
            }
            else {
              // error: Related POI doesn't exist
            }
          }
        }
      }
    }
    // Stop receiving notification
    @objc public func stopReceivingEvent() {
      NotificationCenter.default.removeObserver(self, name: .didEventPOIRegion, object: nil)
    }
    
  }
  ```

  {% endtabs %}

***&#x32;.*** Integrate `AppDelegate.swift` to receive SDK events

  {% tabs flutter ios/Runner/AppDelegate.swift %}

  ``` swift
  @objc class AppDelegate: FlutterAppDelegate {
      let objreciver:GeofencingEventsReceiver = GeofencingEventsReceiver()
    override func application(
      _ application: UIApplication,
      didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
      GeneratedPluginRegistrant.register(with: self)
      ...
      ...
    }
  }
  ```

  {% endtabs %}

#### Receiving Woosmap Geofencing Region events using Android Broadcasts

Geofencing SDK triggers an action `com.woosmap.action.GEOFENCE_TRIGGERED` and broadcasts `regionLog` in the intent extra.

Follow the steps below in order to listen to the broadcasts sent by the Woosmap Geofencing Plugin.

***&#x31;.*** Add the following dependencies in the `build.gradle` file of your main project.
   
  {% tabs flutter android/build.gradle %}

  ``` java
    repositories {
            ...
            ....
            maven { url 'https://jitpack.io' }
        }
  ```

  {% endtabs %}

***&#x32;.*** Add the following dependencies in the `app/build.gradle` file of your main project.

  {% tabs flutter android/app/build.gradle %}

    ``` java
    dependencies {
        ...
        ...
        implementation "androidx.room:room-runtime:2.+"
        implementation "com.batch.android:batch-sdk:2.+"
        implementation "woosmap:geofencing-core-android-sdk:core_geofence_2.+"
        implementation "com.webgeoservices.woosmapgeofencing:woosmap-mobile-sdk:4.+"
    }
    ```
  {% endtabs %}

***&#x33;.*** Add a new class GeofencingEventsReceiver.java/kt, and include the following code in it.

  {% tabs flutter GeofencingEventsReceiver.java/kt %}

  ``` kotlin
  import android.content.BroadcastReceiver
  import android.content.Context
  import android.content.Intent
  import android.util.Log
  import com.batch.android.Batch
  import com.batch.android.BatchEventAttributes
  import com.webgeoservices.woosmapgeofencingcore.database.WoosmapDb
  import org.json.JSONObject
  import java.util.concurrent.ExecutorService
  import java.util.concurrent.Executors

  class GeofencingBroadcastReceiver: BroadcastReceiver() {
      val TAG: String = "GeofencingReceiver"
      private val executorService: ExecutorService = Executors.newSingleThreadExecutor()

      override fun onReceive(context: Context?, intent: Intent?) {
          Log.d(TAG, "Received broadcast")
          executorService.execute {
              try {
                  // Get region data from the intent
                  val regionData = intent?.getStringExtra("regionLog")?.let { JSONObject(it) }
                  // Fetch the POI from the db based on the identifier
                  val poi = WoosmapDb.getInstance(context).poIsDAO.getPOIbyStoreId(regionData!!.getString("identifier"))

                  if (poi != null) { //poi could be null if the entered/exited region is a custom region.

                      // Event with custom attributes
                      val attributes = BatchEventAttributes()
                          .put("identifier", poi.idStore)
                          .put("name", poi.name)
                      Batch.Profile.trackEvent(
                          regionData.getString("eventname"),
                          attributes
                      )
                  }
              } catch (ex: Exception) {
                  Log.e(TAG, ex.toString())
              }
          }
      }
  }
  ```

  ```java
  import android.content.BroadcastReceiver;
  import android.content.Context;
  import android.content.Intent;
  import android.util.Log;

  import com.batch.android.Batch;
  import com.batch.android.BatchEventAttributes;
  import com.webgeoservices.woosmapgeofencingcore.database.POI;
  import com.webgeoservices.woosmapgeofencingcore.database.WoosmapDb;

  import org.json.JSONObject;

  import java.util.concurrent.ExecutorService;
  import java.util.concurrent.Executors;

  public class GeofencingEventsReceiver extends BroadcastReceiver {
      private static final String TAG = "GeofencingReceiver";
      private final ExecutorService executorService = Executors.newSingleThreadExecutor();
      @Override
      public void onReceive(Context context, Intent intent) {
          Log.d(TAG, "Received broadcast");
          executorService.execute(() -> {
              try{
                  // Get region data from the intent
                  JSONObject regionData = new JSONObject(intent.getStringExtra("regionLog"));
                  // Fetch the POI from the db based on the identifier
                  POI poi;
                  poi = WoosmapDb.getInstance(context).getPOIsDAO().getPOIbyStoreId(regionData.getString("identifier"));
                  if (poi != null){ //poi could be null if the entered/exited region is a custom region.

                      // Event with custom attributes
                      BatchEventAttributes attributes = new BatchEventAttributes()
                              .put("identifier", poi.idStore)
                              .put("name", poi.name);
                      Batch.Profile.trackEvent(regionData.getString("eventname"), attributes);
                  }
              }
              catch (Exception ex){
                  Log.e(TAG, ex.toString());
              }
          });
      }
  }

  ```
  {% endtabs %}

***&#x34;.*** If you already have a custom `android.app.Application` subclass registered, you can skip this step.
  
  Open your project's Android folder in Android Studio. Create a new class that subclasses `android.app.Application`. It can be named however you want, but we will call it `MainApplication` for the sake of this example.Place it in your root package.
  
  Then, add an onCreate() override. The class should look like this:

 ``` kotlin
  import android.app.Application
  class MainApplication: Application() {
      override fun onCreate() {
          super.onCreate()
      }
  }
  ```

  ``` java
  import android.app.Application;
  public class MainApplication extends Application {
      @Override
      public void onCreate() {
          super.onCreate();
      }
  }
  ```

***&#x35;.*** Register the newly created Broadcast Receiver in Application class.

  {% tabs flutter android/app/src/main/java/Your App Namespace/MainApplication.java/kt %}

  ``` kotlin
    class MainApplication : Application() {
      lateinit var geofencingEventsReceiver: GeofencingEventsReceiver
      
      override fun onCreate() {
        super.onCreate()
          // Register the receiver with the filter
          geofencingEventsReceiver = GeofencingEventsReceiver()
          val filter = IntentFilter("com.woosmap.action.GEOFENCE_TRIGGERED")
          registerReceiver(geofencingEventsReceiver, filter, RECEIVER_EXPORTED)
      }
    }
  ```

  ``` java
    public class MainApplication extends Application {
        private GeofencingEventsReceiver geofencingEventsReceiver;

        @Override
        public void onCreate() {
            super.onCreate();
            // Register the receiver with the filter
            geofencingEventsReceiver = new GeofencingEventsReceiver();
            IntentFilter filter = new IntentFilter("com.woosmap.action.GEOFENCE_TRIGGERED");
            registerReceiver(geofencingEventsReceiver, filter, RECEIVER_EXPORTED);
        }
    }
  ```

  {% endtabs %}
