# Selective Deliveries

## Login as different users

We created multiple users for our app through the Mitter.io Dashboard at the beginning of this guide. If you haven’t already, take some time to create **3** or more users and copy down their IDs and auth tokens.

Now, you can obviously put up a login page to your app and use a backend server as a token server to login as a user; but for the sake of simplicity, we’ll just swap out the user credentials before building our app.

Get started by defining **3** `UserAuth` objects inside the `onCreate()` method in your `MyApp` class like this:

{% tabs %}
{% tab title="Kotlin" %}
{% code title="MyApp.kt" %}

```kotlin
val jasonAuth = UserAuth(
    userId = "8ed92f3c-0696-4513-a842-085e3cee589e",
    userAuthToken = "eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJtaXR0ZXItaW8iLCJ1c2VyVG9rZW5JZCI6IlJkZHZCNXJ5RGdPNUpvSkoiLCJ1c2VydG9rZW4iOiI5cXA1MjQyY2N1NW9lbHI3OTRzc2ltbDY3OCJ9.aonmZhZWCyIHJR6nxlNn_KSgAvdWlB4vtZgfdXbvlIvXBM5oNaUzpF3YbfAlZeyPr8_uMf8HCcoh4dVFr-lYFw"
)

val katieAuth = UserAuth(
    userId = "cb02bc00-979e-4db2-8625-116178c4ad95",
    userAuthToken = "eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJtaXR0ZXItaW8iLCJ1c2VyVG9rZW5JZCI6Ilg2ZXZKZDVHSmx1SU5URWEiLCJ1c2VydG9rZW4iOiJwdnA2MGFwa3NpYjgzY21yOGI1N2g0YmhpYSJ9.hVw0h3hmtOQlx9phWrJ7zK9an9GmXv9H481OjrbIPOmE58g86EqozHLhASwl0jdiqC5KjU1_nrIK40pmNEvY9w"
)

val samAuth = UserAuth(
    userId = "5cfe3da1-4467-49b8-8325-3e85cec31c5a",
    userAuthToken = "eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJtaXR0ZXItaW8iLCJ1c2VyVG9rZW5JZCI6IlhoSnV5dGw0OG5OSlBJVDYiLCJ1c2VydG9rZW4iOiIyamozaTdhNTA5Yzc3c2Vva2dscGdiZjBpNiJ9.BwPGV2kTdclHdRaIzqjR6yAascqvYE52tH2iLK2aDBaBZA841SM0gW0WdblxLYeAyyM-XKXIEHwM2K0xQwoh7w"
)
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}
{% code title="MyApp.java" %}

```java
UserAuth jasonAuth = new UserAuth(
    "8ed92f3c-0696-4513-a842-085e3cee589e",
    "eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJtaXR0ZXItaW8iLCJ1c2VyVG9rZW5JZCI6ImJtRlI5bWNQaDhkQnJHaWIiLCJ1c2VydG9rZW4iOiJiM2dvY2ZhZ3ZyNWlrNHJkbXJlc29wNnNlcyJ9.dlE1QOYmUJpqoh1kORm3hEI3KbBM0v8kKZQnQQwXR6TZuFiCaDQrJMlp-2dgNP1CTYCPMFYoqGctRWQ5JyNiOQ"
);

UserAuth katieAuth = new UserAuth(
    "cb02bc00-979e-4db2-8625-116178c4ad95",
    "eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJtaXR0ZXItaW8iLCJ1c2VyVG9rZW5JZCI6Ilg2ZXZKZDVHSmx1SU5URWEiLCJ1c2VydG9rZW4iOiJwdnA2MGFwa3NpYjgzY21yOGI1N2g0YmhpYSJ9.hVw0h3hmtOQlx9phWrJ7zK9an9GmXv9H481OjrbIPOmE58g86EqozHLhASwl0jdiqC5KjU1_nrIK40pmNEvY9w"
);
​
UserAuth samAuth = new UserAuth(
    "5cfe3da1-4467-49b8-8325-3e85cec31c5a",
    "eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJtaXR0ZXItaW8iLCJ1c2VyVG9rZW5JZCI6IlhoSnV5dGw0OG5OSlBJVDYiLCJ1c2VydG9rZW4iOiIyamozaTdhNTA5Yzc3c2Vva2dscGdiZjBpNiJ9.BwPGV2kTdclHdRaIzqjR6yAascqvYE52tH2iLK2aDBaBZA841SM0gW0WdblxLYeAyyM-XKXIEHwM2K0xQwoh7w"
);
```

{% endcode %}
{% endtab %}
{% endtabs %}

Next, fire up **3** emulator instances or **3** devices, whichever you prefer, each time swapping out the `userAuth` parameter on the `Mitter` object configuration defined in your `Application` class. Like this:

{% tabs %}
{% tab title="Kotlin" %}
{% code title="MyApp.kt" %}

```kotlin
mitter = Mitter(
    context = this,
    mitterConfig = mitterConfig,
    userAuth = samAuth
)
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}
{% code title="MyApp.java" %}

```java
mitter = new Mitter(
    this,
    mitterConfig,
    samAuth
);
```

