Πώς να δημιουργήσετε ένα REAL σύστημα συνομιλίας για την εκκίνηση σας

Κάθε δεύτερη μέρα βλέπω μια ανάρτηση ιστολογίου για το πώς να δημιουργήσετε ένα σύστημα συνομιλίας χρησιμοποιώντας το WebSockets ή πώς να χρησιμοποιήσετε τη μαγεία της Firebase για να δημιουργήσετε ένα μαγευτικό, αν και ας είμαστε ειλικρινείς: Η οικοδόμηση ενός REAL προσαρμόσιμου συστήματος συνομιλίας είναι μια εντελώς διαφορετική ιστορία.

Τώρα, ας εξετάσουμε μια περίπλοκη περίπτωση χρήσης:
έχουμε ένα προϊόν που αποτελείται από δύο μέρη: 1) κινητή εφαρμογή που οι τελικοί χρήστες μας εγκαθιστούν και 2) ένα ταμπλό διαδικτύου. Ο πίνακας ελέγχου χρησιμοποιείται από τους διαχειριστές για να στοχεύσει μια συγκεκριμένη ομάδα κοινού και να τους στείλει μηνύματα. Το επιλεγμένο κοινό θα λάβει τα μηνύματα στις εφαρμογές τους για κινητά.

Θεωρήστε ότι πρέπει να δώσουμε λύσεις για τις ακόλουθες περιπτώσεις χρήσης:

  • 1-1 συνομιλία μεταξύ δύο χρηστών
  • Ομαδικές συζητήσεις μεταξύ των χρηστών
  • Στέλνουμε μαζικά μηνύματα (αναφερόμαστε σε αυτά ως "καμπάνιες") από τον πίνακα ελέγχου στους χρήστες
  • Αποστολή ξεχωριστών μηνυμάτων σε συγκεκριμένο χρήστη από τον πίνακα ελέγχου

τα μηνύματα καμπάνιας χωρίζονται σε ακόλουθες κατηγορίες:

  • Ο διαχειριστής του πίνακα ελέγχου πρέπει να δημιουργήσει μια ομαδική συζήτηση και να προσθέσει μια ομάδα κοινού.
  • Ο διαχειριστής του πίνακα εργαλείων δημιουργεί μεμονωμένα κανάλια μεταξύ του πίνακα ελέγχου και του κάθε χρήστη και αφήνει ένα μήνυμα σε αυτό το κανάλι. Οι χρήστες ως μέλη, θα λάβουν τα μηνύματα στις εφαρμογές τους για κινητά.
  • Ο διαχειριστής του πίνακα ελέγχου στέλνει ένα μήνυμα προς τους χρήστες. Ο χρήστης θα λάβει το μήνυμα είτε με SMS είτε με μορφή συνομιλίας.

Τώρα το ερώτημα είναι πώς να το εφαρμόσουμε αυτό;

Λύσεις

Μια λύση είναι να επανεφεύρουμε τον τροχό. Όλοι έχουμε ακούσει για το Firebase και το μεγαλείο του. Μπορούμε να χρησιμοποιήσουμε τη βάση δεδομένων πραγματικού χρόνου της Firebase για να δημιουργήσουμε τη δική μας υποδομή συνομιλίας.

Ας δούμε πώς φαίνεται η εφαρμογή:

Στο τέλος θα καταλήξετε με το ακόλουθο δέντρο Firebase:

  • campaignMessageQueue
  • campaignQueue
  • campaignStatus
  • chatMessages
  • chatReadReceipts
  • συζητήσεις
  • chatTypingIndicators
  • ειδοποιήσεις ηλεκτρονικού ταχυδρομείου
  • messageQueue
  • userChats
  • userPushTokens
  • nonChatSMSQueue
  • campaignMessageQueue

Τρομακτικός! Δεν είναι;
Λειτουργεί? Ναί.
Η κλίμακα; Περίπου.
Είναι εύκολο να αντιμετωπιστεί; Ούτε καν!
Για να υποστηρίξετε αυτό το θηρίο, πρέπει να αφιερώσετε πολύ χρόνο και ενέργεια.
Αυτή η λύση επανεμφανίζει κάθε πτυχή ενός συστήματος συνομιλίας, όπως: Αναγνώριση αποδείξεων, Δείκτες πληκτρολόγησης, ειδοποιήσεις και κατάσταση κατάστασης για συνομιλίες.
Πρέπει να έχετε εγκαταστήσει διαφορετικούς εργάτες κόμβων οι οποίοι διαβάζουν από διαφορετικές ουρές στο Firebase Tree.

