

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# SDK Pesan Klien Obrolan IVS: Tutorial Coroutines Kotlin Bagian 1: Ruang Obrolan
<a name="chat-sdk-kotlin-tutorial-chat-rooms"></a>

Ini adalah bagian pertama dari tutorial dua bagian. Anda akan mempelajari hal-hal penting dalam bekerja menggunakan SDK Perpesanan Obrolan Amazon IVS dengan membangun aplikasi Android yang berfungsi sepenuhnya menggunakan bahasa pemrograman [Kotlin](https://kotlinlang.org/) dan [coroutine](https://kotlinlang.org/docs/coroutines-overview.html). Kami menyebut aplikasi itu *Chatterbox*.

Sebelum Anda memulai modul, luangkan beberapa menit untuk membiasakan diri dengan prasyarat, konsep utama di balik token obrolan, dan server backend yang diperlukan untuk membuat ruang obrolan.

Tutorial ini dibuat untuk para developer Android berpengalaman yang baru mengenal SDK Perpesanan Obrolan IVS. Anda harus merasa nyaman dengan bahasa pemrograman Kotlin dan membuat UIs di platform Android.

Bagian pertama dari tutorial ini dipecah menjadi beberapa bagian:

1. [Menyiapkan Authentication/Authorization Server Lokal](#chat-kotlin-rooms-auth-server)

1. [Membuat Proyek Chatterbox](#chat-kotlin-rooms-chatterbox)

1. [Hubungkan dengan Ruang Obrolan dan Amati Pembaruan Koneksi](#chat-kotlin-rooms-connect)

1. [Membangun Penyedia Token](#chat-kotlin-rooms-token-provider)

1. [Langkah Berikutnya](#chat-kotlin-rooms-next-steps)

Untuk dokumentasi SDK lengkap, mulailah dengan [Amazon IVS Chat Client Messaging SDK](chat-sdk.md) (di sini, di *Panduan Pengguna Obrolan Amazon IVS*) dan [Pesan Klien Obrolan: SDK for Android Referensi](https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/latest/) (aktif). GitHub

## Prasyarat
<a name="chat-kotlin-rooms-prerequisites"></a>
+ Kenali Kotlin dan cara membuat aplikasi di platform Android. Jika Anda tidak terbiasa membuat aplikasi untuk Android, pelajari dasar-dasarnya dalam panduan [Membangun aplikasi pertama Anda](https://developer.android.com/codelabs/basic-android-kotlin-compose-first-app#0) untuk para developer Android.
+ Baca dan pahami [Memulai Obrolan Amazon IVS](getting-started-chat.md).
+ Buat pengguna AWS IAM dengan kemampuan `CreateChatToken` dan `CreateRoom` yang ditentukan dalam kebijakan IAM yang ada. (Lihat [Memulai Obrolan Amazon IVS](getting-started-chat.md)).
+ Pastikan secret/access kunci untuk pengguna ini disimpan dalam file kredensial AWS. Untuk instruksinya, lihat [Panduan Pengguna AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) (terutama [Pengaturan file konfigurasi dan kredensial](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html)).
+ Buat ruang obrolan dan simpan ARN-nya. Lihat [Memulai Obrolan Amazon IVS](getting-started-chat.md). (Jika Anda tidak menyimpan ARN, Anda dapat mencarinya nanti dengan konsol atau API Obrolan.)

## Menyiapkan Authentication/Authorization Server Lokal
<a name="chat-kotlin-rooms-auth-server"></a>

Server backend Anda akan bertanggung jawab untuk membuat ruang obrolan dan menghasilkan token obrolan yang diperlukan SDK Android Obrolan IVS guna mengautentikasi dan mengotorisasi klien untuk ruang obrolan Anda.

Lihat [Membuat Token Obrolan](getting-started-chat-auth.md) di *Memulai Obrolan Amazon IVS*. Seperti yang ditunjukkan pada diagram alur di sana, aplikasi sisi server Anda bertanggung jawab untuk membuat token obrolan. Hal ini berarti aplikasi Anda harus menyediakan caranya sendiri untuk menghasilkan token obrolan dengan memintanya dari aplikasi sisi server Anda.

Kami menggunakan kerangka kerja [Ktor](https://ktor.io/) untuk membuat server lokal langsung yang mengelola pembuatan token obrolan menggunakan lingkungan AWS lokal Anda. 

Pada titik ini, kami berharap Anda telah menyiapkan kredensial AWS Anda dengan benar. Untuk step-by-step petunjuknya, lihat [Menyiapkan kredensial sementara AWS dan Wilayah AWS untuk pengembangan](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-credentials.html).

Buat direktori baru dan beri nama `chatterbox`, lalu di dalamnya, buat direktori lain yang diberi nama `auth-server`*.*

Folder server kita akan memiliki struktur sebagai berikut:

```
- auth-server
  - src
    - main
      - kotlin
        - com
          - chatterbox
            - authserver
              - Application.kt
       - resources
         - application.conf
         - logback.xml
   - build.gradle.kts
```

*Catatan: Anda dapat langsung kode copy/paste di sini ke file yang direferensikan.*

Selanjutnya, kita menambahkan semua dependensi dan plugin yang diperlukan agar server autentikasi berfungsi:

**Skrip Kotlin:**

```
// ./auth-server/build.gradle.kts

plugins {
   application
   kotlin("jvm")
   kotlin("plugin.serialization").version("1.7.10")
}

application {   
   mainClass.set("io.ktor.server.netty.EngineMain")
}

dependencies {
   implementation("software.amazon.awssdk:ivschat:2.18.1")
   implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.20")

   implementation("io.ktor:ktor-server-core:2.1.3")
   implementation("io.ktor:ktor-server-netty:2.1.3")
   implementation("io.ktor:ktor-server-content-negotiation:2.1.3")
   implementation("io.ktor:ktor-serialization-kotlinx-json:2.1.3")

   implementation("ch.qos.logback:logback-classic:1.4.4")
}
```

Sekarang kita perlu menyiapkan fungsionalitas pembuatan log untuk server autentikasi. (Untuk informasi selengkapnya, lihat [Konfigurasikan pembuat log](https://ktor.io/docs/logging.html#configure-logger).)

**XML:**

```
// ./auth-server/src/main/resources/logback.xml

<configuration>
   <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
      <encoder>
         <pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
      </encoder>
   </appender>
   <root level="trace">
      <appender-ref ref="STDOUT"/>
   </root>
   <logger name="org.eclipse.jetty" level="INFO"/>
   <logger name="io.netty" level="INFO"/>
</configuration>
```

Server [Ktor](https://ktor.io/docs/welcome.html) memerlukan pengaturan konfigurasi, yang dimuat dari file `application.*` di direktori `resources` secara otomatis, sehingga kita menambahkannya juga. (Untuk informasi selengkapnya, lihat [Konfigurasi dalam file](https://ktor.io/docs/configurations.html#configuration-file).)

**HOCON:**

```
// ./auth-server/src/main/resources/application.conf

ktor {
   deployment {
      port = 3000
   }
   application {
      modules = [ com.chatterbox.authserver.ApplicationKt.main ]
   }
}
```

Terakhir, mari kita implementasikan server kita:

**Kotlin:**

```
// ./auth-server/src/main/kotlin/com/chatterbox/authserver/Application.kt

package com.chatterbox.authserver

import io.ktor.http.*
import io.ktor.serialization.kotlinx.json.*
import io.ktor.server.application.*
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import software.amazon.awssdk.services.ivschat.IvschatClient
import software.amazon.awssdk.services.ivschat.model.CreateChatTokenRequest

@Serializable
data class ChatTokenParams(var userId: String, var roomIdentifier: String)

@Serializable
data class ChatToken(
   val token: String,
   val sessionExpirationTime: String,
   val tokenExpirationTime: String,
)

fun Application.main() {
   install(ContentNegotiation) {
      json(Json)
   }

   routing {
      post("/create_chat_token") {
         val callParameters = call.receive<ChatTokenParams>()
         val request = CreateChatTokenRequest.builder().roomIdentifier(callParameters.roomIdentifier)
            .userId(callParameters.userId).build()
         val token = IvschatClient.create()
            .createChatToken(request)

         call.respond(
            ChatToken(
                token.token(),
                token.sessionExpirationTime().toString(),
                token.tokenExpirationTime().toString()
            )
         )
      }
   }
}
```

## Membuat Proyek Chatterbox
<a name="chat-kotlin-rooms-chatterbox"></a>

Untuk membuat proyek Android, instal dan buka [Android Studio](https://developer.android.com/studio).

Ikuti langkah-langkah yang tercantum dalam [Panduan Membuat Proyek](https://developer.android.com/studio/projects/create-project) Android yang resmi. 
+ Di [Pilih proyek Anda](https://developer.android.com/studio/projects/create-project), pilih templat proyek **Aktivitas Kosong** untuk aplikasi Chatterbox kami.
+ Di [Konfigurasikan proyek Anda](https://developer.android.com/studio/projects/create-project#configure), pilih nilai berikut untuk bidang konfigurasi:
  + **Nama**: Aplikasi Saya
  + **Nama paket**: com.chatterbox.myapp
  + **Simpan lokasi**: arahkan ke direktori `chatterbox` yang dibuat di langkah sebelumnya
  + **Bahasa**: Kotlin
  + **Tingkat API minimum**: API 21: Android 5.0 (Lollipop)

Setelah menentukan semua parameter konfigurasi dengan benar, struktur file kita di dalam folder `chatterbox` akan terlihat seperti berikut:

```
- app
  - build.gradle
  ...
- gradle
- .gitignore
- build.gradle
- gradle.properties
- gradlew
- gradlew.bat
- local.properties
- settings.gradle
- auth-server
  - src
    - main
      - kotlin
        - com
          - chatterbox
            - authserver
              - Application.kt
       - resources
         - application.conf
         - logback.xml
   - build.gradle.kts
```

Sekarang kita memiliki proyek Android yang berfungsi, kita dapat menambahkan [com.amazonaws: ivs-chat-messaging dan [org.jetbrains.kotlinx](https://github.com/Kotlin/kotlinx.coroutines):](https://mvnrepository.com/artifact/com.amazonaws/ivs-chat-messaging) ke dependensi kita. kotlinx-coroutines-core `build.gradle` (Untuk informasi selengkapnya tentang kit alat build [Gradle](https://gradle.org/), lihat [Mengonfigurasi build Anda](https://developer.android.com/build).) 

**Catatan:** Di bagian atas setiap cuplikan kode, ada jalur ke file tempat Anda harus membuat perubahan dalam proyek. Jalur tersebut bersifat relatif terhadap root proyek.

**Kotlin:**

```
// ./app/build.gradle

plugins {
// ...
}

android {
// ...
}

dependencies {
    implementation 'com.amazonaws:ivs-chat-messaging:1.1.0'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'

// ...
}
```

Setelah dependensi baru ditambahkan, jalankan **Sinkronkan Proyek dengan File Gradle** di Android Studio untuk menyinkronkan proyek dengan dependensi baru. (Untuk informasi selengkapnya, lihat [Menambahkan dependensi build](https://developer.android.com/build/dependencies).)

Agar mudah menjalankan server autentikasi (yang dibuat di bagian sebelumnya) dari root proyek, kita memasukkannya sebagai modul baru di `settings.gradle`. (Untuk informasi selengkapnya, lihat [Menyusun dan Membangun Komponen Perangkat Lunak dengan Gradle](https://docs.gradle.org/current/userguide/multi_project_builds.html).)

**Skrip Kotlin:**

```
// ./settings.gradle

// ...

rootProject.name = "My App"
include ':app'
include ':auth-server'
```

Mulai sekarang, karena `auth-server` disertakan dalam proyek Android, Anda dapat menjalankan server autentikasi dengan perintah berikut dari root proyek:

**Shell:**

```
./gradlew :auth-server:run         
```

## Hubungkan dengan Ruang Obrolan dan Amati Pembaruan Koneksi
<a name="chat-kotlin-rooms-connect"></a>

Untuk membuka koneksi ruang obrolan, kita menggunakan [panggilan balik siklus hidup aktivitas onCreate()](https://developer.android.com/guide/components/activities/activity-lifecycle), yang diaktifkan saat aktivitas pertama kali dibuat. [ChatRoom Konstruktor](https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/1.0.0/-amazon%20-i-v-s%20-chat%20-messaging%20-s-d-k%20for%20-android/com.amazonaws.ivs.chat.messaging/-chat-room/index.html) mengharuskan kami untuk menyediakan `region` dan `tokenProvider` membuat instance koneksi ruangan.

**Catatan:** Fungsi `fetchChatToken` dalam cuplikan di bawah ini akan diimplementasikan di [bagian berikutnya](#chat-kotlin-rooms-token-provider).

**Kotlin:**

```
// ./app/src/main/java/com/chatterbox/myapp/MainActivity.kt

package com.chatterbox.myapp
// ...

// AWS region of the room that was created in Getting Started with Amazon IVS Chat
const val REGION = "us-west-2"

class MainActivity : AppCompatActivity() {
    private var room: ChatRoom? = null
    // ...

   override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      setContentView(R.layout.activity_main)

      // Create room instance
      room = ChatRoom(REGION, ::fetchChatToken)
   }

// ...
}
```

Menampilkan dan bereaksi terhadap perubahan dalam koneksi ruang obrolan adalah bagian penting dari pembuatan aplikasi obrolan, seperti `chatterbox`. Sebelum kita dapat mulai berinteraksi dengan ruang tersebut, kita harus berlangganan peristiwa status koneksi ruang obrolan untuk mendapatkan pembaruan.

Di SDK Obrolan untuk coroutine, [https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/1.0.0/-amazon%20-i-v-s%20-chat%20-messaging%20-s-d-k%20for%20-android/com.amazonaws.ivs.chat.messaging/-chat-room/index.html](https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/1.0.0/-amazon%20-i-v-s%20-chat%20-messaging%20-s-d-k%20for%20-android/com.amazonaws.ivs.chat.messaging/-chat-room/index.html) mengharapkan kami untuk menangani peristiwa siklus hidup ruang di [Flow](https://kotlinlang.org/docs/flow.html). Untuk saat ini, fungsi tersebut hanya akan mencatat pesan konfirmasi, ketika diinvokasi:

**Kotlin:**

```
// ./app/src/main/java/com/chatterbox/myapp/MainActivity.kt

package com.chatterbox.myapp
// ...

const val TAG = "Chatterbox-MyApp"

class MainActivity : AppCompatActivity() {
// ...

    override fun onCreate(savedInstanceState: Bundle?) {
        // ...

        // Create room instance
        room = ChatRoom(REGION, ::fetchChatToken).apply {
            lifecycleScope.launch {
                stateChanges().collect { state ->
                    Log.d(TAG, "state change to $state")
                }
            }

            lifecycleScope.launch {
                receivedMessages().collect { message ->
                    Log.d(TAG, "messageReceived $message")
                }
            }

            lifecycleScope.launch {
                receivedEvents().collect { event ->
                    Log.d(TAG, "eventReceived $event")
                }
            }

            lifecycleScope.launch {
                deletedMessages().collect { event ->
                    Log.d(TAG, "messageDeleted $event")
                }
            }

            lifecycleScope.launch {
                disconnectedUsers().collect { event ->
                    Log.d(TAG, "userDisconnected $event")
                }
            }
        }
    }
}
```

Setelah ini, kita perlu menyediakan kemampuan untuk membaca status koneksi ruang. Kita akan menyimpannya di [properti](https://kotlinlang.org/docs/properties.html) `MainActivity.kt` dan menginisialisasinya ke status TERPUTUS default untuk ruang (lihat `state` `ChatRoom` di [Referensi SDK Android Obrolan IVS](https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/latest/)). Agar tetap dapat memperbarui status lokal, kita perlu mengimplementasikan fungsi state-updater; sebut saja `updateConnectionState`:

**Kotlin:**

```
// ./app/src/main/java/com/chatterbox/myapp/MainActivity.kt

package com.chatterbox.myapp
// ...

class MainActivity : AppCompatActivity() {
   private var connectionState = ChatRoom.State.DISCONNECTED

// ...

   private fun updateConnectionState(state: ChatRoom.State) {
      connectionState = state

     when (state) {
          ChatRoom.State.CONNECTED -> {
              Log.d(TAG, "room connected")
          }
          ChatRoom.State.DISCONNECTED -> {
              Log.d(TAG, "room disconnected")
          }
          ChatRoom.State.CONNECTING -> {
              Log.d(TAG, "room connecting")
          }
      }
}
```

[Selanjutnya, kita mengintegrasikan fungsi state-updater kita dengan properti.listener: ChatRoom](https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/1.0.0/-amazon%20-i-v-s%20-chat%20-messaging%20-s-d-k%20for%20-android/com.amazonaws.ivs.chat.messaging/-chat-room/listener.html)

**Kotlin**:

```
// ./app/src/main/java/com/chatterbox/myapp/MainActivity.kt

package com.chatterbox.myapp
// ...

class MainActivity : AppCompatActivity() {
// ...

    override fun onCreate(savedInstanceState: Bundle?) {
        // ...

        // Create room instance
        room = ChatRoom(REGION, ::fetchChatToken).apply {
            lifecycleScope.launch {
                stateChanges().collect { state ->
                    Log.d(TAG, "state change to $state")
                    updateConnectionState(state)

                }
            }

      // ...

      }
   }
}
```

Sekarang kita memiliki kemampuan untuk menyimpan, mendengarkan, dan bereaksi terhadap pembaruan [ChatRoom](https://aws.github.io/amazon-ivs-chat-messaging-sdk-android/1.0.0/-amazon%20-i-v-s%20-chat%20-messaging%20-s-d-k%20for%20-android/com.amazonaws.ivs.chat.messaging/-chat-room/index.html)status, saatnya untuk menginisialisasi koneksi:

**Kotlin:**

```
// ./app/src/main/java/com/chatterbox/myapp/MainActivity.kt

package com.chatterbox.myapp
// ...

class MainActivity : AppCompatActivity() {
// ...

   private fun connect() {
      try {
         room?.connect()
      } catch (ex: Exception) {
         Log.e(TAG, "Error while calling connect()", ex)
      }
   }

   // ...
}
```

## Membangun Penyedia Token
<a name="chat-kotlin-rooms-token-provider"></a>

Kini saatnya membuat fungsi yang bertanggung jawab untuk membuat dan mengelola token obrolan di aplikasi. Di dalam contoh ini, kita menggunakan [Klien HTTP Retrofit untuk Android](https://square.github.io/retrofit/).

Sebelum kita dapat mengirim lalu lintas jaringan yang ada, kita harus menyiapkan konfigurasi keamanan jaringan untuk Android. (Untuk informasi selengkapnya, lihat [Konfigurasikan keamanan jaringan](https://developer.android.com/privacy-and-security/security-config).) Kita mulai dengan menambahkan izin jaringan ke file [Manifes Aplikasi](https://developer.android.com/guide/topics/manifest/manifest-intro). Perhatikan tanda `user-permission` dan atribut `networkSecurityConfig` yang ditambahkan, yang akan mengarahkan ke konfigurasi keamanan jaringan baru kita. *Di dalam kode di bawah ini, ganti *`<version>`* dengan nomor versi SDK Android Obrolan saat ini (misalnya, 1.1.0).*

**XML:**

```
// ./app/src/main/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.chatterbox.myapp">
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        android:allowBackup="true"
        android:fullBackupContent="@xml/backup_rules"
        android:label="@string/app_name"
        android:networkSecurityConfig="@xml/network_security_config"
// ...

// ./app/build.gradle


dependencies {
   implementation("com.amazonaws:ivs-chat-messaging:<version>")
// ...

   implementation("com.squareup.retrofit2:retrofit:2.9.0")
   implementation("com.squareup.retrofit2:converter-gson:2.9.0")
}
```

Nyatakan alamat IP Anda, misalnya domain `10.0.2.2` dan `localhost`, sebagai tepercaya untuk mulai bertukar pesan dengan backend kami:

**XML:**

```
// ./app/src/main/res/xml/network_security_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">10.0.2.2</domain>
        <domain includeSubdomains="true">localhost</domain>
    </domain-config>
</network-security-config>
```

Selanjutnya, kita perlu menambahkan dependensi baru, bersama dengan [Penambahan konverter gson](https://github.com/square/retrofit/tree/trunk/retrofit-converters/gson) untuk mengurai respons HTTP. *Di dalam kode di bawah ini, ganti *`<version>`* dengan nomor versi SDK Android Obrolan saat ini (misalnya, 1.1.0).*

**Skrip Kotlin:**

```
// ./app/build.gradle

dependencies {
   implementation("com.amazonaws:ivs-chat-messaging:<version>")
// ...

   implementation("com.squareup.retrofit2:retrofit:2.9.0")
   implementation("com.squareup.retrofit2:converter-gson:2.9.0")
}
```

Untuk mengambil token obrolan, kita perlu membuat permintaan HTTP POST dari aplikasi `chatterbox` kita. Kita menentukan permintaan dalam antarmuka Retrofit yang akan diimplementasikan. (Lihat [dokumentasi Retrofit](https://square.github.io/retrofit/). Juga biasakan diri Anda dengan spesifikasi [CreateChatToken](https://docs.aws.amazon.com/ivs/latest/ChatAPIReference/API_CreateChatToken.html#API_CreateChatToken_RequestBody)operasi.)

**Kotlin:**

```
// ./app/src/main/java/com/chatterbox/myapp/network/ApiService.kt

package com.chatterbox.myapp.network

import com.amazonaws.ivs.chat.messaging.ChatToken
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.POST

data class CreateTokenParams(var userId: String, var roomIdentifier: String)

interface ApiService {
   @POST("create_chat_token")
   fun createChatToken(@Body params: CreateTokenParams): Call<ChatToken>
}


// ./app/src/main/java/com/chatterbox/myapp/network/RetrofitFactory.kt

package com.chatterbox.myapp.network

import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

object RetrofitFactory {
   private const val BASE_URL = "http://10.0.2.2:3000"

   fun makeRetrofitService(): ApiService {
       return Retrofit.Builder()
           .baseUrl(BASE_URL)
           .addConverterFactory(GsonConverterFactory.create())
           .build().create(ApiService::class.java)
   }
}
```

Dengan jaringan yang telah siap, kini saatnya menambahkan fungsi yang bertanggung jawab untuk membuat dan mengelola token obrolan kita. Kita menambahkannya ke `MainActivity.kt`, yang secara otomatis dibuat ketika proyek [dibuat](#chat-kotlin-rooms-chatterbox):

**Kotlin:**

```
// ./app/src/main/java/com/chatterbox/myapp/MainActivity.kt

package com.chatterbox.myapp

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
import com.amazonaws.ivs.chat.messaging.*
import com.amazonaws.ivs.chat.messaging.coroutines.*
import com.chatterbox.myapp.network.CreateTokenParams
import com.chatterbox.myapp.network.RetrofitFactory
import retrofit2.Call
import java.io.IOException
import retrofit2.Callback
import retrofit2.Response

// custom tag for logging purposes
const val TAG = "Chatterbox-MyApp"

// any ID to be associated with auth token
const val USER_ID = "test user id"
// ID of the room the app wants to access. Must be an ARN. See Amazon Resource Names(ARNs)
const val ROOM_ID = "arn:aws:..."
// AWS region of the room that was created in Getting Started with Amazon IVS Chat
const val REGION = "us-west-2"

class MainActivity : AppCompatActivity() {

   private val service = RetrofitFactory.makeRetrofitService()
   private var userId: String = USER_ID

// ...

   private fun fetchChatToken(callback: ChatTokenCallback) {
      val params = CreateTokenParams(userId, ROOM_ID)
      service.createChatToken(params).enqueue(object : Callback<ChatToken> {
         override fun onResponse(call: Call<ChatToken>, response: Response<ChatToken>) {
            val token = response.body()
            if (token == null) {
               Log.e(TAG, "Received empty token response")
               callback.onFailure(IOException("Empty token response"))
               return
            }

            Log.d(TAG, "Received token response $token")
            callback.onSuccess(token)
         }

         override fun onFailure(call: Call<ChatToken>, throwable: Throwable) {
            Log.e(TAG, "Failed to fetch token", throwable)
            callback.onFailure(throwable)
         }
      })
   }
}
```

## Langkah Berikutnya
<a name="chat-kotlin-rooms-next-steps"></a>

Sekarang, setelah Anda membuat koneksi ruang obrolan, lanjutkan ke Bagian 2 dari tutorial Coroutine Kotlin, [Pesan dan Peristiwa](chat-sdk-kotlin-tutorial-messages-events.md).