{% endcode %}
{% endtab %}
{% endtabs %}

Therefore, first, you can pass `userAuth` as `jasonAuth` and run the project on one emulator instance. Then you can change the `userAuth` to `katieAuth` and then run on a different emulator instance.

This way you can get **3** different users in your **3** emulator instances, and then you can chat between the **3** in real-time.

## Implement the @username mapping

For our demo, we’ll be adding a feature where a user can mention another specific user by the `@username` notation while typing their messages, and the message will only be visible to the mentioned user and the sender.

Before we can get started on that, we need to have a local mapping of the usernames with their actual user IDs on the platform.

Define an object class (or a class with static methods, if using Java) named `UserIdProvider` and add the following piece of code, changing the user IDs and names to your actual user details.

{% tabs %}
{% tab title="Kotlin" %}
{% code title="UserIdProvider.kt" %}

```kotlin
object UserIdProvider {
    fun getUserId(username: String): String = when (username.toLowerCase()) {
        "sam" -> "5cfe3da1-4467-49b8-8325-3e85cec31c5a"
        "jason" -> "8ed92f3c-0696-4513-a842-085e3cee589e"
        "katie" -> "cb02bc00-979e-4db2-8625-116178c4ad95"
        else -> ""
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}
{% code title="UserIdProvider.java" %}

```java
public class UserIdProvider {
    public static String getUserId(String username) {
        switch (username.toLowerCase()) {
            case "sam":
                return "5cfe3da1-4467-49b8-8325-3e85cec31c5a";
            case "jason":
                return "8ed92f3c-0696-4513-a842-085e3cee589e";
            case "katie":
                return "cb02bc00-979e-4db2-8625-116178c4ad95";
            default:
                return "";
        }
    }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

Do note that these usernames are just local names that you can use to identify a user with the `@username` notation.

## Add ACL rules

Now that you’ve defined the mapping, you need to define some ACL rules that you’ll be passing along with your messages to make the selective delivery work.

Create another object class (or a plain class with static method, if using Java) called `AclUtils` and add the following piece of code:

{% tabs %}
{% tab title="Kotlin" %}
{% code title="AclUtils.kt" %}

```kotlin
object AclUtils {
    fun meAndSam(senderId: String): AppliedAclList {
        return AppliedAclList(
            plusAppliedAcls = listOf(
                AppliedAcl
                (
                    ReadMessagePrivilege(),
                    UserIdAccessorSelector(IdUtils.of(UserIdProvider.getUserId("sam")))
                ),
                AppliedAcl
                (
                    ReadMessagePrivilege(),
                    UserIdAccessorSelector(IdUtils.of(senderId))
                )
            ),
            minusAppliedAcls = emptyList()
        )
    }

    fun meAndJason(senderId: String): AppliedAclList {
        return AppliedAclList(
            plusAppliedAcls = listOf(
                AppliedAcl
                (
                    ReadMessagePrivilege(),
                    UserIdAccessorSelector(IdUtils.of(UserIdProvider.getUserId("jason")))
                ),
                AppliedAcl
                (
                    ReadMessagePrivilege(),
                    UserIdAccessorSelector(IdUtils.of(senderId))
                )
            ),
            minusAppliedAcls = emptyList()
        )
    }

    fun meAndKatie(senderId: String): AppliedAclList {
        return AppliedAclList(
            plusAppliedAcls = listOf(
                AppliedAcl
                (
                    ReadMessagePrivilege(),
                    UserIdAccessorSelector(IdUtils.of(UserIdProvider.getUserId("katie")))
                ),
                AppliedAcl
                (
                    ReadMessagePrivilege(),
                    UserIdAccessorSelector(IdUtils.of(senderId))
                )
            ),
            minusAppliedAcls = emptyList()
        )
    }

    fun getAclListFromUsername(username: String, senderId: String) = when (username) {
        "sam" -> meAndSam(senderId)
        "jason" -> meAndJason(senderId)
        "katie" -> meAndKatie(senderId)
        else -> emptyAclList()
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}
{% code title="AclUtils.java" %}

```java
public class AclUtils {
    public static AppliedAclList meAndSam(String senderId) {
        List<AppliedAcl> plusAppliedAcls = new ArrayList<>();
        List<AppliedAcl> minusAppliedAcls = new ArrayList<>();

        plusAppliedAcls.add(
            new AppliedAcl(
                new ReadMessagePrivilege(),
                new UserIdAccessorSelector(IdUtils.of(UserIdProvider.getUserId("sam"), User.class))
            )
        );
        plusAppliedAcls.add(
            new AppliedAcl(
                new ReadMessagePrivilege(),
                new UserIdAccessorSelector(IdUtils.of(senderId, User.class))
            )
        );

        return new AppliedAclList(
            plusAppliedAcls,
            minusAppliedAcls
        );
    }

    public static AppliedAclList meAndJason(String senderId) {
        List<AppliedAcl> plusAppliedAcls = new ArrayList<>();
        List<AppliedAcl> minusAppliedAcls = new ArrayList<>();

        plusAppliedAcls.add(
            new AppliedAcl(
                new ReadMessagePrivilege(),
                new UserIdAccessorSelector(IdUtils.of(UserIdProvider.getUserId("jason"), User.class))
            )
        );
        plusAppliedAcls.add(
            new AppliedAcl(
                new ReadMessagePrivilege(),
                new UserIdAccessorSelector(IdUtils.of(senderId, User.class))
            )
        );

        return new AppliedAclList(
            plusAppliedAcls,
            minusAppliedAcls
        );
    }

    public static AppliedAclList meAndKatie(String senderId) {
        List<AppliedAcl> plusAppliedAcls = new ArrayList<>();
        List<AppliedAcl> minusAppliedAcls = new ArrayList<>();

        plusAppliedAcls.add(
            new AppliedAcl(
                new ReadMessagePrivilege(),
                new UserIdAccessorSelector(IdUtils.of(UserIdProvider.getUserId("katie"), User.class))
            )
        );
        plusAppliedAcls.add(
            new AppliedAcl(
                new ReadMessagePrivilege(),
                new UserIdAccessorSelector(IdUtils.of(senderId, User.class))
            )
        );

        return new AppliedAclList(
            plusAppliedAcls,
            minusAppliedAcls
        );
    }

    public static AppliedAclList getAclListFromUsername(String username, String senderId) {
        switch (username) {
            case "sam":
                return meAndSam(senderId);
            case "jason":
                return meAndJason(senderId);
            case "katie":
                return meAndKatie(senderId);
            default:
                return new AppliedAclList(new ArrayList<AppliedAcl>(), new ArrayList<AppliedAcl>());
        }
    }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

Here, we just define some basic ACL rules based on the chosen username. You can learn more about ACLs and how to use them over [**here**](https://docs.mitter.io/platform-reference-1/acls-and-advanced-permission-model).

For example, the method `meAndSam()` provides an `AppliedAclList` object which tells Mitter.io that the message is only for Sam and the current sender to view. Anyone else in the group will be unaware of this message.

This way you can have a private conversation between users in a group of multiple users.

## Apply ACLs to your outgoing messages

The `sendTextMessage()` method that we used previously to send out messages, accepts another optional parameter called `appliedAcls` where you can pass an `AppliedAclList` object containing your ACL rules for the message you’re sending.

The goal here is to parse the input text and check if there’s an `@` symbol present in the message and then extract the username from that message to determine our ACLs.

We’ll be using our utility methods to determine the ACLs for the username that we get from the input text.

Modify your button click event to this:

{% tabs %}
{% tab title="Kotlin" %}
{% code title="MainActivity.kt" %}

```kotlin
sendButton.setOnClickListener {
    var typedInput = inputMessage?.text.toString()
    var appliedAcls = emptyAclList()

    if (typedInput.contains('@')) {
        val username = typedInput.substring(1, typedInput.indexOf(' '))
        typedInput = typedInput.substringAfter(' ')
        appliedAcls = AclUtils.getAclListFromUsername(username, mitter.getUserId())
    }

    messaging.sendTextMessage(
        channelId = channelId,
        message = typedInput,
        appliedAcls = appliedAcls,
        onValueUpdatedCallback = object : Mitter.OnValueUpdatedCallback {
            override fun onError(apiError: ApiError) {}

            override fun onSuccess() {
                inputMessage?.text?.clear()
            }
        }
    )
}
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}
{% code title="MainActivity.java" %}

```java
sendButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String typedInput = inputMessage.getText().toString();
        AppliedAclList appliedAcls = new AppliedAclList(
            new ArrayList<AppliedAcl>(),
            new ArrayList<AppliedAcl>()
        );

        if (typedInput.contains("@")) {
            String username = typedInput.substring(1, typedInput.indexOf(" "));
            typedInput = typedInput.substring(typedInput.indexOf(" "));
            appliedAcls = AclUtils.getAclListFromUsername(username, mitter.getUserId());
        }

        messaging.sendTextMessage(
            channelId,
            typedInput,
            appliedAcls,
            new Mitter.OnValueUpdatedCallback() {
                @Override
                public void onSuccess() {
                    inputMessage.getText().clear();
                }

                @Override
                public void onError(ApiError apiError) { }
            }
        );
    }
});
```

{% endcode %}
{% endtab %}
{% endtabs %}

Here, we just do a basic check for the `@` symbol, substring the text accordingly, and pass the message along with the applied ACLs to the `sendTextMessage()` method.

Now, if you run the app on all the **3** emulator instances with **3** different users, you can chat among the users and send private messages by just mentioning a user’s name prefixed with an `@` symbol.

For example, if **Katie** would like to send a message to just Jason, she can type “*@jason What’s up?*”.

This will make the message visible only to **Katie** and **Jason**. **Sam** will be totally unaware that this conversation ever happened.

![Selective delivery in action](https://94728489-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LLZR00Qt6hZ5Vke2l2g%2F-LNFsCslCk-iJI7AheSA%2F-LNFsJMTeEH43DwhLwgO%2FCleanShot-2018-09-23-at-01.gif?alt=media\&token=4588cb6b-02e3-47b5-b6d2-04705fdb49c5)

That’s how you can use ACLs to control who sees what. Feel free to define your own use cases and play around.
