Cara menggunakan alat Twilio, Python, dan Google untuk mengotomatisasi pernikahan Anda

Penulis artikel tersebut menceritakan bagaimana ia berhasil menerapkan keterampilan pemrograman untuk mengotomatiskan proses rutin acara pernikahannya sendiri.

Bagi kebanyakan orang, 3 September 2016 adalah hari Sabtu yang paling umum, tetapi dalam ingatan saya tanggal ini akan tetap selamanya, karena pada hari ini saya dan istri saya bermain pernikahan.

gambar

Saat merencanakan pernikahan, Anda perlu mempertimbangkan banyak hal: makanan, dekorasi dan dekorasi, lampu meja (ya, terpisah dari dekorasi), bunga, akomodasi tamu, transportasi, hiburan, dan pilihan tempat. Secara umum, ketika merencanakan pernikahan, Anda dihadapkan dengan banyak hal yang tidak diketahui, tetapi saya yakin akan satu hal: tidak ada pernikahan yang dapat dilakukan tanpa banyak daftar, daftar bersarang yang tidak berakhir sampai akhir. Semakin banyak daftar melayang di depan mata saya, semakin sering saya mulai berpikir tentang cara meningkatkan proses persiapan. Itu sangat tidak efisien dan semua pekerjaan dilakukan secara manual. Saya yakin teknologi pasti dapat membantu meningkatkan setidaknya beberapa poin.

Anda mungkin terkejut mengetahui bahwa mengundang orang ke pernikahan itu mahal (lebih dari 380 pound per orang). Pertama, Anda perlu mengirim undangan awal dengan tanggal dan pemberitahuan singkat, dan hanya kemudian - lengkap, dengan deskripsi acara yang lebih rinci. Semua ini, apalagi, dikirim melalui pos, yang artinya lambat. Upaya untuk "menangkap" undangan dan mendapatkan jawaban dari mereka tentang apakah mereka ingin datang ke liburan dengan makanan dan minuman gratis (walaupun, tampaknya, siapa yang tidak mau?!) Membutuhkan banyak waktu. Dan akhirnya, mengirimkan undangan tidak ramah lingkungan, karena kartu kertas adalah hal yang hanya sekali, mereka dengan cepat lupa dan menjadi tidak berguna bagi siapa pun.

Tetapi kembali ke daftar. Kami membagi tamu menjadi beberapa grup:

  1. Yang ingin Anda lihat di festival
  2. Mereka yang menjawab undangan kedua meminta tanggapan
  3. Mereka yang menerima undangan
  4. Mereka yang menerima undangan dan memilih makanan

Tapi saya suka daftar: mereka memiliki beberapa persyaratan yang telah ditetapkan yang mengubahnya menjadi objek hebat untuk otomatisasi.

Pesan dalam Botol


Saya yakin bahwa semua tamu potensial, berapapun usianya, memiliki telepon seluler, yang berarti sudah tiba saatnya bagi Twilio. Kode yang diberikan di sini dapat dilewati dengan aman jika diinginkan, karena selalu tersedia di repositori GitHub yang sesuai.

SMS sebagai saluran komunikasi sangat sesuai dengan kebutuhan saya. Saya dapat mengatur pengiriman surat secara massal, dengan cepat dan efisien memproses tanggapan. Membuat sketsa kerja pertama dari produk dan mempertimbangkan pilihan basis data, saya mencoba melakukan sesuatu yang sederhana yang dapat dengan mudah dibagikan dan tidak ingin menghabiskan banyak waktu untuk penampilan. Pada akhirnya, saya menemukan perpustakaan python gspread, yang memungkinkan saya untuk membaca dan menulis ke tabel google . Ini bukan pilihan tercepat, tetapi lebih fleksibel, yang membuatnya mudah untuk mengakses tabel dan membaca hasil.

Untuk prompt pertama, saya membuat tabel dengan tiga kolom:

  • Nama
  • Nomor telepon
  • Confirmation_status (Status Konfirmasi)
  • Status detail kontak
  • Message_count (Jumlah pesan yang dikirim ke tamu sangat berguna di masa depan)