Ακολουθεί μια περιγραφή για κάθε εργαζόμενο:

campaignWorker

Ο εργαζόμενος λειτουργεί στο campaignQueue.
Ο εργαζόμενος λαμβάνει θέσεις εργασίας από το περιβάλλον χρήστη του πίνακα ιστού, ανακτά τη λίστα διανομής, δημιουργεί νέες συνομιλίες με χρήστες και στη συνέχεια τοποθετεί το μήνυμα καμπάνιας σε αυτά. Έχει επίσης την ευθύνη δημιουργίας θέσεων εργασίας στο campaignMessageQueue.

messageWorker

Ο εργαζόμενος λειτουργεί στο messageQueue.
Διαχειρίζεται όλες τις εργασίες ειδοποίησης για κανονικά μηνύματα / μηνύματα εκτός καμπάνιας.

campaignMessageWorker

Ο εργαζόμενος λειτουργεί στο campaignMessageQueue. Η λειτουργικότητα είναι ακριβώς όπως το messageWorker, λειτουργεί μόνο σε διαφορετική ουρά.

nonChatSMSWorker

Ο εργαζόμενος λειτουργεί με nonChatSMSQueue.
Διαχειρίζεται την αποστολή μηνυμάτων μόνο SMS που δεν δημιουργούν ένα μήνυμα μέσα σε μια πραγματική συνομιλία.

campaignMessageWorker

Ο εργαζόμενος λειτουργεί στο campaignMessageQueue.
Διαχειρίζεται την αποστολή μαζικών μηνυμάτων εκτός καμπάνιας για έναν πίνακα ελέγχου.

Ακούγεται σαν πολλή δουλειά, όχι; Εφαρμογή και διατήρηση αυτού του κώδικα δεν είναι το μόνο πρόβλημα, μερικές φορές οι εργάτες των κόμβων φράσσονται και άλλες φορές συντρίβονται και πρέπει να ξαναρχίσουν.
Το κόστος συντήρησης είναι τόσο υψηλό που σύντομα θα ψάξετε μια εναλλακτική λύση. Ο στόχος στόχος σας θα είναι να εξαλείψετε την εξάρτηση από τη Firebase ως βάση δεδομένων συζήτησης, το ερώτημα είναι πώς είναι δυνατόν;

Τότε έρχεται να παίζει το Twilio. Είναι κυρίως γνωστά για το SMS API τους, αλλά παρέχουν και ένα API συνομιλίας.

Το προγραμματιζόμενο API του Twilio

Η προγραμματιζόμενη συνομιλία είναι ένα προϊόν συνομιλίας που βασίζεται σε σύννεφο το οποίο παρέχει έναν αριθμό SDK πελατών και ένα API REST για χρήση στην ενσωμάτωση των δυνατοτήτων συνομιλίας σε εφαρμογές και ιστότοπους. Προτυποποιείται μετά από το πρωτόκολλο Extensible Messaging and Presence Protocol (XMPP) και περιστρέφεται γύρω από την έννοια των παρουσιών υπηρεσίας. Οι υπηρεσίες συνομιλίας είναι εκεί όπου ζουν όλα τα κανάλια, τα μηνύματα, οι χρήστες και άλλοι πόροι στο πλαίσιο της ανάπτυξης συνομιλίας.

  • Κάθε παράμετρος υπηρεσίας μπορεί να έχει πολλά κανάλια.
  • Κάθε κανάλι μπορεί να έχει πολλά μέλη.
  • Κάθε κανάλι μπορεί να έχει πολλά μηνύματα.

Οι περιπτώσεις εξυπηρέτησης είναι απομονωμένα σιλό και δεν υπάρχει τρόπος να επικοινωνούν μεταξύ τους δύο διαφορετικές περιπτώσεις υπηρεσιών. Για να στείλετε ένα μήνυμα μεταξύ δύο οντοτήτων. Πρώτον, πρέπει να υπάρχει ένα υπάρχον κανάλι μεταξύ τους. Στη συνέχεια, οι οντότητες πρέπει να προστεθούν ως μέλη στο κανάλι. Κάθε μήνυμα που έχει πέσει στο κανάλι θα δημοσιευθεί στα μέλη. Χρησιμοποιώντας τα SDK πελάτη (διαθέσιμα για ιστό, iOS και Android), μπορούμε να ανακτήσουμε τη λίστα των καναλιών εγγραφής στα οποία ένας χρήστης είναι μέλος (ή έχει προσκληθεί) μόλις αυτός συνδεθεί στον πελάτη.
Αυτό το μοντέλο είναι εξαιρετικά ευέλικτο.

