Name: Telegram
Homepage: https://telegram.org
Short description: Messaging platform.
Optional API documentation URL: https://core.telegram.org/api#telegram-api

Users should post in a public group chat, then note the message link.

Those wishing to audit can add bots to the group without approval from the admins.

Messages cannot be fetched through the bot API, but it can be fetched through the MTProto (client) API with bot credentials. MTProto however is encrypted and is not plain HTTP so it may be better to rely on external libraries.

a month later

Thanks for doing the research!

Working with a public group is not ideal but it works with matrix and like matrix, there's no other way.

Good to know third parties can add bots without approval.

I should look into the MTProto API, not sure how complicated the encryption is. Do you know of NodeJS clients for this?

9 days later

Good find on the NodeJS client. Great, this should be feasible.

Profile bio sounds handier but like you say, demanding some portion of 70 characters is not great. I think we should have both for the people that don't just want to send a message in a big group.

One of these days, let's do a little proof-of-concept šŸ˜‰

a month later

I propose the following scheme:

User creates a verification public channel (for example, https://t.me/hoCheiya5tie8aevei5da4xa4aequ4lo, URL doesnā€™t really matter) with ā€œSign messagesā€ option enabled. Bot then can be added as administrator with no rights and fetch the list of channel administrators via HTTP getChatAdministrators. User with status ā€œcreatorā€ is allowed to verify the account. Verification message itself could be placed in pinned message, which is retrievable with getChat HTTP method. That way no MTPROTO is involved and verification message is visible to everyone (and can be verified by forwarding pinned message to ShowJsonBot, which would show the username).

I could probably contribute a implementation, if such a PR would be accepted.

    Ah, so one channel per user! Add the bot and voila. That's smart and avoids the big central room! Public for everyone and the bot can just use the HTTP API. I like it!

    Ok, so I registered a bot and created a public channel. I'll try the API call later today!

    We should also try this approach with Matrix one day.

    Goldstein if such a PR would be accepted

    All PRs are welcome šŸ™‚

    I think Iā€™ve made a mistake and identity actually canā€™t be verified by forwarding, so you need to trust a bot. Meh.
    Public group admins are visible to everyone though, and thereā€™s an option to disable posting in the group, so it becames a de-facto channel. It looks like this:
    https://t.me/thequei8zeepae0xi7to4chui2Hohcha
    and is also fetchable by bot with the same methods.
    It doesnā€™t even require providing admin rights to the bot.

      Thereā€™s an another interesting question: what should be verified? Telegram username is user-readable, but also easy to change. Telegram id is immutable, but is kinda useless.

        Adding a bot obviously hurts decentralization. Public groups/channels in principle could be fetched without it, but thatā€™s much more difficult.

        Oh. I actually experimented a bit and thereā€™s no need to add a bot! Any bot, even not present in the channel, can make these queries. Then itā€™s just an extremely simple HTTP API with two methods.

          A lot of information here. I'll need to do some testing on my end. We also really need to make sure there are no obvious side channels through which this could be abused.

          Glancing at the PR, we'll have a few things to improve. I think tg:user=complex_user_1234&chat=complex_chat_1234 as a claim is a good start but it's a big departure from all other identity claims, which are (when possible) valid URLs that people can visit.

          How about we use https://t.me/hoCheiya5tie8aevei5da4xa4aequ4lo?user=complex_user_1234?

          Also, I do think we can use the telegram ID and make sure the Keyoxide client simply shows the associated username? That way, the claim can stay identical but the interface will show the current username.

          Thereā€˜s no simple way to get username from ID, as far as I know.

          We can validate both, but thatā€™s about just as brittle as validating just username and also requires providing some One True Way of discovering own ID.

          So what does the API return when you fetch a message? The ID or the username?

          Both. Example outputs:

          {
            "ok": true,
            "result": {
              "id": -1001668437313,
              "title": "thequei8zeepae0xi7to4chui2Hohcha",
              "username": "thequei8zeepae0xi7to4chui2Hohcha",
              "type": "supergroup",
              "description": "0baf2d87cb43746f62372d78de6031aba0bb269a",
              "permissions": {
                "can_send_messages": false,
                "can_send_media_messages": false,
                "can_send_polls": false,
                "can_send_other_messages": false,
                "can_add_web_page_previews": false,
                "can_change_info": false,
                "can_invite_users": false,
                "can_pin_messages": false
              },
              "join_to_send_messages": true,
              "pinned_message": {
                "message_id": 3,
                "from": {
                  "id": 1136612192,
                  "is_bot": false,
                  "first_name": "Max",
                  "username": "goldsteinq",
                  "language_code": "en"
                },
                "chat": {
                  "id": -1001668437313,
                  "title": "thequei8zeepae0xi7to4chui2Hohcha",
                  "username": "thequei8zeepae0xi7to4chui2Hohcha",
                  "type": "supergroup"
                },
                "date": 1660204801,
                "text": "this is a verification message"
              }
            }
          }

          and

          {
            "ok": true,
            "result": [
              {
                "user": {
                  "id": 1136612192,
                  "is_bot": false,
                  "first_name": "Max",
                  "username": "goldsteinq",
                  "language_code": "en"
                },
                "status": "creator",
                "is_anonymous": false
              }
            ]
          }

          Awesome! So then we use the ID to verify the identity and show the username in the UI! Thx for the logs. I'll try and test your code tonight.

          Goldstein Oh. I actually experimented a bit and thereā€™s no need to add a bot! Any bot, even not present in the channel, can make these queries. Then itā€™s just an extremely simple HTTP API with two methods.

          This is not my experience in my testing. If I don't add my bot to the channel, I get a "CHAT_ADMIN_RIGHTS" error message. Am I doing something wrong?

          You need to create a public group (you can disable posting, so it would be like a channel), not a public channel.

          Goldstein Public group admins are visible to everyone though, and thereā€™s an option to disable posting in the group, so it becames a de-facto channel

          It's not easy to make a group. I have to add somebody and if I add a single person, it just makes a private chat. How did you make such a group chat?