Telegram mini app 登录小部件 | 自定义登录按钮 或 静默登录

先说我遇到的问题,我按照流程接入了 telegram 登录小部件,在 PC 或者 H5 可以拿到数据(不管是选择回调函数还是回调地址的形式都可以),但是在 telegram mini app 中登录拿不到数据,在 telegram 中 我点击登录的小部件后是在浏览器中打开授权网址,然后授权后回调也是在浏览器中打开一个新标签页,而不是在 telegram 中打开

设置机器人域名

这里我假设你已经有一个机器人了(没有的网上有很多 文章 教怎么创建机器人),在 @BotFather 中输入 /myapps

image.png

image.png

点击 Edit Web App Url 后输入你的域名地址(这里也可以输入你的开发地址,以 https 开头,但是不能使用 登录小部件 因为你的网址和 telegram-widget.js 生成的 iframe 域名不一致会导致浏览器安全策略问题)

然后再输入 /setdomain, 同样的选择你的机器人然后输入你的网址

image.png

到这一步前置条件已完成。

登录

第一步

设置回调函数

// ...
      <Script
        id="get-telegramAuth"
        dangerouslySetInnerHTML={{
          __html: `
  function onTelegramAuth(user) {
    console.log('user =>>>', user)
    alert('Logged in as ' + user.first_name + ' ' + user.last_name + ' (' + user.id + (user.username ? ', @' + user.username : '') + ')');
  }
`,
        }}
      ></Script>
// ...

第二步

这里我是使用 Next 框架编写的代码,在只需要改一下格式在其他框架中也可以使用。

import Script from 'next/script';
export const TGLogin = () => {
  return <>
  <Script async src='https://telegram.org/js/telegram-widget.js?22' data-telegram-login='<你的机器人用户名>' data-request-access='write' data-size='large' data-radius='10' data-onauth='onTelegramAuth(user)'></Script>
  <div id="my-special-div" onClick={() => {
    window.location.href = 'https://oauth.telegram.org/auth?bot_id=6889929762&origin=https%3A%2F%2Fwww.telegramloveai.com&embed=1&request_access=write&return_to=https%3A%2F%2Fwww.telegramloveai.com%2Fen%2Flogin'
  }}>
    LOGIN
  </div>
  </>;
};

href 中地址是点击登录小部件进入新标签页的地址

image.png

机器人用户名不需要 @

image.png

Mini Apps 成功示例

image.png

静默登录

引入 js 文件 TG 文档

'/api/tg-login' 接口是我自己定义的,里面处理校验数据等逻辑。

'use client';

import Script from 'next/script';
import { toast } from 'sonner';

export const TGInitScript = () => {
  let initData = '';

  const TGWebAppReady = () => {
    const WebApp = window.Telegram.WebApp;

    /**
     * 静默登录
     */
    if (WebApp.initDataUnsafe.user) {
      console.log(WebApp.initDataUnsafe);

      initData = `query_id=${
        WebApp.initDataUnsafe.query_id
      }&user=${encodeURIComponent(
        JSON.stringify(WebApp.initDataUnsafe.user)
      )}&auth_date=${WebApp.initDataUnsafe.auth_date}&hash=${
        WebApp.initDataUnsafe.hash
      }`;

      const sendRequest = async () => {
        try {
          const { result, code, message } = await (
            await fetch('/api/tg-login', {
              method: 'POST',
              body: JSON.stringify({ initData }),
            })
          ).json();

          if (code != '200') {
            throw new Error(message);
          }
        } catch (err: any) {
          toast(err.message);
        }
      };

      sendRequest();
    }
  };
  return (
    <>
      <Script
        src="https://telegram.org/js/telegram-web-app.js"
        onReady={TGWebAppReady}
      ></Script>
    </>
  );
};

api 文件代码

import { NextRequest } from 'next/server';
import { validate } from './check';
import axios from 'axios';

const handle = async (req: NextRequest) => {
  const body = await req.json();

  const BaseUrl =
    '';

  try {
    // 验证数据完整性
    validate(body.initData, process.env.NEXT_PUBLIC_TOKEN!);

    const searchParams = new URLSearchParams(body.initData);
    const user = JSON.parse(searchParams.get('user')!);

    // 和后端接口进行交互
    const { data: ApiData } = await axios(
      BaseUrl + '/authLogin',
      {
        method: 'POST',
        data: {
          loginType: 'telegram-mini-apps',
          email: '',
          nickname:
            user.first_name + (user.last_name ? ' ' + user.last_name : ''),
          openId: user.id,
          avatarUrl: user.photo_url,
          loginName: user.username,
        },
      }
    );

    return Response.json(ApiData, {
      status: 200,
    });
  } catch (error: any) {
    return Response.json(
      {
        code: '500',
        message: error.message || '',
      },
      { status: 500 }
    );
  }
};
export { handle as POST };

check 文件代码是复制的 tma.js 仓库中 文件数据 validate.ts

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用 Java 代码进行 Telegram 登录的示例: ```java import org.telegram.telegrambots.ApiContextInitializer; import org.telegram.telegrambots.bots.TelegramBot; import org.telegram.telegrambots.meta.TelegramBotsApi; import org.telegram.telegrambots.meta.exceptions.TelegramApiException; import org.telegram.telegrambots.meta.generics.BotSession; public class TelegramLogin { public static void main(String[] args) { // 初始化 API 上下文 ApiContextInitializer.init(); // 创建 TelegramBotsApi 实例 TelegramBotsApi botsApi = new TelegramBotsApi(); try { // 注册并启动你的 Bot BotSession botSession = botsApi.registerBot(new YourTelegramBot()); System.out.println("Bot 已启动。按下 Ctrl+C 停止。"); } catch (TelegramApiException e) { e.printStackTrace(); } } } import org.telegram.telegrambots.bots.TelegramLongPollingBot; import org.telegram.telegrambots.meta.api.methods.send.SendMessage; import org.telegram.telegrambots.meta.api.objects.Update; import org.telegram.telegrambots.meta.exceptions.TelegramApiException; public class YourTelegramBot extends TelegramLongPollingBot { @Override public void onUpdateReceived(Update update) { // 处理收到的消息 if (update.hasMessage() && update.getMessage().hasText()) { String messageText = update.getMessage().getText(); long chatId = update.getMessage().getChatId(); // 回复消息 SendMessage message = new SendMessage() .setChatId(chatId) .setText("你发送了:" + messageText); try { execute(message); } catch (TelegramApiException e) { e.printStackTrace(); } } } @Override public String getBotUsername() { // 返回你的 Bot 的用户名 return "YourBotUsername"; } @Override public String getBotToken() { // 返回你的 Bot 的 Token return "YourBotToken"; } } ``` 请确保在运行代码之前,你已经在 Telegram 上创建了一个 Bot,并获得了 Bot 的用户名和 Token。将这些信息替换到代码中的 `YourBotUsername` 和 `YourBotToken` 处。 此示例使用了 `TelegramBotsApi` 和 `TelegramLongPollingBot` 类,它们是 TelegramBots 库的一部分。请确保已经将 TelegramBots 库添加到你的项目中。 这个示例中的代码是一个简单的回复机器人,它会将接收到的消息原样返回给用户。你可以根据自己的需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值