Ας επιστρέψουμε στο αρχικό πρόβλημα που λύσαμε προηγουμένως μέσω της Firebase. Θα προσπαθήσουμε να το εφαρμόσουμε στο Twilio:

Αρχικά, δημιουργούμε μια προεπιλεγμένη υπηρεσία. Αυτή η υπηρεσία υπηρεσίας χρησιμοποιείται από τον πίνακα ελέγχου για την αποστολή μηνυμάτων στους χρήστες των κινητών συσκευών. Επίσης, οι χρήστες μας θα μπορούν να στέλνουν ιδιωτικά μηνύματα στον διαχειριστή του πίνακα ελέγχου. Όλα αυτά τα κανάλια παραμένουν σε αυτήν την υπηρεσία.

Χρησιμοποιώντας το προγραμματιζόμενο API Chat, μπορούμε να εξαλείψουμε εντελώς την εξάρτηση από το Firebase. Θα προχωρήσουμε στην κατάργηση των προαναφερθέντων εργαζομένων στον κόμβο και θα απλοποιήσουμε τη δομή του έργου μας.

Τώρα ας μιλήσουμε για το API του Chat REST του Twilio. Μπορούμε να το χρησιμοποιήσουμε για να εφαρμόσουμε όλες τις περιπτώσεις χρήσης που συζητήσαμε νωρίτερα. Το API χρησιμοποιείται από το backend μας και προορίζεται για χρήση του συστήματος. Το API μπορεί να χρησιμοποιηθεί για την ενορχήστρωση της χρήσης προγραμματιζόμενης συνομιλίας, μπορείτε να προσθέσετε μέλη, να στείλετε αυθαίρετα μηνύματα, να αλλάξετε το ρόλο των χρηστών κλπ. Βασικά, είναι θεϊκό για το σύστημά μας συνομιλίας.

Ακολουθεί μια σύντομη λεπτομέρεια για τον τρόπο εφαρμογής κάθε σεναρίου:

  • Συζήτηση χρηστών σε χρήστη (κινητό): Κάθε φορά που ένας χρήστης χρειάζεται να ξεκινήσει συνομιλία με άλλο χρήστη, ο πελάτης κινητής τηλεφωνίας στέλνει ένα αίτημα στο παρεχόμενο τελικό σημείο στο backend. Το backend θα προσπαθήσει να βρει ένα κανάλι με το μοναδικό όνομα του χρήστη [user1.uuid, user2.uuid] .sort.join (':') στην προεπιλεγμένη υπηρεσία. Αν δεν βρεθεί κανάλι με αυτό το μοναδικό, ο πελάτης REST θα δημιουργήσει ένα νέο κανάλι με αυτό το όνομα και θα προσθέσει και τους δύο χρήστες ως μέλη. Το τελικό σημείο θα επιστρέψει το κατάλληλο αναγνωριστικό καναλιού στον πελάτη κινητής τηλεφωνίας στο ωφέλιμο φορτίο επιστροφής. Από εκεί, ο κινητός πελάτης μπορεί να στείλει μηνύματα σε αυτό το κανάλι. Χρησιμοποιώντας το REST API του Twilio, διασφαλίζουμε ότι δεν δημιουργούμε διπλά κανάλια μεταξύ δύο χρηστών και διατηρούμε το ιστορικό των συνομιλιών. Την επόμενη φορά, ένας χρήστης θέλει να στείλει ένα μήνυμα σε έναν συνάδελφο χρήστη, θα χρησιμοποιηθεί το ίδιο κανάλι.
def create_1_to_1_chat (u1, u2)
 unique_name = [u1.uuid, u2.uuid] .sort.join (':')
 όνομα = User.where (uuid: [u1.uuid, u2.uuid] .sort) .map (&: όνομα) .join ('-')
 c = add_channel (unique_name, όνομα, κανάλι_τύπου:: δημόσια)
 c = update_attribute (c, 'θέμα', όνομα)
 add_member (c, u1)
 add_member (c, u2)
 c.sid