Setelah menyelesaikan entri data dasar, saya menjalankan daftar melalui gspread , yang mengirim SMS ke setiap tamu yang memiliki nomor ponsel:

import json import time import gspread from oauth2client.client import SignedJwtAssertionCredentials from twilio.rest import TwilioRestClient #      #     json,    json_key = json.load(open('.json')) scope = ['https://spreadsheets.google.com/feeds'] credentials = SignedJwtAssertionCredentials(json_key['client_email'], json_key['private_key'].encode(), scope) gc = gspread.authorize(credentials) wks = gc.open("wedding_guests") #     workbook- wks_attendees = wks.get_worksheet(0) #     ACCOUNT_SID = 'TWILIO_ACCOUNT_SID' AUTH_TOKEN = 'TWILIO_AUTH_TOKEN' client = TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN) #    ,   range    for num in range(2, 60): print "sleeping for 2 seconds" time.sleep(2) #         guest_number = wks_attendees.acell('B'+str(num)).value guest_name = wks_attendees.acell('A'+str(num)).value Message_body = <span class="pl-s"><span class="pl-k">u</span><span class="pl-pds">"</span><span class="pl-cce">\u2B50</span><span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-s"><span class="pl-k">u</span><span class="pl-pds">"</span><span class="pl-cce">\u2764</span><span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-s"><span class="pl-k">u</span><span class="pl-pds">"</span><span class="pl-cce">\u2B50</span><span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-s"><span class="pl-k">u</span><span class="pl-pds">"</span><span class="pl-cce">\u2764</span><span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-s"><span class="pl-k">u</span><span class="pl-pds">"</span><span class="pl-cce">\u2B50</span><span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-s"><span class="pl-k">u</span><span class="pl-pds">"</span><span class="pl-cce">\u2764</span><span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-s"><span class="pl-k">u</span><span class="pl-pds">"</span><span class="pl-cce">\u2B50</span><span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-s"><span class="pl-k">u</span><span class="pl-pds">"</span><span class="pl-cce">\u2764</span><span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-s"><span class="pl-pds">"</span><span class="pl-cce">\n\n</span><span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-s"><span class="pl-k">u</span><span class="pl-pds">"</span><span class="pl-cce">\u2709</span><span class="pl-pds">"</span></span> <span class="pl-k">+</span><span class="pl-s"><span class="pl-pds">"</span> Save the date! <span class="pl-pds">"</span></span><span class="pl-k">+</span> <span class="pl-s"><span class="pl-k">u</span><span class="pl-pds">"</span><span class="pl-cce">\u2709</span><span class="pl-pds">"</span></span> <span class="pl-k">+</span><span class="pl-s"><span class="pl-pds">"</span><span class="pl-cce">\n\n</span>Lauren Pang and Thomas Curtis are delighted to invite you to our wedding.<span class="pl-cce">\n\n</span>Saturday 3rd September 2016. <span class="pl-cce">\n\n</span>Colville Hall,<span class="pl-cce">\n</span>Chelmsford Road,<span class="pl-cce">\n</span>White Roding,<span class="pl-cce">\n</span>CM6 1RQ.<span class="pl-cce">\n\n</span>The Ceremony begins at 2pm.<span class="pl-cce">\n\n</span>More details will follow shortly!<span class="pl-cce">\n\n</span>Please text YES if you are saving the date and can join us or text NO if sadly, you won't be able to be with us.<span class="pl-cce">\n\n</span><span class="pl-pds">"</span></span> <span class="pl-s"><span class="pl-k">u</span><span class="pl-pds">"</span><span class="pl-cce">\u2B50</span><span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-s"><span class="pl-k">u</span><span class="pl-pds">"</span><span class="pl-cce">\u2764</span><span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-s"><span class="pl-k">u</span><span class="pl-pds">"</span><span class="pl-cce">\u2B50</span><span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-s"><span class="pl-k">u</span><span class="pl-pds">"</span><span class="pl-cce">\u2764</span><span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-s"><span class="pl-k">u</span><span class="pl-pds">"</span><span class="pl-cce">\u2B50</span><span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-s"><span class="pl-k">u</span><span class="pl-pds">"</span><span class="pl-cce">\u2764</span><span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-s"><span class="pl-k">u</span><span class="pl-pds">"</span><span class="pl-cce">\u2B50</span><span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-s"><span class="pl-k">u</span><span class="pl-pds">"</span><span class="pl-cce">\u2764</span><span class="pl-pds">"</span></span>, if not guest_number: #      print guest_name + ' telephone number empty not messaging' wks_attendees.update_acell('E'+str(num), '0') else: print 'Sending message to ' + guest_name client.messages.create( to="+" + guest_number, #  +   e.164 from_="", #     Twillio body=message_body, ) wks_attendees.update_acell('E'+str(num), int(wks_attendees.acell('E'+str(num)).value) + 1) # increment the message count row else: # else-  print 'finished' 

