Das Schreiben eines Telegramm-Clients ist einfach


    Was ist der Unterschied zwischen Telegramm und anderen beliebten Boten? Er ist offen!
    Andere Messenger haben ebenfalls eine API, aber ist das Telegramm aus irgendeinem Grund als das offenste der beliebtesten bekannt?


    Zunächst hat Telegram einen wirklich vollständig offenen Client-
    Code . Leider sehen wir nicht jeden Tag Commits direkt auf GitHub, aber wir haben einen Code unter einer offenen Lizenz. Die Telegrammarchitektur impliziert, dass sowohl Bot als auch API fast dieselben Methoden haben - https://core.telegram.org/methods .


    Tatsächlich ist Telegram nicht nur ein Chat-Messenger, sondern eine soziale Plattform, auf die für verschiedene Arten von Anwendungen zugegriffen werden kann. Sie können Benutzern zusätzliche Chips bereitstellen, anstatt ein vorgefertigtes Netzwerk von Benutzern und Servern für die Nachrichtenübermittlung zu verwenden. Es klingt so attraktiv, dass wir versuchen wollten, unseren „Client“ für Telegramme zu schreiben.


    Das Wesentliche der Anwendung


    Wir beschäftigen uns hauptsächlich mit Karten und Navigation, daher haben wir uns sofort mit Geolokalisierung befasst. Es hat mir sehr gut gefallen, dass es in Telegram vor allen anderen Anwendungen eine bequeme Möglichkeit gab, Ihren Standort in Echtzeit zu teilen ( https://telegram.org/blog/live-locations ), und ich verwende ihn häufig: Helfen Sie mir, mich zu orientieren, zeigen Sie meinen Weg und Das Wichtigste ist, die Hauptfrage "Wann wirst du sein?" zu beantworten. Im Prinzip reicht dies für die meisten Menschen aus, aber wie immer gibt es Szenarien, in denen einfache Möglichkeiten nicht ausreichen. Beispielsweise kann es sich um eine Gruppe von mehr als 10 Personen mit unterschiedlichen Geräten (einige Geräte sind möglicherweise keine Telefone) und unterschiedlichen Personen handeln. Für diese Personen wäre es praktisch, Nachrichten in einer Gruppe auszutauschen und sich gegenseitig auf einer Karte zu sehen.


    Wir haben uns auf die Aufgabe konzentriert, zusätzlichen Wert für Telegramm zu schaffen und nicht zu versuchen, ihn für andere Zwecke zu verwenden. Wir wollten nicht, dass Leute, die keinen speziellen Telegramm-Client hatten, im Chat ein Durcheinander von Nachrichten oder etwas Unverständliches sehen. Menschen mit einem "verbesserten" Kunden haben zusätzliche Möglichkeiten, zum Beispiel:


    1. Feinere Zeitverwaltung beim Senden von Standorten in Echtzeit zum Chatten.
    2. Zeigen Sie den Standort der Kontakte auf der Karte an.
    3. Herstellen einer Verbindung zum Chat von Beacon-Geräten über eine externe API (Bot).

    Wie haben wir das gemacht?


    Glücklicherweise ist der gesamte Code, den wir schreiben, Open Source, sodass ich sofort einen Link zu seiner Implementierung geben kann - Bot- Implementierung und Telegramm-Client-Implementierung auf Kotlin .


    Bot - die Grundlagen

    Es gibt viele Dokumentationen und Beispiele zur Implementierung von Bot, aber ich möchte trotzdem noch einmal auf einige der Fallstricke eingehen. Zunächst haben wir die Serverseite
    in Java geschrieben und die Bibliothek org.telegram ausgewählt: telegrambots. Da es sich bei unserem Server um einen regulären SpringBoot handelt, ist die Initialisierung äußerst einfach:


       // Gradle implementation "org.telegram:telegrambots:3.6"
       TelegramBotsApi telegramBotsApi = new TelegramBotsApi();
       telegramBotsApi.registerBot(new TelegramLongPollingBot() {...});

    Das Hauptmerkmal der Standortübertragung ist, dass sie regelmäßig aktualisiert werden muss und der Bot bereits gesendete Nachrichten bearbeiten muss. Wenn es keine solche Gelegenheit gäbe, würde Bot den Chat nur als Spam versenden und natürlich wäre es Epic Fail. Gott sei Dank Telegramm gibt dem Bot das Recht, Nachrichten für 24 Stunden zu bearbeiten (Minimum, möglicherweise länger).


    Es gibt viele Möglichkeiten, eine Nachricht zu senden. Es gibt den Typ Nur Text, Veranstaltungsort, Ort, Spiel, Kontakt, Rechnung usw. Es schien, dass die Lage perfekt für unsere Aufgabe war, aber ein unangenehmes Merkmal wurde aufgedeckt. Der Standort kann jeweils nur von einem Gerät auf ein Konto oder einen Bot übertragen werden! Stellen Sie sich vor, Sie haben zwei Telefone und von zwei Telefonen aus haben Sie Ihren Standort in einem Chat gesendet. Auf dem Server tritt also ein Fehler auf und die erste Standortfreigabe wird einfach gestoppt. Es scheint, dass dies eindeutig ein neuronaler Fall ist, aber stellen Sie sich vor, Sie haben viele chinesische Beacons, die den Standort an eine bestimmte URL senden können, aber nicht direkt an Telegram. Sie schreiben Bot, der vom Server abholt und Telegramme sendet. Hier stellt sich heraus, dass Bot nicht mehr als eine Beacon-Nachricht mit dem Standorttyp senden kann. Es stellt sich heraus


    Die Lösung ist einfach: Senden Sie Textnachrichten, und der Client analysiert den Text und zeigt die Positionen auf der Karte an. Leider werden im Standard-Telegramm-Client nur Textnachrichten angezeigt, aber Sie können dort einen Link einfügen, um die Karte zu öffnen.


    Bot - Fallstricke

    Leider musste Bot bis zu 2,5 Mal umschreiben. Das Hauptproblem ist das falsche Design der Kommunikation.


    1. Aus irgendeinem Grund schien es zunächst eine gute Idee zu sein, ob der Bot ein vollwertiger Teilnehmer am Chat sein und Nachrichten senden würde. Dies ist jedoch sowohl in Bezug auf die Privatsphäre der Korrespondenz als auch in Bezug auf die Interaktion mit dem Bot schlecht. Verwenden Sie Inline-Bots , um die richtige Entscheidung zu treffen . Somit ist garantiert, dass der Bot nichts anderes als seinen Standort sieht und in jedem Chat verwendet werden kann. Menschlich gesehen ist es unkulturell, Ihren Bot in eine Art allgemeinen Chat zu ziehen, aber Sie müssen eins zu eins mit dem Bot sprechen und ihn konfigurieren, damit er die erforderlichen Nachrichten an jeden ausgewählten Chat senden kann.
    2. In der Telegrammnachrichten-API gibt es in der Vergangenheit zwei Arten von Interaktionen: Schaltflächen unter dem Text ((Inline-Schaltflächen) [ https://core.telegram.org/bots/2-0-intro#switch-to-inline-buttons ]) und direkte Antworten auf den Bot Text. Im Allgemeinen sind die Antworten mit dem Bot hoffnungslos veraltet. Schaltflächen sind aus Sicht der Implementierung etwas komplizierter, dies wird jedoch durch die Benutzerfreundlichkeit vollständig bezahlt und sollten für alle Nicht-Texteingaben verwendet werden.
    3. Als Beispiel für einen Bot sehen Sie den beliebten @vote_bot oder unseren @osmand_bot.

    Telegramm-Client

    Wir konnten keine Beispiele für einen vorgefertigten Telegramm-Client finden, außer für den Haupt-Client, aber die recht einfache tdlib-Struktur half uns, in nur wenigen Tagen einen Basis-Client zu erstellen.


    Gradle-Setup:
    task downloadTdLibzip {
        doLast {
            ant.get(src: 'https://core.telegram.org/tdlib/tdlib.zip', dest: 'tdlib.zip', skipexisting: 'true')
            ant.unzip(src: 'tdlib.zip', dest: 'tdlib/')
        }
    }
    task copyNativeLibs(type: Copy) {
        dependsOn downloadTdLibzip
        from "tdlib/libtd/src/main/libs"
        into "libs"
    }
    task copyJavaSources(type: Copy) {
        dependsOn downloadTdLibzip
        from "tdlib/libtd/src/main/java/org/drinkless/td"
        into "src/org/drinkless/td"
    }
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
    }

    Fast alle Interna des Telegramms sind in C ++ geschrieben und aus Sicht von Android ist auf den 1,5-MB-Proxy-Methoden TdApi.java nur die API-Klasse sichtbar . Durch Vergleichen der Dokumentation der Bots und des Namens der Methoden können Sie einfach herausfinden, wohin Sie sich bewegen müssen.


    Kundeninitialisierung mit globalem Handler:
    fun init(): Boolean {
        return if (libraryLoaded) {
            // create client
            client = Client.create(UpdatesHandler(), null, null)
            true
        } else {
            false
        }
    }

    Benutzerfotoanfrage:
    private fun requestUserPhoto(user: TdApi.User) {
        val remotePhoto = user.profilePhoto?.small?.remote
        if (remotePhoto != null && remotePhoto.id.isNotEmpty()) {
            downloadUserFilesMap[remotePhoto.id] = user
            client!!.send(TdApi.GetRemoteFile(remotePhoto.id, null)) { obj ->
                when (obj.constructor) {
                    TdApi.Error.CONSTRUCTOR -> {
                        val error = obj as TdApi.Error
                        val code = error.code
                        if (code != IGNORED_ERROR_CODE) {
                            listener?.onTelegramError(code, error.message)
                        }
                    }
                    TdApi.File.CONSTRUCTOR -> {
                        val file = obj as TdApi.File
                        client!!.send(TdApi.DownloadFile(file.id, 10), defaultHandler)
                    }
                    else -> listener?.onTelegramError(-1, "Receive wrong response from TDLib: $obj")
                }
            }
        }
    }

    Telegramm-Client - Fallstricke

    1. Registrierung / Login und Logout. Bei der Registrierung müssen verschiedene Szenarien berücksichtigt werden: Wenn der Zugangscode per SMS oder an einen anderen Telegramm-Client gesendet wird, Zwei-Faktor-Autorisierung usw. Die größte Herausforderung ist das Testen. Jede Autorisierung, die mehr als dreimal durchgeführt wurde, führte zu einer Sperrung des Kontos für 24 Stunden, sodass das Testen der Abmeldung besonders viel Spaß machte. Trotz der Tatsache, dass eine Registrierung nur einmal erforderlich ist, ist dies wahrscheinlich der schwierigste Teil der Integration.
    2. Bestimmen Sie, wie und in welcher Reihenfolge Nachrichten gelesen werden sollen. Jeder Client hat Zugriff auf alle Nachrichten in allen Chats, diese müssen jedoch nacheinander ausgelesen werden. In unserem Fall müssen 99% der Nachrichten verworfen werden. Zuerst haben wir aus irgendeinem Grund alle Nachrichten der letzten 3 Tage mit einem Login gelesen, aber später verursachte es nur Probleme und als wir neu starteten, verschwanden die Nachrichten. Daher lesen wir jetzt nur neue Nachrichten und speichern für die Nachrichten, die wir benötigen, die ID in der internen Datenbank.

    Was ist passiert?


    Wenn man alle Fallstricke kennt, kann man wahrscheinlich alles um ein Vielfaches schneller machen, aber für drei Personen stellte sich heraus, dass es ungefähr 1-2 Monate waren. Die endgültige App finden Sie bei Google Play .



    Die Hauptfrage in dieser Geschichte ist, wie korrekt diese Interaktion aus Sicht des Telegramms ist und ob Benutzer diese Art der Integration mögen. In jedem Fall ist die Idee selbst eine Nische und hat bereits einzelne Kunden gefunden.


    Gerne beantworte ich Ihre Fragen.


    Jetzt auch beliebt: