在React TypeScript Web应用中添加Teams呼叫按钮(支持多号码/多按钮)
React TypeScript 实现点击唤起Teams呼叫的方案
基础实现逻辑
不需要依赖额外的Teams SDK,直接使用Teams官方约定的呼叫深层链接格式即可触发唤起逻辑,浏览器和系统会自动弹出是否打开Teams客户端发起呼叫的确认提示,符合简易实现的要求。
完整代码实现
类型定义与组件封装
import React from 'react'; // 组件入参类型定义 interface TeamsCallButtonProps { /** 要拨打的手机号,支持带国家码、横杠、空格格式 */ phoneNumber: string; /** 按钮展示文案,默认为“发起Teams呼叫” */ buttonText?: string; /** 是否展示自定义联系人卡片,默认为false */ showContactCard?: boolean; /** 联系人卡片需要展示的额外信息,可按需扩展 */ contactInfo?: { name?: string; avatar?: string; email?: string; }; } // 自定义渲染联系人卡片的方法示例,可按需替换为自己项目的UI组件实现 const renderCustomContactCard = (phone: string, info?: TeamsCallButtonProps['contactInfo']) => { // 示例:使用项目内的浮层组件、Popover组件等渲染卡片,展示手机号、联系人姓名、头像等内容 console.log('展示联系人卡片', phone, info); }; const TeamsCallButton: React.FC<TeamsCallButtonProps> = ({ phoneNumber, buttonText = '发起Teams呼叫', showContactCard = false, contactInfo }) => { const handleCall = () => { // 清理手机号格式,移除所有非数字和+号的字符,避免格式错误导致唤起失败 const cleanedPhone = phoneNumber.replace(/[^0-9+]/g, ''); // Teams 呼叫固定链接格式 const teamsCallLink = `https://teams.microsoft.com/l/call/0/0?users=${cleanedPhone}`; // 新窗口打开链接触发唤起,避免当前页面被替换 window.open(teamsCallLink, '_blank', 'noopener noreferrer'); // 触发联系人卡片渲染 if (showContactCard) { renderCustomContactCard(cleanedPhone, contactInfo); } }; return ( <button onClick={handleCall} style={{ padding: '6px 12px', background: '#464EB8', color: '#fff', border: 'none', borderRadius: '4px', cursor: 'pointer' }} > {buttonText} </button> ); }; export default TeamsCallButton;
使用说明
- 唤起确认弹窗是浏览器和系统的默认行为,无需额外编码,只要用户本地安装了Teams客户端,点击后就会弹出是否打开Teams发起呼叫的提示
- Teams原生的小型联系人卡片仅支持在Teams内嵌运行的应用中调用,外部独立Web应用无法直接唤起,可自行实现自定义UI的浮层卡片替代,效果完全可以和原生卡片一致
- 如果需要兼容用户未设置Teams为呼叫协议默认应用的场景,可以把唤起链接替换为
tel:${cleanedPhone}格式,系统会弹出应用选择列表,用户可手动选择用Teams发起呼叫
业务页面调用示例
// 业务页面中引入组件直接使用即可 import TeamsCallButton from './components/TeamsCallButton'; const ContactPage = () => { return ( <div> <h2>联系人列表</h2> <TeamsCallButton phoneNumber="+86 138-0013-8000" buttonText="拨打张三电话" showContactCard={true} contactInfo={{ name: '张三', email: 'zhangsan@example.com' }} /> </div> ); }; export default ContactPage;
内容的提问来源于stack exchange,提问作者Noah
相关产品推荐
相关产品推荐