Dan karena SMS biasanya terlihat sedikit membosankan, saya menambahkan beberapa Unicode untuk membuatnya lebih menarik. Seperti inilah bentuk pesan untuk tamu yang beruntung:

gambar

Selanjutnya, saya menggunakan Flask sebagai server web, membuat permintaan URL saya untuk Twilio Messaging point ke / pesan, dan menambahkan if-check sederhana ke parse response:

 @app.route("/messages", methods=['GET', 'POST']) def hello_guest():  if "yes" in body_strip:    #      confirmation_status    wks_attendees.update_acell("F"+str(guest_confirmation_cell.row), 'Accepted')  #    ยซ ยป       resp.message(u"\u2665" + "Thanks for confirming, we'll be in touch!" + u"\u2665")  # r ,    elif "no" in from_body.lower():    #    ยซ ยป       wks_attendees.update_acell("F"+str(guest_confirmation_cell.row), 'Declined')    #       resp.message("Sorry to hear that, we still love you though!")  else:  #  ,        resp.message("You sent a different keyword, we need a yes or a no, you sent: "+           from_body)  return str(resp) 

gambargambar

Pesan pertama dikirim pada pukul 8:37 pada 19 Februari, dan konfirmasi pertama diterima sedikit kemudian pada pukul 8:40. Pada 9:38, saya sudah menerima 23 konfirmasi, yaitu, 32% jawaban ada di saku saya! 2 hari setelah dimulainya pengiriman massal, 58% tamu telah mengkonfirmasi keikutsertaan mereka. Meskipun keberhasilannya jelas, calon istri saya belum 100% terkesan dengan layanan SMS saya untuk undangan pernikahan, dan saya memutuskan untuk menambahkan beberapa fungsi lagi ke aplikasi.

Statistik! Saya bisa membuat daftar tamu terkini dan memberikannya atas permintaan, memberikan calon pengantin saya umpan balik instan. Kode itu ternyata sangat sederhana, karena saya sudah menyiapkan beberapa penghitung paling sederhana di tabel sebelumnya, dan karena itu semuanya turun untuk mendapatkan konten sel individu dan menambahkannya ke SMS:

 #    guest_confirmed = wks_attendees.acell('C70').value guest_unconfirmed = wks_attendees.acell('C71').value guest_no_response = wks_attendees.acell('C72').value guest_acceptance = wks_attendees.acell('C73').value elif "numbers" in from_body.lower():  #   ( - ,   )  resp.message("RSVP update:\n\nTotal Accepted: " + guest_confirmed         "\n\nTotal declined: " guest_unconfirmed "\n\nTotal no response: "+         guest_no_response + "\n\nTotal acceptance rate: " + guest_acceptance) 

Contoh SMS yang dikirim oleh kode ini:

gambar

Mungkin terlihat tidak terlalu indah, tetapi sangat informatif.

