

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

# Memproses Dokumen dengan Operasi Asynchronous
<a name="async"></a>

Amazon Textract dapat mendeteksi dan menganalisis teks dalam dokumen multihalaman yang dalam format PDF atau TIFF. Ini termasuk faktur dan tanda terima. Pengolahan dokumen multipage merupakan operasi asinkron. Pengolahan dokumen asinkron berguna untuk memproses dokumen multipage yang besar. Misalnya, file PDF dengan lebih dari 1.000 halaman membutuhkan waktu untuk diproses. Memproses file PDF secara asinkron memungkinkan aplikasi Anda menyelesaikan tugas lain sementara menunggu proses selesai. 

Bagian ini mencakup bagaimana Anda dapat menggunakan Amazon Textract untuk mendeteksi dan menganalisis teks secara asinkron pada dokumen multihalaman atau satu halaman. Dokumen multipage harus dalam format PDF atau TIFF. Dokumen satu halaman yang diproses dengan operasi asinkron dapat dalam format JPEG, PNG, TIFF atau PDF.

Anda dapat menggunakan operasi asinkron Amazon Texact untuk tujuan berikut:
+ Deteksi teks - Anda dapat mendeteksi baris dan kata-kata pada dokumen multipage. Operasi asinkron[StartDocumentTextDetection](API_StartDocumentTextDetection.md)dan[GetDocumentTextDetection](API_GetDocumentTextDetection.md). Untuk informasi selengkapnya, lihat [Mendeteksi teks](how-it-works-detecting.md).
+ Analisis teks - Anda dapat mengidentifikasi hubungan antara teks yang terdeteksi pada dokumen multipage. Operasi asinkron[StartDocumentAnalysis](API_StartDocumentAnalysis.md)dan[GetDocumentAnalysis](API_GetDocumentAnalysis.md). Untuk informasi selengkapnya, lihat [Menganalisis Dokumen](how-it-works-analyzing.md).
+ Analisis pengeluaran — Anda dapat mengidentifikasi hubungan data pada faktur dan tanda terima multipage. Amazon Textract memperlakukan setiap faktur atau halaman penerimaan dokumen multi-halaman sebagai tanda terima individu atau faktur. Ini tidak mempertahankan konteks dari satu halaman ke halaman lain dari dokumen multi-halaman. Operasi asinkron[StartExpenseAnalysis](API_StartExpenseAnalysis.md)dan[GetExpenseAnalysis](API_GetExpenseAnalysis.md). Untuk informasi selengkapnya, lihat [Menganalisis Faktur dan Penerimaan](invoices-receipts.md).

**Topics**
+ [Memanggil Operasi Asinkron Amazon Texact](api-async.md)
+ [Mengkonfigurasi Amazon Textract untuk Operasi Asynchronous](api-async-roles.md)
+ [Mendeteksi atau Menganalisis Teks dalam Dokumen Multipage](async-analyzing-with-sqs.md)
+ [Pemberitahuan Amazon Textract](async-notification-payload.md)

# Memanggil Operasi Asinkron Amazon Texact
<a name="api-async"></a>

Amazon Textract menyediakan API asinkron yang dapat Anda gunakan untuk memproses dokumen multipage dalam format PDF atau TIFF. Anda juga dapat menggunakan operasi asinkron untuk memproses dokumen satu halaman yang ada dalam format JPEG, PNG, TIFF, atau PDF. 

Informasi dalam topik ini menggunakan operasi pendeteksian teks untuk menunjukkan cara menggunakan operasi asinkron Amazon Texact. Pendekatan yang sama bekerja dengan operasi analisis teks[StartDocumentAnalysis](API_StartDocumentAnalysis.md)dan[GetDocumentAnalysis](API_GetDocumentAnalysis.md). Ini juga bekerja sama dengan[StartExpenseAnalysis](API_StartExpenseAnalysis.md)dan[GetExpenseAnalysis](API_GetExpenseAnalysis.md). 

Sebagai contoh, lihat [Mendeteksi atau Menganalisis Teks dalam Dokumen Multipage](async-analyzing-with-sqs.md).

Amazon Textract Texact secara tidak sinkron memproses dokumen yang tersimpan di bucket Amazon S3. Anda mulai memproses dengan memanggil`Start`operasi, seperti[StartDocumentTextDetection](API_StartDocumentTextDetection.md). Status penyelesaian untuk permintaan diterbitkan ke topik Amazon Simple Notification Service (Amazon SNS). Untuk mendapatkan status penyelesaian dari topik Amazon SNS, Anda dapat menggunakan antrean Amazon Simple Queue Service (Amazon SQS) atau fungsi AWS Lambda. Setelah Anda memiliki status penyelesaian, Anda perlu memanggil operasi `Get`, seperti [GetDocumentTextDetection](API_GetDocumentTextDetection.md), untuk mendapatkan hasil permintaan. 

Hasil panggilan asinkron dienkripsi dan disimpan selama 7 hari dalam bucket milik Amazon Textract Texact secara default, kecuali jika Anda menetapkan bucket Amazon S3 menggunakan operasi`OutputConfig`argumen.

Tabel berikut menunjukkan operasi Start and Get yang sesuai untuk berbagai jenis pemrosesan asinkron yang didukung oleh Amazon Textract:


**Mulai/Dapatkan Operasi API untuk Operasi Asinkron Amazon Texact**  

| Jenis Pengolahan | Mulai API | Dapatkan API | 
| --- | --- | --- | 
| Pendeteksi teks | StartDocumentTextDetection | GetDocumentTextDetection | 
| Analisis Teks | StartDocumentAnalysis | GetDocumentAnalysis | 
| Analisis Beban | StartExpenseAnalysis | GetExpenseAnalysis | 

