Blog AWS Indonesia

Membangun Bot Cuaca Serverless dengan SMS Dua-Arah, AWS SAM, dan AWS Lambda

Banyak orang yang senang diberikan fasilitas untuk mengirim pesan teks ke perusahaan untuk mengubah appointment, mendapatkan dukungan, atau menerima pembaruan pesanan. Short Message Service (SMS) ada di mana-mana di seluruh dunia dan didukung di hampir setiap ponsel yang dapat Anda temukan hari ini. Ini juga bisa menjadi antarmuka yang baik untuk berbagai aplikasi bisnis.

Banyak pengembang tahu bahwa Amazon SNS dapat mengirim pesan teks satu arah. Tetapi, hanya sedikit yang tahu tentang menangani percakapan dua arah dengan layanan lain yang tersedia. Dalam contoh yang dibahas pada tulisan ini, Anda dapat mengatur dan menggunakan SMS dua arah dalam waktu sekitar 10 menit.

Contoh ini membuat bot cuaca yang merespons pesan teks dari pengguna, memberikan informasi cuaca sesuai kode pos yang diminta. Demo ini hanya berfungsi untuk pengguna Amerika Serikat, tetapi prinsip desain aplikasi ini berlaku di mana saja. Anda akan menerima balasan dalam beberapa detik berisi laporan cuaca saat ini.

Tulisan ini mencakup langkah-langkah berikut:

  • Menyiapkan nomor telepon di Amazon Pinpoint.
  • Melakukan penerapan (deployment) aplikasi serverless menggunakan AWS SAM untuk merespons pesan teks.
  • Meninjau kode yang digunakan dalam fungsi AWS Lambda.

Arsitektur akhir terlihat seperti diagram berikut:

Menyiapkan Amazon Pinpoint

Amazon Pinpoint menyediakan berbagai cara berbeda untuk mengirim pesan pribadi ke pelanggan. Hal ini memudahkan untuk mengoordinasikan pesan dalam jumlah besar untuk aplikasi web atau seluler. Hal ini dirancang untuk membantu Anda mendorong keterlibatan dan membuat aplikasi lebih bermanfaat bagi pengguna Anda. Proyek ini menggunakan fitur pengiriman pesan teks dua arah, tetapi Amazon Pinpoint memiliki berbagai kemampuan lainnya.

Pertama, atur nomor telepon untuk proyek ini. Amazon Pinpoint menyediakan nomor khusus, yang saat ini berharga $1/bulan dan tidak termasuk dalam tunjangan Tingkat Gratis (Free Tier). Anda juga dikenai biaya untuk pesan teks, jadi pastikan untuk meninjau harga saat ini sebelum merilis aplikasi apa pun ke production.

Untuk memesan nomor telepon khusus Anda, ikuti langkah-langkah ini:

  1. Masuk ke konsol Amazon Pinpoint.
  2. Pastikan Anda berada di Wilayah tempat Amazon Pinpoint didukung. Untuk daftar terbaru, lihat AWS Service Endpoints. Panduan ini menggunakan us-east-1 (US East – N. Virginia).
  3. Pada halaman Get started, untuk Project name, masukkan weatherApp, dan pilih Create a project.
  4. Pada halaman Configure features, untuk SMS and voice, pilih Configure.
  5. Pilih Enable the SMS channel for this project, dan pilih Save changes.
  6. Pilih Settings, SMS and voice.

    Untuk Target country or Region, pilih United States. Untuk Default call type, pilih Promotional dan lalu pilih Request long codes. Halaman konfirmasi menunjukkan bahwa nomor telepon baru telah ditambahkan ke akun.
  7. Di bawah Number settings, pilih Request long codes.
  8. Di bagian atas halaman, pilih All projects, dan catat Project ID. Anda memerlukan nilai ini di bagian selanjutnya.

Anda sekarang memiliki nomor telepon khusus yang siap menerima pesan SMS. Saat ini, pesan tidak dialihkan ke mana pun. Anda akan mengkonfigurasi hal ini di bagian selanjutnya.

Menyiapkan Aplikasi Serverless

Sebelum melakukan penerapan (deployment) kode, Anda memerlukan kunci API dari layanan OpenWeatherMap. Untuk akun gratis, daftar di halaman Create New Account. Layanan ini menyediakan API dimana Anda dapat mengirimkan kode pos dan menerima kondisi cuaca saat ini untuk lokasi tersebut.