Fakta bahwa Lauren sekarang dapat mengikuti pembaruan otomatis dari daftar tamu menyelamatkan kami dari banyak sakit kepala. Akibatnya, saya menerima persetujuan darinya untuk integrasi SMS yang meluas, dan segera alat ini digunakan di hampir semua proses di mana dimungkinkan. Beberapa aplikasi sudah jelas, misalnya, mengirim pemberitahuan SMS tentang peluncuran situs pernikahan (dibuat, dengan cara, di Heroku ), atau bekerja dengan daftar hadiah pernikahan dan banyak solusi lain yang saya banggakan hingga hari ini.

Pesta yang mulia


Setelah menyusun daftar undangan dan mengumpulkan jawaban, ia sampai pada pelajaran, yang biasanya ditunda sampai nanti - mencari tahu preferensi selera para tamu. Langkah pertama adalah mengirim SMS lain yang memberi tahu para tamu tentang perlunya mengunjungi situs web dan memilih kategori makanan yang disajikan menggunakan formulir google. Bentuknya terlihat sangat biasa, tetapi mengisi file yang sama di mana ada data tentang pengunjung. Jadi, sekarang kami memiliki tabel pengunjung yang menerima undangan, dan meja yang mengisi formulir pemilihan makanan. Jika kita berbicara tentang alat otomasi biasa, saya harus menunggu para tamu untuk perlahan-lahan memilih hidangan mereka, namun, pernikahan saya diadakan dengan dukungan Twillio, dan ini berarti bahwa saya bisa mendapatkan respons dari para tamu dengan sedikit usaha.

Itu perlu untuk memverifikasi dua tabel dengan nama para tamu dan memperbarui status hidangan yang dipilih setelah menerima informasi baru. Ini membutuhkan beberapa lonceng dan peluit tambahan dalam kode, tetapi segera setelah saya selesai menggunakannya, saya dapat menjalankan skrip secepatnya, menerima SMS dengan informasi terbaru:

 import json import time import gspread from oauth2client.client import SignedJwtAssertionCredentials from twilio.rest import TwilioRestClient #     json,    json_key = json.load(open('')) scope = ['https://spreadsheets.google.com/feeds'] credentials = SignedJwtAssertionCredentials(json_key['client_email'],                      json_key['private_key'].encode(),                      scope) gc = gspread.authorize(credentials) wks = gc.open("")  #      wks_attendees = wks.get_worksheet(0)  #   wks_food = wks.get_worksheet(1)  #    ACCOUNT_SID = 'TWILIO_ACCOUNT_SID' AUTH_TOKEN = 'TWILIO_AUTH_TOKEN' client = TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN) #   . -       for num in range(2, 60):  food_guest_name = wks_food.acell('B'+str(num)).value  #        if food_guest_name:    attendees_name = wks_attendees.find(val_food_guest_name).value    attendees_name_row = wks_attendees.find(val_food_guest_name).row    menu_status = wks_attendees.acell("G"+str(attendees_name_row)).value    if food_guest_name == attendees_name:      print      if menu_status == 'Y':  #   ,          print('Skipping')      else:  #    ,           print ('Food sheet name ' + food_guest_name + 'Attendees sheet name ' + attendees_name)        #            wks_attendees.update_acell("G"+str(attendees_name_row), 'Y')    else:      print('nothing found, moving on')      wks_attendees.update_acell('E'+str(num), int(wks.acell('E'+str(num)).value) + 1)  #      else:    #           client.messages.create(from_="",  #  Twillio                to="",  #                  body="Finished processing current meal listnnGuest meals confirmed" + guest_meals_confirmed + "\n\nGuest meals unconfirmed: " + guest_meals_unconfirmed) 

Sekarang saya memiliki daftar tamu yang akurat dan daftar hidangan yang terus diperbarui, masuk akal untuk membuat statistik ini tersedia untuk umum menggunakan aplikasi utama. Untuk ini, hanya perlu menambahkan konten sel yang sesuai ke balasan SMS:

 #           elif "food" in body_strip.strip():  resp.message("Guest meals decided:" + guest_meals_confirmed + "\nGuest meals undecided: " + guest_meals_unconfirmed + "\n\nMenu breakdown:\n\n" + starter_option_1 +": " + starter_option_1_amount + "\n" + starter_option_2 +": " + starter_option_2_amount + "\n" + starter_option_3 +": " + starter_option_3_amount + "\n" + main_option_1 +": " + main_option_1_amount + "\n" + main_option_2 +": " + main_option_2_amount + "\n" + main_option_3 +": " + main_option_3_amount + "\n" + dessert_option_1 + ": " + dessert_option_1_amount + "\n" + dessert_option_2 + ": " + dessert_option_2_amount) 