τέλος

2. Χρήστη στην συνομιλία του πίνακα ελέγχου (κινητό): Η διαδικασία είναι πολύ παρόμοια με την προηγούμενη περίπτωση χρήσης. Η μεγαλύτερη διαφορά είναι ότι το backend θα προσπαθήσει να βρει ή να αρχικοποιήσει το κανάλι στην υπηρεσία υπηρεσίας του πίνακα ελέγχου (και όχι στην προεπιλεγμένη υπηρεσία):

def create_user_to_dashboard_chat (u)
 c = add_channel (u.uuid, "# {@ dashboard.name"> @ dashboard.name "> @ dashboard.name"> u.name} - # {@ dashboard.name} # {u.uuid} ")
 c = update_attribute (c, 'θέμα', @ dashboard.name)
 c = update_attribute (c, 'dashboard_uuid', @ dashboard.uuid)
 add_member (c, u)
 add_member (c, @dashboard, role_sid:: channel_admin)
 res = TwilioChannel.load_channel (@dashboard, c)
 res
τέλος

3. πίνακας ελέγχου για συνομιλία χρηστών (ιστός): Μερικές φορές θα θέλαμε να στείλουμε ένα μήνυμα σε έναν μεμονωμένο χρήστη. Η λογική που χρησιμοποιείται εδώ είναι ακριβώς η ίδια που χρησιμοποιήσαμε για τη συζήτηση "user-to-dashboard".

4. Πίνακες ελέγχου χρήστη (καμπάνιες): Όπως αναφέρθηκε προηγουμένως, χρειαζόμασταν να υποστηρίξουμε δύο διαφορετικούς τύπους επικοινωνίας από το ταμπλό σε χρήστες.
Πρώτη περίπτωση χρήσης είναι όταν ο πίνακας ελέγχου πρέπει να δημιουργήσει μια ομαδική συζήτηση με κάποιους χρήστες σε αυτό. Το αίτημα θα σταλεί από τον πίνακα ελέγχου στο backend μαζί με τη λίστα των παραμέτρων αναζήτησης που πρέπει να χρησιμοποιηθεί για τον ορισμό του κοινού. Το Backend θα λάβει το αίτημα και δημιουργεί ασύγχρονα ένα νέο κανάλι και προσθέτει το επιλεγμένο κοινό ως μέλη στο κανάλι.
Η δεύτερη περίπτωση χρήσης είναι όταν ο ταμπλός πρέπει να ανοίξει μεμονωμένα κανάλια μεταξύ του ίδιου και των χρηστών κινητής τηλεφωνίας. Κανονικά ένας διαχειριστής χρησιμοποιεί αυτόν τον τύπο επικοινωνίας για να απαιτήσει μια απάντηση από το κοινό. Το αίτημα θα αποσταλεί από τον πίνακα ελέγχου στο backend μαζί με τη λίστα παραμέτρων αναζήτησης που πρέπει να χρησιμοποιηθεί για τον προσδιορισμό της ταυτότητας του κοινού. Το Backend λαμβάνει το αίτημα και δημιουργεί ένα διαφορετικό κανάλι για κάθε χρήστη και προσθέτει αυτόν το χρήστη ως μέλος. Χρησιμοποιούμε το Sidekiq για αποτελεσματική επεξεργασία φόντου.

Εκδηλώσεις Webhooks

Οι προγραμματιζόμενες επαναλήψεις συμβάντων συνομιλίας σας επιτρέπουν να παρακολουθείτε και να παρακολουθείτε συγκεκριμένα συμβάντα στην υπηρεσία backend. Οι δύο κατηγορίες συμβάντων είναι "Προ-Συμβάν" (σύγχρονη) και "Μετα-Συμβάν" (ασύγχρονη). Όταν έχει οριστεί μια επανάκληση, το Twilio θα κάνει ένα αίτημα HTTP στην καθορισμένη διεύθυνση URL του webhook. Αυτή η αίτηση περιέχει όλα τα σχετικά δεδομένα μεταβλητών.
Χρησιμοποιήσαμε επανακλήσεις μετά την εκδήλωση για σκοπούς αναλύσεων και επίσης να προσθέσουμε ξανά διαφορετικούς πίνακες ελέγχου ως μέλη στα κανάλια. Σύμφωνα με τα έγγραφα, οι "webhost" μετά την "Εκδήλωση" είναι "ειδοποιούνται μόνο" και παρέχουν πληροφορίες μετά την ολοκλήρωση της ενέργειας. Σε αντίθεση με αυτά που προηγούνται του γεγονότος, αυτά δεν εμποδίζουν τις επανάκλησεις καθώς είναι ενημερωτικά.
Βασίσαμε ειδικά στους χειριστές συμβάντων onMessageSent και onChannelAdded.