Untuk contoh yang menggunakanAWS Lambdafungsi, lihat[Pemrosesan dokumen berskala besar dengan Amazon Textract](https://github.com/aws-samples/amazon-textract-serverless-large-scale-document-processing).

Diagram berikut menunjukkan proses untuk mendeteksi teks dokumen dalam citra dokumen yang tersimpan di bucket Amazon S3. Dalam diagram, antrean Amazon SQS mendapatkan status penyelesaian dari topik Amazon SNS. 

![\[alt text not found\]](http://docs.aws.amazon.com/id_id/textract/latest/dg/images/asynchronous.png)


Proses yang ditampilkan oleh diagram sebelumnya adalah sama untuk menganalisis teks dan faktur/tanda terima. Anda mulai menganalisis teks dengan menelepon[StartDocumentAnalysis](API_StartDocumentAnalysis.md)dan mulai menganalisis faktur/tanda terima dengan menelepon[StartExpenseAnalysis](API_StartExpenseAnalysis.md)Anda mendapatkan hasilnya dengan menelepon[GetDocumentAnalysis](API_GetDocumentAnalysis.md)atau[GetExpenseAnalysis](API_GetExpenseAnalysis.md)masing-masing.

## Pendeteksi teks
<a name="api-async-start"></a>

Anda memulai permintaan pendeteksi teks Amazon Texact dengan menelepon[StartDocumentTextDetection](API_StartDocumentTextDetection.md). Berikut ini adalah contoh permintaan JSON yang diberikan oleh `StartDocumentTextDetection`.

```
{
    "DocumentLocation": {
        "S3Object": {
            "Bucket": "bucket",
            "Name": "image.pdf"
        }
    },
    "ClientRequestToken": "DocumentDetectionToken",
    "NotificationChannel": {
        "SNSTopicArn": "arn:aws:sns:us-east-1:nnnnnnnnnn:topic",
        "RoleArn": "arn:aws:iam::nnnnnnnnnn:role/roleTopic"
    },
    "JobTag": "Receipt"
}
```

Parameter input`DocumentLocation`menyediakan nama file dokumen dan bucket Amazon S3 untuk mengambilnya.`NotificationChannel`berisi Amazon Resource Name (ARN) dari topik Amazon SNS yang memberi tahu Amazon Textract saat permintaan pendeteksi teks selesai. Topik Amazon SNS harus berada di Wilayah AWS yang sama dengan titik akhir Amazon Textract Texact yang Anda hubungi.`NotificationChannel`juga berisi ARN untuk peran yang memungkinkan Amazon Textract untuk mempublikasikan ke topik Amazon SNS. Anda memberikan izin penerbitan Amazon Textract Texact untuk topik Amazon SNS Anda dengan menciptakan peran layanan IAM. Untuk informasi selengkapnya, lihat [Mengkonfigurasi Amazon Textract untuk Operasi Asynchronous](api-async-roles.md).

Anda juga dapat menentukan parameter input opsional,`JobTag`, yang mengizinkan Anda untuk mengidentifikasi tugas, atau kelompok tugas, dalam status penyelesaian yang diterbitkan untuk topik Amazon SNS. Misalnya, Anda dapat menggunakan`JobTag`untuk mengidentifikasi jenis dokumen yang sedang diproses, seperti formulir pajak atau tanda terima.

Untuk mencegah duplikasi pekerjaan analisis yang tidak disengaja, Anda dapat memberikan token idempotensi , `ClientRequestToken`. Jika Anda memberikan nilai untuk`ClientRequestToken`, yang`Start`operasi mengembalikan yang sama`JobId`untuk beberapa panggilan identik ke`Start`operasi, seperti`StartDocumentTextDetection`. Token `ClientRequestToken` memiliki masa pakai 7 hari. Setelah 7 hari, Anda bisa menggunakannya kembali. Jika Anda menggunakan kembali token selama masa token aktif, hal berikut akan terjadi: 
+ Jika Anda menggunakan kembali token dengan sama`Start`operasi dan parameter input yang sama, sama`JobId`dikembalikan. Tugas tidak akan dilakukan lagi dan Amazon Textract Texact tidak mengirimkan status penyelesaian ke topik Amazon SNS yang terdaftar.
+ Jika Anda menggunakan kembali token dengan operasi `Start` dan perubahan pada input parameter kecil, Anda mendapatkan pengecualian yang ditimbulkan `idempotentparametermismatchexception` (Kode status HTTP: 400).
+ Jika Anda menggunakan kembali token dengan yang berbeda`Start`operasi, operasi berhasil.

Parameter opsional lain yang tersedia adalah`OutputConfig`, yang memungkinkan Anda menyesuaikan di mana output Anda akan ditempatkan. Secara default, Amazon Textract akan menyimpan hasil secara internal, dan hanya dapat diakses oleh operasi Get API. Dengan`OutputConfig`diaktifkan, Anda dapat mengatur nama bucket output akan dikirim ke, dan awalan file hasil, di mana Anda dapat men-download hasil Anda. Selain itu, Anda dapat mengatur`KMSKeyID`parameter ke kunci yang dikelola pelanggan untuk mengenkripsi output Anda. Tanpa parameter ini, Amazon Textract akan mengenkripsi sisi server menggunakanKunci yang dikelola AWSuntuk Amazon S3

**catatan**  
Sebelum menggunakan parameter ini, pastikan Anda memiliki izin PutObject untuk bucket output. Selain itu, pastikan Anda memiliki izin Decrypt, ReEncrypt, GenerateDataKey, dan DescribeKey untukAWS KMSkunci jika Anda memutuskan untuk menggunakannya.

Respons terhadap operasi `StartDocumentTextDetection` adalah pengidentifikasi tugas (`JobId`). Gunakan`JobId`untuk melacak permintaan dan mendapatkan hasil analisis setelah Amazon Textract Texact menerbitkan status penyelesaian ke topik Amazon SNS. Berikut ini adalah contoh:

```
{"JobId":"270c1cc5e1d0ea2fbc59d97cb69a72a5495da75851976b14a1784ca90fc180e3"}
```

Jika Anda memulai terlalu banyak pekerjaan secara bersamaan, panggilan ke`StartDocumentTextDetection`menaikkan`LimitExceededException`exception (Kode status HTTP: 400) hingga jumlah tugas yang berjalan bersamaan di bawah batas layanan Amazon Textract Texact. 

Jika Anda menemukan bahwa pengecualian LimitExceededException dimunculkan dengan rongsokan aktivitas, mohon pertimbangkan untuk menggunakan antrean Amazon SQS untuk mengelola permintaan yang masuk. KontakAWSSupport jika Anda menemukan bahwa jumlah rata-rata permintaan bersamaan tidak dapat dikelola oleh antrean Amazon SQS dan Anda masih menerima`LimitExceededException`pengecualian. 

## Mendapatkan Status Penyelesaian Permintaan Analisis Amazon Textract
<a name="api-async-get-status"></a>

Amazon Textract Texact mengirimkan notifikasi penyelesaian analisis ke topik Amazon SNS yang terdaftar. Pemberitahuan tersebut mencakup pengindentifikasi tugas dan status penyelesaian operasi dalam string JSON. Permintaan deteksi teks yang sukses memiliki`SUCCEEDED`status. Misalnya, hasil berikut menunjukkan berhasilnya pengolahan tugas pendeteksi teks.

```
{
    "JobId": "642492aea78a86a40665555dc375ee97bc963f342b29cd05030f19bd8fd1bc5f",
    "Status": "SUCCEEDED",
    "API": "StartDocumentTextDetection",
    "JobTag": "Receipt",
    "Timestamp": 1543599965969,
    "DocumentLocation": {
        "S3ObjectName": "document",
        "S3Bucket": "bucket"
    }
}
```

Untuk informasi selengkapnya, lihat [Pemberitahuan Amazon Textract](async-notification-payload.md).

Untuk mendapatkan status informasi yang dipublikasikan ke topik Amazon SNS, gunakan salah satu opsi berikut:
+ **AWS Lambda** — Anda dapat berlangganan fungsi AWS Lambda yang Anda tulis untuk topik Amazon SNS. Fungsi ini dipanggil saat Amazon Textract memberi tahu topik Amazon SNS bahwa permintaannya telah selesai. Gunakan fungsi Lambda jika Anda menginginkan kode sisi server untuk memproses hasil permintaan deteksi teks. Misalnya, Anda mungkin ingin menggunakan kode sisi server untuk menganotasi gambar atau membuat laporan tentang teks yang terdeteksi sebelum mengembalikan informasi ke aplikasi klien.
+ **Amazon SQS**— Anda dapat berlangganan antrean Amazon SQS ke topik Amazon SNS. Anda kemudian dapat melakukan polling antrean Amazon SQS untuk mengambil status penyelesaian yang diterbitkan oleh Amazon Textract saat permintaan pendeteksi teks selesai. Untuk informasi selengkapnya, lihat [Mendeteksi atau Menganalisis Teks dalam Dokumen Multipage](async-analyzing-with-sqs.md). Gunakan antrean Amazon SQS jika Anda ingin memanggil operasi Amazon Textract Texact hanya dari aplikasi klien. 

**penting**  
Kami tidak merekomendasikan untuk mendapatkan status penyelesaian permintaan dengan berulang kali memanggil Amazon Textract`Get`operasi. Hal ini karena Amazon Textract Texact throttles`Get`operasi jika terlalu banyak permintaan yang dibuat. Jika Anda memproses beberapa dokumen secara bersamaan, akan lebih mudah dan lebih efisien untuk memantau satu antrean SQS untuk notifikasi penyelesaian daripada membuat polling Amazon Textract untuk status setiap pekerjaan secara individual.

## Mendapatkan Hasil Deteksi Amazon Textract Texact
<a name="api-async-get"></a>

Untuk mendapatkan hasil permintaan pendeteksi teks, pertama pastikan bahwa status penyelesaian yang diambil dari topik Amazon SNS adalah`SUCCEEDED`. Kemudian panggil `GetDocumentTextDetection`, yang memberikan nilai `JobId` yang dikembalikan dari `StartDocumentTextDetection`. Permintaan JSON serupa dengan contoh berikut:

```
{
    "JobId": "270c1cc5e1d0ea2fbc59d97cb69a72a5495da75851976b14a1784ca90fc180e3",
    "MaxResults": 10,
    "SortBy": "TIMESTAMP"
}
```

`JobId`adalah pengidentifikasi untuk operasi deteksi teks. Karena deteksi teks dapat menghasilkan data dalam jumlah besar, gunakan`MaxResults`untuk menentukan jumlah hasil maksimum yang akan dikembalikan dalam satu`Get`operasi. Nilai default untuk`MaxResults`adalah 1.000. Jika Anda menentukan nilai yang lebih besar dari 1.000, hanya 1.000 hasil yang dikembalikan. Jika operasi tidak mengembalikan semua hasil, token pagination untuk halaman berikutnya dikembalikan. Untuk mendapatkan halaman hasil berikutnya, tentukan token di`NextToken`parameter. 

**catatan**  
Amazon Textract Texact mempertahankan hasil operasi asinkron selama 7 hari. Anda tidak dapat mengambil hasilnya setelah waktu ini.

Parameter`GetDocumentTextDetection`respon operasi JSON serupa dengan yang berikut ini. Jumlah total halaman yang terdeteksi dikembalikan`DocumentMetadata`. Teks yang terdeteksi dikembalikan dalam`Blocks`array. Untuk informasi tentang`Block`benda, lihat[Deteksi Teks dan Dokumen Analisis Respon Objek](how-it-works-document-layout.md).

```
{
    "DocumentMetadata": {
        "Pages": 1
    },
    "JobStatus": "SUCCEEDED",
    "Blocks": [
        {
            "BlockType": "PAGE",
            "Geometry": {
                "BoundingBox": {
                    "Width": 1.0,
                    "Height": 1.0,
                    "Left": 0.0,
                    "Top": 0.0
                },
                "Polygon": [
                    {
                        "X": 0.0,
                        "Y": 0.0
                    },
                    {
                        "X": 1.0,
                        "Y": 0.0
                    },
                    {
                        "X": 1.0,
                        "Y": 1.0
                    },
                    {
                        "X": 0.0,
                        "Y": 1.0
                    }
                ]
            },
            "Id": "64533157-c47e-401a-930e-7ca1bb3ac3fa",
            "Relationships": [
                {
                    "Type": "CHILD",
                    "Ids": [
                        "4297834d-dcb1-413b-8908-3b96866ebbb5",
                        "1d85ba24-2877-4d09-b8b2-393833d769e9",
                        "193e9c47-fd87-475a-ba09-3fda210d8784",
                        "bd8aeb62-961b-4b47-b78a-e4ed9eeecd0f"
                    ]
                }
            ],
            "Page": 1
        },
        {
            "BlockType": "LINE",
            "Confidence": 53.301639556884766,
            "Text": "ellooworio",
            "Geometry": {
                "BoundingBox": {
                    "Width": 0.9999999403953552,
                    "Height": 0.5365243554115295,
                    "Left": 0.0,
                    "Top": 0.46347561478614807
                },
                "Polygon": [
                    {
                        "X": 0.0,
                        "Y": 0.46347561478614807
                    },
                    {
                        "X": 0.9999999403953552,
                        "Y": 0.46347561478614807
                    },
                    {
                        "X": 0.9999999403953552,
                        "Y": 1.0
                    },
                    {
                        "X": 0.0,
                        "Y": 1.0
                    }
                ]
            },
            "Id": "4297834d-dcb1-413b-8908-3b96866ebbb5",
            "Relationships": [
                {
                    "Type": "CHILD",
                    "Ids": [
                        "170c3eb9-5155-4bec-8c44-173bba537e70"
                    ]
                }
            ],
            "Page": 1
        },
        {
            "BlockType": "LINE",
            "Confidence": 89.15632629394531,
            "Text": "He llo,",
            "Geometry": {
                "BoundingBox": {
                    "Width": 0.33642634749412537,
                    "Height": 0.49159330129623413,
                    "Left": 0.13885067403316498,
                    "Top": 0.17169663310050964
                },
                "Polygon": [
                    {
                        "X": 0.13885067403316498,
                        "Y": 0.17169663310050964
                    },
                    {
                        "X": 0.47527703642845154,
                        "Y": 0.17169663310050964
                    },
                    {
                        "X": 0.47527703642845154,
                        "Y": 0.6632899641990662
                    },
                    {
                        "X": 0.13885067403316498,
                        "Y": 0.6632899641990662
                    }
                ]
            },
            "Id": "1d85ba24-2877-4d09-b8b2-393833d769e9",
            "Relationships": [
                {
                    "Type": "CHILD",
                    "Ids": [
                        "516ae823-3bab-4f9a-9d74-ad7150d128ab",
                        "6bcf4ea8-bbe8-4686-91be-b98dd63bc6a6"
                    ]
                }
            ],
            "Page": 1
        },
        {
            "BlockType": "LINE",
            "Confidence": 82.44834899902344,
            "Text": "worlo",
            "Geometry": {
                "BoundingBox": {
                    "Width": 0.33182239532470703,
                    "Height": 0.3766750991344452,
                    "Left": 0.5091826915740967,
                    "Top": 0.23131252825260162
                },
                "Polygon": [
                    {
                        "X": 0.5091826915740967,
                        "Y": 0.23131252825260162
                    },
                    {
                        "X": 0.8410050868988037,
                        "Y": 0.23131252825260162
                    },
                    {
                        "X": 0.8410050868988037,
                        "Y": 0.607987642288208
                    },
                    {
                        "X": 0.5091826915740967,
                        "Y": 0.607987642288208
                    }
                ]
            },
            "Id": "193e9c47-fd87-475a-ba09-3fda210d8784",
            "Relationships": [
                {
                    "Type": "CHILD",
                    "Ids": [
                        "ed135c3b-35dd-4085-8f00-26aedab0125f"
                    ]
                }
            ],
            "Page": 1
        },
        {
            "BlockType": "LINE",
            "Confidence": 88.50325775146484,
            "Text": "world",
            "Geometry": {
                "BoundingBox": {
                    "Width": 0.35004907846450806,
                    "Height": 0.19635874032974243,
                    "Left": 0.527581512928009,
                    "Top": 0.30100569128990173
                },
                "Polygon": [
                    {
                        "X": 0.527581512928009,
                        "Y": 0.30100569128990173
                    },
                    {
                        "X": 0.8776305913925171,
                        "Y": 0.30100569128990173
                    },
                    {
                        "X": 0.8776305913925171,
                        "Y": 0.49736443161964417
                    },
                    {
                        "X": 0.527581512928009,
                        "Y": 0.49736443161964417
                    }
                ]
            },
            "Id": "bd8aeb62-961b-4b47-b78a-e4ed9eeecd0f",
            "Relationships": [
                {
                    "Type": "CHILD",
                    "Ids": [
                        "9e28834d-798e-4a62-8862-a837dfd895a6"
                    ]
                }
            ],
            "Page": 1
        },
        {
            "BlockType": "WORD",
            "Confidence": 53.301639556884766,
            "Text": "ellooworio",
            "Geometry": {
                "BoundingBox": {
                    "Width": 1.0,
                    "Height": 0.5365243554115295,
                    "Left": 0.0,
                    "Top": 0.46347561478614807
                },
                "Polygon": [
                    {
                        "X": 0.0,
                        "Y": 0.46347561478614807
                    },
                    {
                        "X": 1.0,
                        "Y": 0.46347561478614807
                    },
                    {
                        "X": 1.0,
                        "Y": 1.0
                    },
                    {
                        "X": 0.0,
                        "Y": 1.0
                    }
                ]
            },
            "Id": "170c3eb9-5155-4bec-8c44-173bba537e70",
            "Page": 1
        },
        {
            "BlockType": "WORD",
            "Confidence": 88.46246337890625,
            "Text": "He",
            "Geometry": {
                "BoundingBox": {
                    "Width": 0.15350718796253204,
                    "Height": 0.29955607652664185,
                    "Left": 0.13885067403316498,
                    "Top": 0.21856294572353363
                },
                "Polygon": [
                    {
                        "X": 0.13885067403316498,
                        "Y": 0.21856294572353363
                    },
                    {
                        "X": 0.292357861995697,
                        "Y": 0.21856294572353363
                    },
                    {
                        "X": 0.292357861995697,
                        "Y": 0.5181190371513367
                    },
                    {
                        "X": 0.13885067403316498,
                        "Y": 0.5181190371513367
                    }
                ]
            },
            "Id": "516ae823-3bab-4f9a-9d74-ad7150d128ab",
            "Page": 1
        },
        {
            "BlockType": "WORD",
            "Confidence": 89.8501968383789,
            "Text": "llo,",
            "Geometry": {
                "BoundingBox": {
                    "Width": 0.17724157869815826,
                    "Height": 0.49159327149391174,
                    "Left": 0.2980354428291321,
                    "Top": 0.17169663310050964
                },
                "Polygon": [
                    {
                        "X": 0.2980354428291321,
                        "Y": 0.17169663310050964
                    },
                    {
                        "X": 0.47527703642845154,
                        "Y": 0.17169663310050964
                    },
                    {
                        "X": 0.47527703642845154,
                        "Y": 0.6632899045944214
                    },
                    {
                        "X": 0.2980354428291321,
                        "Y": 0.6632899045944214
                    }
                ]
            },
            "Id": "6bcf4ea8-bbe8-4686-91be-b98dd63bc6a6",
            "Page": 1
        },
        {
            "BlockType": "WORD",
            "Confidence": 82.44834899902344,
            "Text": "worlo",
            "Geometry": {
                "BoundingBox": {
                    "Width": 0.33182239532470703,
                    "Height": 0.3766750991344452,
                    "Left": 0.5091826915740967,
                    "Top": 0.23131252825260162
                },
                "Polygon": [
                    {
                        "X": 0.5091826915740967,
                        "Y": 0.23131252825260162
                    },
                    {
                        "X": 0.8410050868988037,
                        "Y": 0.23131252825260162
                    },
                    {
                        "X": 0.8410050868988037,
                        "Y": 0.607987642288208
                    },
                    {
                        "X": 0.5091826915740967,
                        "Y": 0.607987642288208
                    }
                ]
            },
            "Id": "ed135c3b-35dd-4085-8f00-26aedab0125f",
            "Page": 1
        },
        {
            "BlockType": "WORD",
            "Confidence": 88.50325775146484,
            "Text": "world",
            "Geometry": {
                "BoundingBox": {
                    "Width": 0.35004907846450806,
                    "Height": 0.19635874032974243,
                    "Left": 0.527581512928009,
                    "Top": 0.30100569128990173
                },
                "Polygon": [
                    {
                        "X": 0.527581512928009,
                        "Y": 0.30100569128990173
                    },
                    {
                        "X": 0.8776305913925171,
                        "Y": 0.30100569128990173
                    },
                    {
                        "X": 0.8776305913925171,
                        "Y": 0.49736443161964417
                    },
                    {
                        "X": 0.527581512928009,
                        "Y": 0.49736443161964417
                    }
                ]
            },
            "Id": "9e28834d-798e-4a62-8862-a837dfd895a6",
            "Page": 1
        }
    ]
}
```

# Mengkonfigurasi Amazon Textract untuk Operasi Asynchronous
<a name="api-async-roles"></a>

Prosedur berikut menunjukkan kepada Anda cara mengonfigurasi Amazon Textract yang akan digunakan dengan topik Amazon Simple Notification Service (Amazon SNS) dan antrean Amazon Simple Queue Service (Amazon SQS).

**catatan**  
Jika Anda menggunakan instruksi ini untuk mengatur[Mendeteksi atau Menganalisis Teks dalam Dokumen Multipage](async-analyzing-with-sqs.md)example, Anda tidak perlu melakukan langkah 3 — 6. Contoh tersebut mencakup kode untuk membuat dan mengonfigurasi topik Amazon SNS dan antrean Amazon SQS.

**Untuk mengonfigurasi Amazon Textract**

1. Menyiapkan sebuahAWSakun untuk mengakses Amazon Textract. Untuk informasi selengkapnya, lihat [Langkah 1: Siapkan Akun AWS dan Buat Pengguna IAM](setting-up.md).

   Pastikan bahwa pengguna setidaknya memiliki izin berikut:
   + AmazonTextractFullAccess
   + AmazonS3ReadOnlyAccess
   + AmazonSNSFullAccess
   + AmazonSQSFullAccess

1. Instal dan konfigurasikan SDK AWS yang diperlukan. Untuk informasi selengkapnya, lihat [Langkah 2: MenyiapkanAWS CLIdanAWSSDK](setup-awscli-sdk.md). 

1. [Membuat topik Amazon SNS](https://docs.aws.amazon.com/sns/latest/dg/sns-tutorial-create-topic.html). Tambahkan nama topik dengan*AmazontExtract*. Perhatikan topik Amazon Resource Name (ARN). Pastikan bahwa topik berada di Wilayah yang sama denganAWSendpoint yang Anda gunakan dengan akun AWS Anda.

1. [Buat antrean standar Amazon SQS](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-create-queue.html) dengan menggunakan [Konsol Amazon SQS](https://console.aws.amazon.com/sqs/). Perhatikan antrean ARN.

1. [Berlangganan antrean ke topik](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-subscribe-queue-sns-topic.html) yang Anda buat di langkah 3.

1. [Memberikan izin untuk topik Amazon SNS untuk mengirim pesan ke antrean Amazon SQS](https://docs.aws.amazon.com/sns/latest/dg/subscribe-sqs-queue-to-sns-topic.html).

1. Buat peran layanan IAM untuk memberikan akses Amazon Textract Texact ke topik Amazon SNS Anda. Catat Amazon Resource Name (ARN) dari peran layanan tersebut. Untuk informasi selengkapnya, lihat [Memberikan Amazon Textract Akses ke Topik Amazon SNS Anda](#api-async-roles-all-topics).

1. [Tambahkan kebijakan inline berikut](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html#embed-inline-policy-console)untuk pengguna IAM yang Anda buat pada langkah 1. 

   ```
   {
       "Version": "2012-10-17",
       "Statement": [
           {
               "Sid": "MySid",
               "Effect": "Allow",
               "Action": "iam:PassRole",
               "Resource": "Service role ARN from step 7"
           }
       ]
   }
   ```

   Berikan kebijakan inline sebuah nama.

1. Sekarang Anda dapat menjalankan contoh di[Mendeteksi atau Menganalisis Teks dalam Dokumen Multipage](async-analyzing-with-sqs.md).

## Memberikan Amazon Textract Akses ke Topik Amazon SNS Anda
<a name="api-async-roles-all-topics"></a>

Amazon Textract memerlukan izin untuk mengirim pesan ke topik Amazon SNS Anda saat operasi asinkron selesai. Anda menggunakan peran layanan IAM untuk memberikan akses Amazon Textract Texact ke topik Amazon SNS. 

 Ketika Anda membuat topik Amazon SNS, Anda harus menambahkan nama topik dengan**AmazonTextract**—misalnya,**AmazonTextractMyTopicName**. 

1. Masuk ke konsol IAM ([https://console.aws.amazon.com/iam](https://console.aws.amazon.com/iam)).

1. Di panel navigasi, pilih **Peran**.

1. Pilih **Buat peran**.

1. Untuk **Pilih jenis entitas tepercaya**, pilih **Layanan AWS**. 

1. Untuk**Pilih layanan yang akan menggunakan peran ini**, pilih**Textract**.

1. Pilih **Berikutnya: Izin**.

1. Verifikasi bahwa**AmazonTextractServiceRole**kebijakan telah dimasukkan dalam daftar kebijakan terlampir. Untuk menampilkan kebijakan dalam daftar, masukkan bagian dari nama kebijakan di**Kebijakan filter**.

1. Pilih **Berikutnya: Tanda**.

1. Anda tidak perlu menambahkan tag, jadi pilih**Selanjutnya: Tinjau**.

1. Di**Tinjau**bagian, untuk**Nama peran**, masukkan nama untuk peran tersebut (example,`TextractRole`). Masuk**Deskripsi peran**, perbarui deskripsi untuk peran, dan kemudian pilih**Buat peran**.

1. Pilih peran baru untuk membuka halaman detail peran.

1. Di**Ringkasan**, salin**ARN Peran**nilai dan menyimpannya.

1. Memiilih**Hubungan kepercayaan**.

1. Memiilih**Edit hubungan kepercayaan**, dan memastikan bahwa kebijakan kepercayaan terlihat sebagai berikut.

   ```
   {
     "Version": "2012-10-17",
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "Service": "textract.amazonaws.com"
         },
         "Action": "sts:AssumeRole"
       }
     ]
   }
   ```

1. Pilih **Perbarui Kebijakan Kepercayaan**.

# Mendeteksi atau Menganalisis Teks dalam Dokumen Multipage
<a name="async-analyzing-with-sqs"></a>

Prosedur ini menunjukkan kepada Anda cara untuk mendeteksi atau menganalisis teks dalam dokumen multihalaman dengan menggunakan operasi pendeteksi Amazon Textract, dokumen yang disimpan dalam bucket Amazon S3, topik Amazon SNS, dan antrean Amazon SQS. Pengolahan dokumen multipage merupakan operasi asinkron. Untuk informasi selengkapnya, lihat [Memanggil Operasi Asinkron Amazon Texact](api-async.md).

Anda dapat memilih jenis pemrosesan yang ingin Anda lakukan kode: deteksi teks, analisis teks, atau analisis biaya. 

Hasil pengolahan dikembalikan dalam array[Block](API_Block.md)objek, yang berbeda tergantung pada jenis pengolahan yang Anda gunakan.

 Untuk mendeteksi teks atau menganalisis dokumen multipage, Anda melakukan hal berikut:

1. Buat topik Amazon SNS dan antrean Amazon SQS.

1. Berlangganan antrean topik.

1. Berikan izin topik untuk mengirim pesan ke antrean.

1. Mulai memproses dokumen. Gunakan operasi yang sesuai untuk jenis analisis yang Anda pilih:
   + [StartDocumentTextDetection](API_StartDocumentTextDetection.md)untuk tugas deteksi teks.
   + [StartDocumentAnalysis](API_StartDocumentAnalysis.md)untuk tugas analisis teks.
   + [StartExpenseAnalysis](API_StartExpenseAnalysis.md)untuk tugas analisis biaya.

1. Dapatkan status penyelesaian dari antrean Amazon SQS. Contoh kode melacak pengenal pekerjaan (`JobId`) yang dikembalikan oleh`Start`operasi. Ini hanya mendapatkan hasil untuk mencocokkan pengidentifikasi tugas yang dibaca dari status penyelesaian. Hal ini penting jika aplikasi lain menggunakan antrean dan topik yang sama. Untuk kesederhanaan, contoh penghapusan tugas yang tidak cocok. Pertimbangkan untuk menambahkan tugas yang dihapus ke antrean surat mati Amazon SQS untuk penyelidikan lebih lanjut.

1. Dapatkan dan tampilkan hasil pemrosesan dengan memanggil operasi yang sesuai untuk jenis analisis yang Anda pilih:
   + [GetDocumentTextDetection](API_GetDocumentTextDetection.md)untuk tugas deteksi teks.
   + [GetDocumentAnalysis](API_GetDocumentAnalysis.md)untuk tugas analisis teks.
   + [GetExpenseAnalysis](API_GetExpenseAnalysis.md)untuk tugas analisis biaya.

1. Hapus topik Amazon SNS dan antrean Amazon SQS.

## Melakukan Operasi Asinkron
<a name="async-prerequisites"></a>

Contoh kode untuk prosedur ini disediakan di Java, Python, danAWS CLI. Sebelum memulai, pasang yang sesuaiAWSSDK. Untuk informasi selengkapnya, lihat [Langkah 2: MenyiapkanAWS CLIdanAWSSDK](setup-awscli-sdk.md). 

**Untuk mendeteksi atau menganalisis teks dalam dokumen multipage**

1. Konfigurasikan akses pengguna ke Amazon Textract Texact, dan konfigurasikan akses Amazon Textract Texact ke Amazon SNS. Untuk informasi selengkapnya, lihat [Mengkonfigurasi Amazon Textract untuk Operasi Asynchronous](api-async-roles.md). Untuk menyelesaikan prosedur ini, Anda memerlukan file dokumen multipage dalam format PDF. Lewati langkah 3 — 6 karena contoh kode membuat dan mengonfigurasi topik Amazon SNS dan antrean Amazon SQS. Jika completDalam contoh CLI, Anda tidak perlu mengatur antrian SQS. 

1. Unggah file dokumen multipage dalam format PDF atau TIFF ke bucket Amazon S3. (Dokumen satu halaman dalam format JPEG, PNG, TIFF, atau PDF juga dapat diproses). 

   Untuk instruksi, lihat[Mengunggah objek ke Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/user-guide/UploadingObjectsintoAmazonS3.html)di*Panduan Pengguna Amazon Simple Storage Service*.

1. Gunakan hal berikutAWS SDK untuk Java, SDK for Python (Boto3), atauAWS CLIkode untuk mendeteksi teks atau menganalisis teks dalam dokumen multipage. Di`main`Fungsi:
   + Ganti nilai`roleArn`dengan peran IAM ARN yang Anda simpan[Memberikan Amazon Textract Akses ke Topik Amazon SNS Anda](api-async-roles.md#api-async-roles-all-topics). 
   + Ganti nilai`bucket`dan`document`dengan nama file bucket dan dokumen yang Anda tentukan pada langkah 2. 
   + Ganti nilai`type`parameter masukan dari`ProcessDocument`berfungsi dengan jenis pengolahan yang ingin Anda lakukan. Gunakan`ProcessType.DETECTION`untuk mendeteksi teks. Gunakan`ProcessType.ANALYSIS`untuk menganalisis teks. 
   + Untuk contoh Python, ganti nilai`region_name`dengan wilayah klien Anda beroperasi di.

   UntukAWS CLIcontoh, lakukan hal berikut:
   + Saat menelepon[StartDocumentTextDetection](API_StartDocumentTextDetection.md), ganti nilai`bucket-name`dengan nama bucket S3 Anda, dan ganti`file-name`dengan nama file yang Anda tentukan pada langkah 2. Tentukan wilayah bucket Anda dengan mengganti`region-name`dengan nama wilayah Anda. Perhatikan bahwa contoh CLI tidak menggunakan SQS. 
   + Saat menelepon[GetDocumentTextDetection](API_GetDocumentTextDetection.md)menggantikan`job-id-number`dengan`job-id`dikembalikan oleh[StartDocumentTextDetection](API_StartDocumentTextDetection.md). Tentukan wilayah bucket Anda dengan mengganti`region-name`dengan nama wilayah Anda.

------
#### [ Java ]

   ```
   package com.amazonaws.samples;
   
   import java.util.Arrays;
   import java.util.HashMap;
   import java.util.List;
   import java.util.Map;
   
   import com.amazonaws.auth.policy.Condition;
   import com.amazonaws.auth.policy.Policy;
   import com.amazonaws.auth.policy.Principal;
   import com.amazonaws.auth.policy.Resource;
   import com.amazonaws.auth.policy.Statement;
   import com.amazonaws.auth.policy.Statement.Effect;
   import com.amazonaws.auth.policy.actions.SQSActions;
   import com.amazonaws.services.sns.AmazonSNS;
   import com.amazonaws.services.sns.AmazonSNSClientBuilder;
   import com.amazonaws.services.sns.model.CreateTopicRequest;
   import com.amazonaws.services.sns.model.CreateTopicResult;
   import com.amazonaws.services.sqs.AmazonSQS;
   import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
   import com.amazonaws.services.sqs.model.CreateQueueRequest;
   import com.amazonaws.services.sqs.model.Message;
   import com.amazonaws.services.sqs.model.QueueAttributeName;
   import com.amazonaws.services.sqs.model.SetQueueAttributesRequest;
   import com.amazonaws.services.textract.AmazonTextract;
   import com.amazonaws.services.textract.AmazonTextractClientBuilder;
   import com.amazonaws.services.textract.model.Block;
   import com.amazonaws.services.textract.model.DocumentLocation;
   import com.amazonaws.services.textract.model.DocumentMetadata;
   import com.amazonaws.services.textract.model.GetDocumentAnalysisRequest;
   import com.amazonaws.services.textract.model.GetDocumentAnalysisResult;
   import com.amazonaws.services.textract.model.GetDocumentTextDetectionRequest;
   import com.amazonaws.services.textract.model.GetDocumentTextDetectionResult;
   import com.amazonaws.services.textract.model.NotificationChannel;
   import com.amazonaws.services.textract.model.Relationship;
   import com.amazonaws.services.textract.model.S3Object;
   import com.amazonaws.services.textract.model.StartDocumentAnalysisRequest;
   import com.amazonaws.services.textract.model.StartDocumentAnalysisResult;
   import com.amazonaws.services.textract.model.StartDocumentTextDetectionRequest;
   import com.amazonaws.services.textract.model.StartDocumentTextDetectionResult;
   import com.fasterxml.jackson.databind.JsonNode;
   import com.fasterxml.jackson.databind.ObjectMapper;;
   public class DocumentProcessor {
   
       private static String sqsQueueName=null;
       private static String snsTopicName=null;
       private static String snsTopicArn = null;
       private static String roleArn= null;
       private static String sqsQueueUrl = null;
       private static String sqsQueueArn = null;
       private static String startJobId = null;
       private static String bucket = null;
       private static String document = null; 
       private static AmazonSQS sqs=null;
       private static AmazonSNS sns=null;
       private static AmazonTextract textract = null;
   
       public enum ProcessType {
           DETECTION,ANALYSIS
       }
   
       public static void main(String[] args) throws Exception {
           
           String document = "document";
           String bucket = "bucket";
           String roleArn="role";
   
           sns = AmazonSNSClientBuilder.defaultClient();
           sqs= AmazonSQSClientBuilder.defaultClient();
           textract=AmazonTextractClientBuilder.defaultClient();
           
           CreateTopicandQueue();
           ProcessDocument(bucket,document,roleArn,ProcessType.DETECTION);
           DeleteTopicandQueue();
           System.out.println("Done!");
           
           
       }
       // Creates an SNS topic and SQS queue. The queue is subscribed to the topic. 
       static void CreateTopicandQueue()
       {
           //create a new SNS topic
           snsTopicName="AmazonTextractTopic" + Long.toString(System.currentTimeMillis());
           CreateTopicRequest createTopicRequest = new CreateTopicRequest(snsTopicName);
           CreateTopicResult createTopicResult = sns.createTopic(createTopicRequest);
           snsTopicArn=createTopicResult.getTopicArn();
           
           //Create a new SQS Queue
           sqsQueueName="AmazonTextractQueue" + Long.toString(System.currentTimeMillis());
           final CreateQueueRequest createQueueRequest = new CreateQueueRequest(sqsQueueName);
           sqsQueueUrl = sqs.createQueue(createQueueRequest).getQueueUrl();
           sqsQueueArn = sqs.getQueueAttributes(sqsQueueUrl, Arrays.asList("QueueArn")).getAttributes().get("QueueArn");
           
           //Subscribe SQS queue to SNS topic
           String sqsSubscriptionArn = sns.subscribe(snsTopicArn, "sqs", sqsQueueArn).getSubscriptionArn();
           
           // Authorize queue
             Policy policy = new Policy().withStatements(
                     new Statement(Effect.Allow)
                     .withPrincipals(Principal.AllUsers)
                     .withActions(SQSActions.SendMessage)
                     .withResources(new Resource(sqsQueueArn))
                     .withConditions(new Condition().withType("ArnEquals").withConditionKey("aws:SourceArn").withValues(snsTopicArn))
                     );
                     
   
             Map queueAttributes = new HashMap();
             queueAttributes.put(QueueAttributeName.Policy.toString(), policy.toJson());
             sqs.setQueueAttributes(new SetQueueAttributesRequest(sqsQueueUrl, queueAttributes)); 
             
   
            System.out.println("Topic arn: " + snsTopicArn);
            System.out.println("Queue arn: " + sqsQueueArn);
            System.out.println("Queue url: " + sqsQueueUrl);
            System.out.println("Queue sub arn: " + sqsSubscriptionArn );
        }
       static void DeleteTopicandQueue()
       {
           if (sqs !=null) {
               sqs.deleteQueue(sqsQueueUrl);
               System.out.println("SQS queue deleted");
           }
           
           if (sns!=null) {
               sns.deleteTopic(snsTopicArn);
               System.out.println("SNS topic deleted");
           }
       }
       
       //Starts the processing of the input document.
       static void ProcessDocument(String inBucket, String inDocument, String inRoleArn, ProcessType type) throws Exception
       {
           bucket=inBucket;
           document=inDocument;
           roleArn=inRoleArn;
   
           switch(type)
           {
               case DETECTION:
                   StartDocumentTextDetection(bucket, document);
                   System.out.println("Processing type: Detection");
                   break;
               case ANALYSIS:
                   StartDocumentAnalysis(bucket,document);
                   System.out.println("Processing type: Analysis");
                   break;
               default:
                   System.out.println("Invalid processing type. Choose Detection or Analysis");
                   throw new Exception("Invalid processing type");
              
           }
   
           System.out.println("Waiting for job: " + startJobId);
           //Poll queue for messages
           List<Message> messages=null;
           int dotLine=0;
           boolean jobFound=false;
   
           //loop until the job status is published. Ignore other messages in queue.
           do{
               messages = sqs.receiveMessage(sqsQueueUrl).getMessages();
               if (dotLine++<40){
                   System.out.print(".");
               }else{
                   System.out.println();
                   dotLine=0;
               }
   
               if (!messages.isEmpty()) {
                   //Loop through messages received.
                   for (Message message: messages) {
                       String notification = message.getBody();
   
                       // Get status and job id from notification.
                       ObjectMapper mapper = new ObjectMapper();
                       JsonNode jsonMessageTree = mapper.readTree(notification);
                       JsonNode messageBodyText = jsonMessageTree.get("Message");
                       ObjectMapper operationResultMapper = new ObjectMapper();
                       JsonNode jsonResultTree = operationResultMapper.readTree(messageBodyText.textValue());
                       JsonNode operationJobId = jsonResultTree.get("JobId");
                       JsonNode operationStatus = jsonResultTree.get("Status");
                       System.out.println("Job found was " + operationJobId);
                       // Found job. Get the results and display.
                       if(operationJobId.asText().equals(startJobId)){
                           jobFound=true;
                           System.out.println("Job id: " + operationJobId );
                           System.out.println("Status : " + operationStatus.toString());
                           if (operationStatus.asText().equals("SUCCEEDED")){
                               switch(type)
                               {
                                   case DETECTION:
                                       GetDocumentTextDetectionResults();
                                       break;
                                   case ANALYSIS:
                                       GetDocumentAnalysisResults();
                                       break;
                                   default:
                                       System.out.println("Invalid processing type. Choose Detection or Analysis");
                                       throw new Exception("Invalid processing type");
                                  
                               }
                           }
                           else{
                               System.out.println("Document analysis failed");
                           }
   
                           sqs.deleteMessage(sqsQueueUrl,message.getReceiptHandle());
                       }
   
                       else{
                           System.out.println("Job received was not job " +  startJobId);
                           //Delete unknown message. Consider moving message to dead letter queue
                           sqs.deleteMessage(sqsQueueUrl,message.getReceiptHandle());
                       }
                   }
               }
               else {
                   Thread.sleep(5000);
               }
           } while (!jobFound);
   
           System.out.println("Finished processing document");
       }
       
       private static void StartDocumentTextDetection(String bucket, String document) throws Exception{
   
           //Create notification channel 
           NotificationChannel channel= new NotificationChannel()
                   .withSNSTopicArn(snsTopicArn)
                   .withRoleArn(roleArn);
   
           StartDocumentTextDetectionRequest req = new StartDocumentTextDetectionRequest()
                   .withDocumentLocation(new DocumentLocation()
                       .withS3Object(new S3Object()
                           .withBucket(bucket)
                           .withName(document)))
                   .withJobTag("DetectingText")
                   .withNotificationChannel(channel);
   
           StartDocumentTextDetectionResult startDocumentTextDetectionResult = textract.startDocumentTextDetection(req);
           startJobId=startDocumentTextDetectionResult.getJobId();
       }
       
     //Gets the results of processing started by StartDocumentTextDetection
       private static void GetDocumentTextDetectionResults() throws Exception{
           int maxResults=1000;
           String paginationToken=null;
           GetDocumentTextDetectionResult response=null;
           Boolean finished=false;
           
           while (finished==false)
           {
               GetDocumentTextDetectionRequest documentTextDetectionRequest= new GetDocumentTextDetectionRequest()
                       .withJobId(startJobId)
                       .withMaxResults(maxResults)
                       .withNextToken(paginationToken);
               response = textract.getDocumentTextDetection(documentTextDetectionRequest);
               DocumentMetadata documentMetaData=response.getDocumentMetadata();
   
               System.out.println("Pages: " + documentMetaData.getPages().toString());
               
               //Show blocks information
               List<Block> blocks= response.getBlocks();
               for (Block block : blocks) {
                   DisplayBlockInfo(block);
               }
               paginationToken=response.getNextToken();
               if (paginationToken==null)
                   finished=true;
               
           }
           
       }
   
       private static void StartDocumentAnalysis(String bucket, String document) throws Exception{
           //Create notification channel 
           NotificationChannel channel= new NotificationChannel()
                   .withSNSTopicArn(snsTopicArn)
                   .withRoleArn(roleArn);
           
           StartDocumentAnalysisRequest req = new StartDocumentAnalysisRequest()
                   .withFeatureTypes("TABLES","FORMS")
                   .withDocumentLocation(new DocumentLocation()
                       .withS3Object(new S3Object()
                           .withBucket(bucket)
                           .withName(document)))
                   .withJobTag("AnalyzingText")
                   .withNotificationChannel(channel);
   
           StartDocumentAnalysisResult startDocumentAnalysisResult = textract.startDocumentAnalysis(req);
           startJobId=startDocumentAnalysisResult.getJobId();
       }
       //Gets the results of processing started by StartDocumentAnalysis
       private static void GetDocumentAnalysisResults() throws Exception{
   
           int maxResults=1000;
           String paginationToken=null;
           GetDocumentAnalysisResult response=null;
           Boolean finished=false;
           
           //loops until pagination token is null
           while (finished==false)
           {
               GetDocumentAnalysisRequest documentAnalysisRequest= new GetDocumentAnalysisRequest()
                       .withJobId(startJobId)
                       .withMaxResults(maxResults)
                       .withNextToken(paginationToken);
               
               response = textract.getDocumentAnalysis(documentAnalysisRequest);
   
               DocumentMetadata documentMetaData=response.getDocumentMetadata();
   
               System.out.println("Pages: " + documentMetaData.getPages().toString());
   
               //Show blocks, confidence and detection times
               List<Block> blocks= response.getBlocks();
   
               for (Block block : blocks) {
                   DisplayBlockInfo(block);
               }
               paginationToken=response.getNextToken();
               if (paginationToken==null)
                   finished=true;
           }
   
       }
       //Displays Block information for text detection and text analysis
       private static void DisplayBlockInfo(Block block) {
           System.out.println("Block Id : " + block.getId());
           if (block.getText()!=null)
               System.out.println("\tDetected text: " + block.getText());
           System.out.println("\tType: " + block.getBlockType());
           
           if (block.getBlockType().equals("PAGE") !=true) {
               System.out.println("\tConfidence: " + block.getConfidence().toString());
           }
           if(block.getBlockType().equals("CELL"))
           {
               System.out.println("\tCell information:");
               System.out.println("\t\tColumn: " + block.getColumnIndex());
               System.out.println("\t\tRow: " + block.getRowIndex());
               System.out.println("\t\tColumn span: " + block.getColumnSpan());
               System.out.println("\t\tRow span: " + block.getRowSpan());
   
           }
           
           System.out.println("\tRelationships");
           List<Relationship> relationships=block.getRelationships();
           if(relationships!=null) {
               for (Relationship relationship : relationships) {
                   System.out.println("\t\tType: " + relationship.getType());
                   System.out.println("\t\tIDs: " + relationship.getIds().toString());
               }
           } else {
               System.out.println("\t\tNo related Blocks");
           }
   
           System.out.println("\tGeometry");
           System.out.println("\t\tBounding Box: " + block.getGeometry().getBoundingBox().toString());
           System.out.println("\t\tPolygon: " + block.getGeometry().getPolygon().toString());
           
           List<String> entityTypes = block.getEntityTypes();
           
           System.out.println("\tEntity Types");
           if(entityTypes!=null) {
               for (String entityType : entityTypes) {
                   System.out.println("\t\tEntity Type: " + entityType);
               }
           } else {
               System.out.println("\t\tNo entity type");
           }
           
           if(block.getBlockType().equals("SELECTION_ELEMENT")) {
               System.out.print("    Selection element detected: ");
               if (block.getSelectionStatus().equals("SELECTED")){
                   System.out.println("Selected");
               }else {
                   System.out.println(" Not selected");
               }
           }
           if(block.getPage()!=null)
               System.out.println("\tPage: " + block.getPage());            
           System.out.println();
       }
   }
   ```

------
#### [ AWS CLI ]

   IniAWS CLImemulai deteksi asinkron teks dalam dokumen tertentu. Ini menghasilkan`job-id`yang dapat digunakan untuk retreive hasil deteksi. 

   ```
   aws textract start-document-text-detection --document-location 
   "{\"S3Object\":{\"Bucket\":\"bucket-name\",\"Name\":\"file-name\"}}" --region region-name
   ```

   IniAWS CLIperintah mengembalikan hasil untuk operasi asinkron Amazon Textract bila disediakan dengan`job-id`. 

   ```
   aws textract get-document-text-detection --region region-name --job-id job-id-number
   ```

   Jika Anda mengakses CLI pada perangkat Windows, gunakan tanda kutip ganda bukan tanda kutip tunggal dan melarikan diri tanda kutip ganda dalam dengan garis miring terbalik (yaitu\$1) untuk mengatasi kesalahan parser yang mungkin Anda hadapi. Sebagai contoh, lihat di bawah

   ```
   aws textract start-document-text-detection --document-location "{\"S3Object\":{\"Bucket\":\"bucket\",\"Name\":\"document\"}}" --region region-name
   ```

------
#### [ Python ]

   ```
   import boto3
   import json
   import sys
   import time
   
   
   class ProcessType:
       DETECTION = 1
       ANALYSIS = 2
   
   
   class DocumentProcessor:
       jobId = ''
       region_name = ''
   
       roleArn = ''
       bucket = ''
       document = ''
   
       sqsQueueUrl = ''
       snsTopicArn = ''
       processType = ''
   
       def __init__(self, role, bucket, document, region):
           self.roleArn = role
           self.bucket = bucket
           self.document = document
           self.region_name = region
   
           self.textract = boto3.client('textract', region_name=self.region_name)
           self.sqs = boto3.client('sqs')
           self.sns = boto3.client('sns')
   
       def ProcessDocument(self, type):
           jobFound = False
   
           self.processType = type
           validType = False
   
           # Determine which type of processing to perform
           if self.processType == ProcessType.DETECTION:
               response = self.textract.start_document_text_detection(
                   DocumentLocation={'S3Object': {'Bucket': self.bucket, 'Name': self.document}},
                   NotificationChannel={'RoleArn': self.roleArn, 'SNSTopicArn': self.snsTopicArn})
               print('Processing type: Detection')
               validType = True
   
           if self.processType == ProcessType.ANALYSIS:
               response = self.textract.start_document_analysis(
                   DocumentLocation={'S3Object': {'Bucket': self.bucket, 'Name': self.document}},
                   FeatureTypes=["TABLES", "FORMS"],
                   NotificationChannel={'RoleArn': self.roleArn, 'SNSTopicArn': self.snsTopicArn})
               print('Processing type: Analysis')
               validType = True
   
           if validType == False:
               print("Invalid processing type. Choose Detection or Analysis.")
               return
   
           print('Start Job Id: ' + response['JobId'])
           dotLine = 0
           while jobFound == False:
               sqsResponse = self.sqs.receive_message(QueueUrl=self.sqsQueueUrl, MessageAttributeNames=['ALL'],
                                                      MaxNumberOfMessages=10)
   
               if sqsResponse:
   
                   if 'Messages' not in sqsResponse:
                       if dotLine < 40:
                           print('.', end='')
                           dotLine = dotLine + 1
                       else:
                           print()
                           dotLine = 0
                       sys.stdout.flush()
                       time.sleep(5)
                       continue
   
                   for message in sqsResponse['Messages']:
                       notification = json.loads(message['Body'])
                       textMessage = json.loads(notification['Message'])
                       print(textMessage['JobId'])
                       print(textMessage['Status'])
                       if str(textMessage['JobId']) == response['JobId']:
                           print('Matching Job Found:' + textMessage['JobId'])
                           jobFound = True
                           self.GetResults(textMessage['JobId'])
                           self.sqs.delete_message(QueueUrl=self.sqsQueueUrl,
                                                   ReceiptHandle=message['ReceiptHandle'])
                       else:
                           print("Job didn't match:" +
                                 str(textMessage['JobId']) + ' : ' + str(response['JobId']))
                       # Delete the unknown message. Consider sending to dead letter queue
                       self.sqs.delete_message(QueueUrl=self.sqsQueueUrl,
                                               ReceiptHandle=message['ReceiptHandle'])
   
           print('Done!')
   
       def CreateTopicandQueue(self):
   
           millis = str(int(round(time.time() * 1000)))
   
           # Create SNS topic
           snsTopicName = "AmazonTextractTopic" + millis
   
           topicResponse = self.sns.create_topic(Name=snsTopicName)
           self.snsTopicArn = topicResponse['TopicArn']
   
           # create SQS queue
           sqsQueueName = "AmazonTextractQueue" + millis
           self.sqs.create_queue(QueueName=sqsQueueName)
           self.sqsQueueUrl = self.sqs.get_queue_url(QueueName=sqsQueueName)['QueueUrl']
   
           attribs = self.sqs.get_queue_attributes(QueueUrl=self.sqsQueueUrl,
                                                   AttributeNames=['QueueArn'])['Attributes']
   
           sqsQueueArn = attribs['QueueArn']
   
           # Subscribe SQS queue to SNS topic
           self.sns.subscribe(
               TopicArn=self.snsTopicArn,
               Protocol='sqs',
               Endpoint=sqsQueueArn)
   
           # Authorize SNS to write SQS queue
           policy = """{{
     "Version":"2012-10-17",
     "Statement":[
       {{
         "Sid":"MyPolicy",
         "Effect":"Allow",
         "Principal" : {{"AWS" : "*"}},
         "Action":"SQS:SendMessage",
         "Resource": "{}",
         "Condition":{{
           "ArnEquals":{{
             "aws:SourceArn": "{}"
           }}
         }}
       }}
     ]
   }}""".format(sqsQueueArn, self.snsTopicArn)
   
           response = self.sqs.set_queue_attributes(
               QueueUrl=self.sqsQueueUrl,
               Attributes={
                   'Policy': policy
               })
   
       def DeleteTopicandQueue(self):
           self.sqs.delete_queue(QueueUrl=self.sqsQueueUrl)
           self.sns.delete_topic(TopicArn=self.snsTopicArn)
   
       # Display information about a block
       def DisplayBlockInfo(self, block):
   
           print("Block Id: " + block['Id'])
           print("Type: " + block['BlockType'])
           if 'EntityTypes' in block:
               print('EntityTypes: {}'.format(block['EntityTypes']))
   
           if 'Text' in block:
               print("Text: " + block['Text'])
   
           if block['BlockType'] != 'PAGE':
               print("Confidence: " + "{:.2f}".format(block['Confidence']) + "%")
   
           print('Page: {}'.format(block['Page']))
   
           if block['BlockType'] == 'CELL':
               print('Cell Information')
               print('\tColumn: {} '.format(block['ColumnIndex']))
               print('\tRow: {}'.format(block['RowIndex']))
               print('\tColumn span: {} '.format(block['ColumnSpan']))
               print('\tRow span: {}'.format(block['RowSpan']))
   
               if 'Relationships' in block:
                   print('\tRelationships: {}'.format(block['Relationships']))
   
           print('Geometry')
           print('\tBounding Box: {}'.format(block['Geometry']['BoundingBox']))
           print('\tPolygon: {}'.format(block['Geometry']['Polygon']))
   
           if block['BlockType'] == 'SELECTION_ELEMENT':
               print('    Selection element detected: ', end='')
               if block['SelectionStatus'] == 'SELECTED':
                   print('Selected')
               else:
                   print('Not selected')
   
       def GetResults(self, jobId):
           maxResults = 1000
           paginationToken = None
           finished = False
   
           while finished == False:
   
               response = None
   
               if self.processType == ProcessType.ANALYSIS:
                   if paginationToken == None:
                       response = self.textract.get_document_analysis(JobId=jobId,
                                                                      MaxResults=maxResults)
                   else:
                       response = self.textract.get_document_analysis(JobId=jobId,
                                                                      MaxResults=maxResults,
                                                                      NextToken=paginationToken)
   
               if self.processType == ProcessType.DETECTION:
                   if paginationToken == None:
                       response = self.textract.get_document_text_detection(JobId=jobId,
                                                                            MaxResults=maxResults)
                   else:
                       response = self.textract.get_document_text_detection(JobId=jobId,
                                                                            MaxResults=maxResults,
                                                                            NextToken=paginationToken)
   
               blocks = response['Blocks']
               print('Detected Document Text')
               print('Pages: {}'.format(response['DocumentMetadata']['Pages']))
   
               # Display block information
               for block in blocks:
                   self.DisplayBlockInfo(block)
                   print()
                   print()
   
               if 'NextToken' in response:
                   paginationToken = response['NextToken']
               else:
                   finished = True
   
       def GetResultsDocumentAnalysis(self, jobId):
           maxResults = 1000
           paginationToken = None
           finished = False
   
           while finished == False:
   
               response = None
               if paginationToken == None:
                   response = self.textract.get_document_analysis(JobId=jobId,
                                                                  MaxResults=maxResults)
               else:
                   response = self.textract.get_document_analysis(JobId=jobId,
                                                                  MaxResults=maxResults,
                                                                  NextToken=paginationToken)
   
                   # Get the text blocks
               blocks = response['Blocks']
               print('Analyzed Document Text')
               print('Pages: {}'.format(response['DocumentMetadata']['Pages']))
               # Display block information
               for block in blocks:
                   self.DisplayBlockInfo(block)
                   print()
                   print()
   
                   if 'NextToken' in response:
                       paginationToken = response['NextToken']
                   else:
                       finished = True
   
   
   def main():
       roleArn = ''
       bucket = ''
       document = ''
       region_name = ''
   
       analyzer = DocumentProcessor(roleArn, bucket, document, region_name)
       analyzer.CreateTopicandQueue()
       analyzer.ProcessDocument(ProcessType.DETECTION)
       analyzer.DeleteTopicandQueue()
   
   
   if __name__ == "__main__":
       main()
   ```

------
#### [ Node.JS ]

   Dalam contoh ini, ganti nilai`roleArn`dengan peran IAM ARN yang Anda simpan[Memberikan Amazon Textract Akses ke Topik Amazon SNS Anda](api-async-roles.md#api-async-roles-all-topics). Ganti nilai`bucket`dan`document`dengan nama file bucket dan dokumen yang Anda tentukan pada langkah 2 di atas. Ganti nilai`processType`dengan jenis pemrosesan yang ingin Anda gunakan pada dokumen input. Akhirnya, ganti nilai`REGION`dengan wilayah klien Anda beroperasi di.

   ```
    // snippet-start:[sqs.JavaScript.queues.createQueueV3]
   // Import required AWS SDK clients and commands for Node.js
   import { CreateQueueCommand, GetQueueAttributesCommand, GetQueueUrlCommand, 
       SetQueueAttributesCommand, DeleteQueueCommand, ReceiveMessageCommand, DeleteMessageCommand } from  "@aws-sdk/client-sqs";
     import {CreateTopicCommand, SubscribeCommand, DeleteTopicCommand } from "@aws-sdk/client-sns";
     import  { SQSClient } from "@aws-sdk/client-sqs";
     import  { SNSClient } from "@aws-sdk/client-sns";
     import  { TextractClient, StartDocumentTextDetectionCommand, StartDocumentAnalysisCommand, GetDocumentAnalysisCommand, GetDocumentTextDetectionCommand, DocumentMetadata } from "@aws-sdk/client-textract";
     import { stdout } from "process";
     
     // Set the AWS Region.
     const REGION = "us-east-1"; //e.g. "us-east-1"
     // Create SNS service object.
     const sqsClient = new SQSClient({ region: REGION });
     const snsClient = new SNSClient({ region: REGION });
     const textractClient = new TextractClient({ region: REGION });
     
     // Set bucket and video variables
     const bucket = "bucket-name";                                                                                                                  
     const documentName = "document-name";
     const roleArn = "role-arn"
     const processType = "DETECTION"
     var startJobId = ""
     
     var ts = Date.now();
     const snsTopicName = "AmazonTextractExample" + ts;
     const snsTopicParams = {Name: snsTopicName}
     const sqsQueueName = "AmazonTextractQueue-" + ts;
   
     // Set the parameters
     const sqsParams = {
       QueueName: sqsQueueName, //SQS_QUEUE_URL
       Attributes: {
         DelaySeconds: "60", // Number of seconds delay.
         MessageRetentionPeriod: "86400", // Number of seconds delay.
       },
     };
     
     // Process a document based on operation type
     const processDocumment = async (type, bucket, videoName, roleArn, sqsQueueUrl, snsTopicArn) =>
       {
       try
       {
           // Set job found and success status to false initially
         var jobFound = false
         var succeeded = false
         var dotLine = 0
         var processType = type
         var validType = false
   
         if (processType == "DETECTION"){
           var response = await textractClient.send(new StartDocumentTextDetectionCommand({DocumentLocation:{S3Object:{Bucket:bucket, Name:videoName}}, 
             NotificationChannel:{RoleArn: roleArn, SNSTopicArn: snsTopicArn}}))
           console.log("Processing type: Detection")
           validType = true
         }
   
         if (processType == "ANALYSIS"){
           var response = await textractClient.send(new StartDocumentAnalysisCommand({DocumentLocation:{S3Object:{Bucket:bucket, Name:videoName}}, 
             NotificationChannel:{RoleArn: roleArn, SNSTopicArn: snsTopicArn}}))
           console.log("Processing type: Analysis")
           validType = true
         }
   
         if (validType == false){
             console.log("Invalid processing type. Choose Detection or Analysis.")
             return
         }
       // while not found, continue to poll for response
       console.log(`Start Job ID: ${response.JobId}`)
       while (jobFound == false){
         var sqsReceivedResponse = await sqsClient.send(new ReceiveMessageCommand({QueueUrl:sqsQueueUrl, 
           MaxNumberOfMessages:'ALL', MaxNumberOfMessages:10}));
         if (sqsReceivedResponse){
           var responseString = JSON.stringify(sqsReceivedResponse)
           if (!responseString.includes('Body')){
             if (dotLine < 40) {
               console.log('.')
               dotLine = dotLine + 1
             }else {
               console.log('')
               dotLine = 0 
             };
             stdout.write('', () => {
               console.log('');
             });
             await new Promise(resolve => setTimeout(resolve, 5000));
             continue
           }
         }
   
           // Once job found, log Job ID and return true if status is succeeded
           for (var message of sqsReceivedResponse.Messages){
               console.log("Retrieved messages:")
               var notification = JSON.parse(message.Body)
               var rekMessage = JSON.parse(notification.Message)
               var messageJobId = rekMessage.JobId
               if (String(rekMessage.JobId).includes(String(startJobId))){
                   console.log('Matching job found:')
                   console.log(rekMessage.JobId)
                   jobFound = true
                   // GET RESUlTS FUNCTION HERE
                   var operationResults = await GetResults(processType, rekMessage.JobId)
                   //GET RESULTS FUMCTION HERE
                   console.log(rekMessage.Status)
               if (String(rekMessage.Status).includes(String("SUCCEEDED"))){
                   succeeded = true
                   console.log("Job processing succeeded.")
                   var sqsDeleteMessage = await sqsClient.send(new DeleteMessageCommand({QueueUrl:sqsQueueUrl, ReceiptHandle:message.ReceiptHandle}));
               }
               }else{
               console.log("Provided Job ID did not match returned ID.")
               var sqsDeleteMessage = await sqsClient.send(new DeleteMessageCommand({QueueUrl:sqsQueueUrl, ReceiptHandle:message.ReceiptHandle}));
               }
           }
   
       console.log("Done!")
       }
       }catch (err) {
           console.log("Error", err);
         }
     }
   
     // Create the SNS topic and SQS Queue
     const createTopicandQueue = async () => {
       try {
         // Create SNS topic
         const topicResponse = await snsClient.send(new CreateTopicCommand(snsTopicParams));
         const topicArn = topicResponse.TopicArn
         console.log("Success", topicResponse);
         // Create SQS Queue
         const sqsResponse = await sqsClient.send(new CreateQueueCommand(sqsParams));
         console.log("Success", sqsResponse);
         const sqsQueueCommand = await sqsClient.send(new GetQueueUrlCommand({QueueName: sqsQueueName}))
         const sqsQueueUrl = sqsQueueCommand.QueueUrl
         const attribsResponse = await sqsClient.send(new GetQueueAttributesCommand({QueueUrl: sqsQueueUrl, AttributeNames: ['QueueArn']}))
         const attribs = attribsResponse.Attributes
         console.log(attribs)
         const queueArn = attribs.QueueArn
         // subscribe SQS queue to SNS topic
         const subscribed = await snsClient.send(new SubscribeCommand({TopicArn: topicArn, Protocol:'sqs', Endpoint: queueArn}))
         const policy = {
           Version: "2012-10-17",
           Statement: [
             {
               Sid: "MyPolicy",
               Effect: "Allow",
               Principal: {AWS: "*"},
               Action: "SQS:SendMessage",
               Resource: queueArn,
               Condition: {
                 ArnEquals: {
                   'aws:SourceArn': topicArn
                 }
               }
             }
           ]
         };
     
         const response = sqsClient.send(new SetQueueAttributesCommand({QueueUrl: sqsQueueUrl, Attributes: {Policy: JSON.stringify(policy)}}))
         console.log(response)
         console.log(sqsQueueUrl, topicArn)
         return [sqsQueueUrl, topicArn]
     
       } catch (err) {
         console.log("Error", err);
   
       }
     }
   
     const deleteTopicAndQueue = async (sqsQueueUrlArg, snsTopicArnArg) => {
       const deleteQueue = await sqsClient.send(new DeleteQueueCommand({QueueUrl: sqsQueueUrlArg}));
       const deleteTopic = await snsClient.send(new DeleteTopicCommand({TopicArn: snsTopicArnArg}));
       console.log("Successfully deleted.")
     }
   
     const displayBlockInfo = async (block) => {
       console.log(`Block ID: ${block.Id}`)
       console.log(`Block Type: ${block.BlockType}`)
       if (String(block).includes(String("EntityTypes"))){
           console.log(`EntityTypes: ${block.EntityTypes}`)
       }
       if (String(block).includes(String("Text"))){
           console.log(`EntityTypes: ${block.Text}`)
       }
       if (!String(block.BlockType).includes('PAGE')){
           console.log(`Confidence: ${block.Confidence}`)
       }
       console.log(`Page: ${block.Page}`)
       if (String(block.BlockType).includes("CELL")){
           console.log("Cell Information")
           console.log(`Column: ${block.ColumnIndex}`)
           console.log(`Row: ${block.RowIndex}`)
           console.log(`Column Span: ${block.ColumnSpan}`)
           console.log(`Row Span: ${block.RowSpan}`)
           if (String(block).includes("Relationships")){
               console.log(`Relationships: ${block.Relationships}`)
           }
       }
   
       console.log("Geometry")
       console.log(`Bounding Box: ${JSON.stringify(block.Geometry.BoundingBox)}`)
       console.log(`Polygon: ${JSON.stringify(block.Geometry.Polygon)}`)
   
       if (String(block.BlockType).includes('SELECTION_ELEMENT')){
         console.log('Selection Element detected:')
         if (String(block.SelectionStatus).includes('SELECTED')){
           console.log('Selected')
         } else {
           console.log('Not Selected')
         }
   
       }
     }
   
     const GetResults = async (processType, JobID) => {
   
       var maxResults = 1000
       var paginationToken = null
       var finished = false
   
       while (finished == false){
         var response = null
         if (processType == 'ANALYSIS'){
           if (paginationToken == null){
             response = textractClient.send(new GetDocumentAnalysisCommand({JobId:JobID, MaxResults:maxResults}))
         
           }else{
             response = textractClient.send(new GetDocumentAnalysisCommand({JobId:JobID, MaxResults:maxResults, NextToken:paginationToken}))
           }
         }
           
         if(processType == 'DETECTION'){
           if (paginationToken == null){
             response = textractClient.send(new GetDocumentTextDetectionCommand({JobId:JobID, MaxResults:maxResults}))
         
           }else{
             response = textractClient.send(new GetDocumentTextDetectionCommand({JobId:JobID, MaxResults:maxResults, NextToken:paginationToken}))
           }
         }
   
         await new Promise(resolve => setTimeout(resolve, 5000));
         console.log("Detected Documented Text")
         console.log(response)
         //console.log(Object.keys(response))
         console.log(typeof(response))
         var blocks = (await response).Blocks
         console.log(blocks)
         console.log(typeof(blocks))
         var docMetadata = (await response).DocumentMetadata
         var blockString = JSON.stringify(blocks)
         var parsed = JSON.parse(JSON.stringify(blocks))
         console.log(Object.keys(blocks))
         console.log(`Pages: ${docMetadata.Pages}`)
         blocks.forEach((block)=> {
           displayBlockInfo(block)
           console.log()
           console.log()
         })
   
         //console.log(blocks[0].BlockType)
         //console.log(blocks[1].BlockType)
   
   
         if(String(response).includes("NextToken")){
           paginationToken = response.NextToken
         }else{
           finished = true
         }
       }
   
     }
   
   
     // DELETE TOPIC AND QUEUE
     const main = async () => {
       var sqsAndTopic = await createTopicandQueue();
       var process = await processDocumment(processType, bucket, documentName, roleArn, sqsAndTopic[0], sqsAndTopic[1])
       var deleteResults = await deleteTopicAndQueue(sqsAndTopic[0], sqsAndTopic[1])
     }
   
   main()
   ```

------

1. Jalankan kode tersebut. Operasi mungkin membutuhkan waktu beberapa saat untuk menyelesaikan. Setelah selesai, daftar blok untuk teks yang terdeteksi atau dianalisis akan ditampilkan.

# Pemberitahuan Amazon Textract
<a name="async-notification-payload"></a>

Amazon Textract menerbitkan hasil permintaan analisis Amazon Textract, termasuk status penyelesaian, ke topik Amazon Simple Notification Service (Amazon SNS). Untuk mendapatkan notifikasi dari topik Amazon SNS, gunakan antrean Amazon SQS atauAWS Lambdafungsi. Untuk informasi selengkapnya, lihat [Memanggil Operasi Asinkron Amazon Texact](api-async.md). Sebagai contoh, lihat [Mendeteksi atau Menganalisis Teks dalam Dokumen Multipage](async-analyzing-with-sqs.md).

Hasilnya memiliki format JSON berikut:

```
{
  "JobId": "String",
  "Status": "String",
  "API": "String",
  "JobTag": "String",
  "Timestamp": Number,
  "DocumentLocation": {
    "S3ObjectName": "String",
    "S3Bucket": "String"
  }
}
```

Tabel ini menjelaskan parameter yang berbeda dalam respons Amazon Textract.


| Parameter | Deskripsi | 
| --- | --- | 
|  JobId  |  Pengenal unik yang diberikan Amazon Textract untuk pekerjaan itu. Cocok dengan pengidentifikasi tugas yang dikembalikan dari`Start`operasi, seperti[StartDocumentTextDetection](API_StartDocumentTextDetection.md).  | 
|  Status  |  Status tugas. Nilai yang valid adalah Berhasil, Gagal, atau Kesalahan.  | 
|  API  |  Operasi Amazon Textract Texact yang digunakan untuk menganalisis dokumen input, seperti[StartDocumentTextDetection](API_StartDocumentTextDetection.md)atau[StartDocumentAnalysis](API_StartDocumentAnalysis.md).  | 
|  JobTag  |  Pengidentifikasi yang ditentukan pengguna untuk tugas tersebut. Anda menentukan`JobTag`dalam panggilan ke`Start`operasi, seperti[StartDocumentTextDetection](API_StartDocumentTextDetection.md).  | 
|  Timestamp  |  The Unix timestamp yang menunjukkan ketika pekerjaan selesai, kembali dalam milidetik.  | 
|  DokumenLokasi  |  Detail tentang dokumen yang telah diproses. Mencakup nama file dan bucket Amazon S3 tempat file disimpan.  | 