gambar

Ukuran ini ternyata sangat berguna, karena memungkinkan perusahaan yang melayani liburan untuk menyadari kemajuan kami dan memberikan informasi yang sangat praktis dari mereka yang belum membuat pilihan. Pesaing berikutnya untuk otomatisasi adalah proses menerima tanggapan dari tamu. Untuk melakukan ini, hanya perlu membaca daftar, menemukan di dalamnya "pelanggar" yang tidak memilih piring mereka, dan mengirimi mereka pesan!

 for num in range(2, 72):  #         print "sleeping for 3 seconds"  time.sleep(3)  #            wedding_guest_number = wks_attendees.acell('B'+str(num)).value  #     wedding_guest_name = wks_attendees.acell('A'+str(num)).value  #     menu_guest = wks_attendees.acell('G'+str(num)).value  if not wedding_guest_number:    print wedding_guest_name+' telephone number empty not messaging'  #   ,     .            wks_attendees.update_acell('H'+str(num), '1')  #         else:    if menu_guest == "N":  #    !      !      print 'Sending message to '+wedding_guest_name      client.messages.create(        to="+" + wedding_guest_number,        from_="",  #   Twillio        body="If you have received this message, you have not chosen your food options for Tom & Lauren's Wedding!\n\nYou can pick your choices via the website, no paper or postage required!\n\nhttp://www.yourwebsitehere.com/food"      )      wks_attendees.update_acell('H'+str(num), int(wks_attendees.acell('H'+str(num)).value) + 1)  #        else:          # else-   print 'finished' 

gambar

Hari besar itu mendekat lebih cepat dari yang bisa kita bayangkan. Satu-satunya hal yang harus kami lakukan adalah mengirim SMS terakhir, mengingatkan tamu tentang detail dasar dan kebutuhan untuk mempersenjatai diri dengan payung, yang akan membantu melindungi diri mereka dari musim panas Inggris yang biasanya hujan:

gambar

Kesimpulannya


Mengorganisir pernikahan tidak pernah mudah. Kapan saja, mungkin bagi Anda tampak bahwa banyak aspek acara berada di luar kendali Anda. Otomatisasi jelas membuat hidup saya lebih mudah dengan menyediakan saluran komunikasi langsung dengan para tamu dan alat yang tak terhitung jumlahnya untuk mengikuti jawaban mereka dan mengingatkan mereka tentang kebutuhan untuk memutuskan dan menjawab. Dia membantu kami mengambil salah satu hal paling membosankan yang menyertai acara seperti itu ke tangan kami sendiri, dan memungkinkan kami untuk meluangkan banyak waktu dan fokus pada komponen penting lainnya dari peristiwa penting dalam hidup kami.

Membuat solusi yang skalabel untuk tugas-tugas kompleks tidak pernah mudah, dan bahkan salah satu versi terakhir dari aplikasi saya hampir tidak dapat mengatasi tugas-tugas di tempat. Awalnya, saya berencana untuk mengembangkan solusi yang lebih komprehensif, dengan visualisasi kemajuan, integrasi suara, kurang tergantung pada skrip CLI, tetapi waktu menang dalam lomba ini. Secara umum, saya senang dengan bagaimana semuanya berubah. Tidak ada sistem komunikasi yang sempurna. Anda harus selalu menggunakan saluran yang paling cocok untuk audiens Anda, baik itu SMS , Voice , Chat , Video atau semaphore .

Jika Anda ingin berbicara tentang otomatisasi pernikahan, kirim email ke saya di Twitter .

gambar

Source: https://habr.com/ru/post/id402827/


All Articles