Περιορισμοί

Το προγραμματιζόμενο API Chat είναι ακόμα νέος και είναι σε εξέλιξη. Ενώ εργαζόμαστε για τη δημιουργία της ολοκαίνουργιας μας συνομιλίας, αντιμετωπίσαμε τους ακόλουθους περιορισμούς:

  • Στην περίπτωση καμπανιών (μαζικά μηνύματα που ξεκινούν από τον πίνακα ελέγχου), δεν προσθέτουμε αρχικά τους διαχειριστές του πίνακα ελέγχου ως μέλος στο κανάλι. Ένας περιορισμός του τρέχοντος API Twilio Chat είναι ότι, μια οντότητα θα μπορούσε να είναι μέλος έως και 1000 καναλιών. Σύμφωνα με το Twilio, αυτό είναι ένα μαλακό όριο που τους επιτρέπει να βελτιώνουν την κλίμακα τους, αλλά από την άλλη, είναι κάπως περιοριστικό. Επομένως, προσθέτουμε μόνο το ταμπλό ως μέλος αν υπάρχει εισερχόμενο μήνυμα από τους χρήστες των κινητών. Αυτός ο περιορισμός σημαίνει επίσης ότι πρέπει να καταργήσουμε το ταμπλό από το κανάλι, όταν ο διαχειριστής ολοκληρώσει την επεξεργασία του (η ιδέα ανοιχτών / κλειστών καναλιών που αναφέρθηκε προηγουμένως).
  • Προς το παρόν, μπορούμε να ορίσουμε προσαρμοσμένα χαρακτηριστικά σε κανάλια και μηνύματα. αν και δεν υπάρχει κανένας τρόπος να ερωτηθούν μέσω αυτών. Αυτό είναι υπερβολικά περιοριστικό και κατά τη γνώμη μου είναι το πιο σημαντικό έλλειμμα.
  • Κάθε κανάλι μπορεί να έχει μέχρι 1000 μέλη σε αυτό. Για να είμαι δίκαιος, νομίζω ότι οποιαδήποτε ομαδική συζήτηση με περισσότερα από 20 μέλη είναι μια θέση γεμάτη χάος, επομένως δεν θεωρώ ότι αυτό αποτελεί πραγματικό περιορισμό.

συμπέρασμα

Συνολικά, νομίζω ότι το Twilio παρέχει στους χρήστες μια πολύ ομαλότερη εμπειρία στην οικοδόμηση ενός συστήματος συνομιλίας σε σύγκριση με το Firebase.
Μακροπρόθεσμα, ένα σύστημα συνομιλίας που υποστηρίζεται από ένα πρωτόκολλο Pub-Sub θα είναι ο πραγματικός νικητής όσον αφορά την επεκτασιμότητα και τη συντήρηση.
Ας γνωρίζουμε απλώς ότι υπάρχουν διαφορετικές λύσεις για την κατασκευή ενός συστήματος συνομιλίας. Όταν πρέπει να αποφασίσετε ποια λύση λειτουργεί καλύτερα για εσάς, προσπαθήστε να δημιουργήσετε μια λίστα πλεονεκτημάτων και μειονεκτημάτων. Η επανεμφάνιση του τροχού δεν είναι πάντα κακή ιδέα, αλλά πρέπει επίσης να εξετάσετε τους διαθέσιμους πόρους. Όντας μια εκκίνηση, είναι ζωτικής σημασίας να κινηθείτε γρήγορα. Τώρα θα μπορούσατε να κινηθείτε γρήγορα χωρίς να θυσιάζετε την ποιότητα χρησιμοποιώντας ακριβώς το σωστό εργαλείο.

Πόροι:
https://www.twilio.com/docs/api/chat/
https://firebase.google.com/