Pastikan Anda telah memasang AWS CLI dan AWS SAM CLI sebelum melanjutkan. Anda menggunakan alat-alat ini dari command line untuk mengotomatiskan deployment aplikasi ini. Kode untuk langkah-langkah ini disimpan dalam repositori GitHub aws-serverless-sar-pinpoint-weather. Anda menggunakan templat AWS SAM dalam repositori untuk mengoordinasikan deployment fungsi Lambda dan SNS topic.

  1. Buat direktori baru yang kosong di mesin lokal Anda dan melakukan kloning repositori:
    git clone https://github.com/jbesw/aws-serverless-sar-pinpoint-weather-bot

  2. Buat bucket untuk deployment (tentukan nama bucket yang unik):
    aws s3 mb s3://your_bucket_name

    Ubah ke direktori yang dikloning:

    cd .\aws-serverless-sar-pinpoint-weather-bot\
  3. Jalankan proses build AWS SAM dan buat AWS SAM package.

    sam build
    sam package --output-template-file packaged.yaml --s3-bucket your_bucket_name

     

  4. Deploy aplikasi AWS SAM:
    1. Ganti APIKeyAnda dengan kunci API OpenWeatherMap.
    2. Ganti ApplicationIDAnda dengan ID proyek Amazon Pinpoint dari bagian pertama.
      sam deploy --template-file packaged.yaml \
        --stack-name myWeatherBot
        --capabilities CAPABILITY_IAM
        --region us-east-1
        –-parameter-overrides APIkey=<<yourAPIkey>> ApplicationId=<<yourApplicationId>

Setelah menjalankan perintah ini, konsol menampilkan pesan berikut:

Successfully created/updated stack – myWeatherBot.

Pada titik ini, Anda telah menggunakan Lambda function untuk memproses logika utama aplikasi dan SNS topic untuk menerima pesan teks. Langkah terakhir adalah menghubungkan layanan Amazon Pinpoint dengan SNS topic yang telah dibuat oleh AWS SAM template ini.

Hubungkan Amazon Pinpoint ke Amazon SNS

Buka konsol SNS untuk menemukan topic yang dibuat oleh deployment, dan salin ARN ke clipboard.

Untuk menambahkan SNS topic ke proyek Amazon Pinpoint:

  1. Di konsol Amazon Pinpoint, di bawah All projects, pilih proyek weatherApp Anda.
  2. Di panel navigasi kiri, pilih Settings, SMS and voice.
  3. Di bawah Number settings, pilih nomor telepon. Expand bagian Two-way SMS, dan centang Enable two-way SMS.
  4. Di bawah Incoming message destination, pilih Choose an existing SNS topic, lalu pilih ARN yang Anda salin sebelumnya.
  5. Pilih Save.

Sekarang Anda dapat menguji deployment Anda. Kirimkan weather <kode pos> ke nomor telepon khusus Anda. Server akan merespons dengan ringkasan cuaca.

Meninjau Kode

Ketika Amazon Pinpoint menerima pesan teks yang masuk ke nomor telepon khusus, Amazon Pinpoint menerbitkan pesan ke SNS topic. Fungsi Lambda yang melakukan langganan ke topik ini akan dipanggil setiap kali pesan baru tiba.

App.js berisi entry point untuk Lambda handler, menyediakan top-level error handler dan melakukan iterasi melalui event object jika beberapa pesan diterima. Setiap pesan dikirim ke fungsi smsResponder. Hal ini terbungkus await Promise.all sehingga pemrosesan terjadi secara paralel, karena pesan tidak saling bergantung.

exports.lambdaHandler = async (event, context) => {
  console.log('Starting handler')
  
  await Promise.all(
    event.Records.map(async (record) => {
      try {
        await smsResponder(record)
      } catch (err) {
        console.error(err)
        return err
      }
    })
  )

  return  {
    'statusCode': 200
  }
}

smsResponder.js memeriksa apakah pesan teks dimulai dengan kata kunci (weather), diikuti oleh kode pos yang valid. Setelah meminta ringkasan cuaca, ia mengirimkan respons kembali ke Amazon Pinpoint untuk mengirim SMS kembali ke pengguna.

Ketika objek params di-build untuk membuat pesan teks yang merespons, fungsi ini membalikkan nomor telepon tujuan dan asal dari pesan yang masuk. Itu menandai pesan sebagai PROMOTIONAL, dan mengatur response channel menjadi SMS.

const AWS = require('aws-sdk')
AWS.config.update({ region: process.env.AWS_REGION || 'us-east-1' })

const { getWeather } = require('./getWeather')
const KEYWORD = 'weather'

const validateZipCode = function (elementValue){
  let zipCodePattern = /^\d{5}$|^\d{5}-\d{4}$/
   return zipCodePattern.test(elementValue)
}

const sendSMS = async function (params) {
  const pinpoint = new AWS.Pinpoint()
  console.log('sendSMS called: ', JSON.stringify(params, null, 2))

  return new Promise((resolve, reject) => {
    pinpoint.sendMessages(params, function(err, data) {
      if(err) {
        console.error('sendSMS error:', err)
        reject(err)
      } else {
        console.log("Message sent. Data: ", data)
        resolve(data)
      }
    })
  })
}

const smsResponder = async (event) => {

  const msg = JSON.parse(event.Sns.Message)
  const msgWords = msg.messageBody.split(" ")

  // Check the first word of the text message is the keyword
  if (msgWords[0].toLowerCase() !== KEYWORD) return console.log('No keyword found - exiting')

  // Validate zip code and get the weather
  let message =''
  const zipCode = msgWords[1]

  if (validateZipCode(zipCode)) {
    message = await getWeather(zipCode)
  } else {
    message = 'Invalid zip code - text me in the format "weather 00000".'
  }

  // Send the SMS response
  var params = {
    ApplicationId: process.env.ApplicationId,
    MessageRequest: {
      Addresses: {
        [msg.originationNumber]: {
          ChannelType: 'SMS'
        }
      },
      MessageConfiguration: {
        SMSMessage: {
          Body: message,
          MessageType: 'PROMOTIONAL',
          OriginationNumber: msg.destinationNumber
        }
      }
    }
  }

Terakhir, getWeather.js mengambil kode pos dan melakukan permintaan API OpenWeatherMap untuk mendapatkan ringkasan cuaca. Ia melakukan beberapa pemrosesan yang minimal untuk mengubah hasilnya menjadi pesan teks.

const getWeather = async function (zipCode) {

  try {
    // Get weather for the zip code provided
    const response = await axios({
      url: `${weatherURL}&zip=${zipCode}&APPID=${process.env.APIkey}`,
      method: 'get',
      port: 443,
      responseType: JSON
    })

    // Build natural response
    const weather = `Weather in ${response.data.name}: ${response.data.weather[0].description}, currently ${parseInt(response.data.main.temp)} degrees with a low of ${parseInt(response.data.main.temp_min)} and a high of ${parseInt(response.data.main.temp_max)}.`
    console.log('getWeather response: ', weather)
    return weather

  } catch (err) {
    console.error('getWeather error: ', err)

Kesimpulan

Amazon Pinpoint menyederhanakan penanganan SMS dua arah ke telepon pelanggan. Lambda function dapat memeriksa pesan teks yang masuk, memproses data, dan mengirim respons, semuanya dalam 100 baris kode. Meskipun contoh ini hanya memeriksa cuaca satu kali, fungsionalitas dapat diperluas ke salah satu hal berikut:

  • Mengirim laporan cuaca harian.
  • Memberikan peringatan untuk peristiwa cuaca yang signifikan.
  • Menambahkan kata kunci tambahan untuk mendukung berbagai jenis kueri, seperti rata-rata cuaca.

Selain itu, alur ini dapat digunakan untuk membantu mendukung pemrosesan pesanan, manajemen appointment, atau membuat kampanye pemasaran. Menambahkan SMS dua arah memberi pelanggan Anda cara baru untuk berinteraksi dengan aplikasi bisnis Anda.


Tulisan ini berasal dari artikel Building a serverless weather bot with two-way SMS, AWS SAM, and AWS Lambda yang ditulis oleh James Beswick dan diterjemahkan oleh Teddy Aryono.

Petra Barus

Petra Barus

Petra Novandi Barus is Developer Advocate at Amazon Web Services based in Jakarta. He is passionate in helping startups and developers in Indonesia to reinvent on behalf their customers. Prior to AWS, Petra co-founded UrbanIndo.com as CTO. The startup became the largest real-estate portal in Indonesia and then was acquired by 99.co. During that time Petra had been a happy AWS customer for 8 years. Petra is also very active in local tech communities