如果您注意到由于系统因 Unicode 而只能发送多条短信,导致您的短信账单费用飙升,那么“如何阻止这种情况”很可能是您目前最迫切想解决的问题。一个不小心输入的智能引号(弯引号)或表情符号(emoji),就会瞬间将一条标准的低成本短信变成三条独立的计费分段,从而迅速消耗您的营销和运营预算。
步骤 1:理解为什么 Unicode 会强制拆分多个短信分段
要阻止您的短信网关将单条消息拆分为多个计费分段,您必须首先了解短信编码的底层技术原理。传统的电信网络在发送文本消息时主要使用两种编码标准:GSM-7 和 UCS-2 (Unicode)。
在标准的 GSM-7 编码下,单个短信分段最多可包含 160 个字符。该字符集包括标准的拉丁字母(A-Z、a-z)、数字(0-9)和一些常见的标点符号。然而,一旦您的消息内容中包含哪怕一个超出此基本字符集的字符——例如弯引号(’)、带重音符号的字母(á、é、ö)或表情符号(emoji)——整条短信的编码就会自动切换为 UCS-2。
当您的消息切换到 UCS-2 Unicode 编码时,每个分段的字符数限制会从 160 个字骤降至仅 70 个字符。如果您的消息长度为 140 个字符,它在 GSM-7 编码下可以轻松装入单个分段。但在 UCS-2 下,这相同的 140 个字符将需要拆分为两个独立的分段。像 Twilio、Vonage 和 MessageBird 这样的传统 API 提供商是按分段计费的,这意味着单条消息的成本会瞬间翻倍甚至翻三倍。
| 编码标准 | 最大字符数(单分段) | 最大字符数(多分段) | 常见触发字符 |
|---|---|---|---|
| GSM-7 | 160 个字符 | 每个分段 153 个字符 | 标准英文字母、数字、基本标点符号 |
| UCS-2 (Unicode) | 70 个字符 | 每个分段 67 个字符 | 表情符号(Emoji)、智能引号(“、”)、非拉丁字母、重音符号(é、ñ) |
这种机制解释了为什么您的应用程序会因为 Unicode 而发送多条短信。要解决这个问题,您要么需要对输入数据进行严格的清洗,要么需要过渡到不因发送较长、现代文本消息而惩罚性收费的 低成本短信 API。
步骤 2:在代码中清除或替换 Unicode 字符
通过编程防止 Unicode 拆分最直接的方法是在将消息发送到短信网关之前对其进行清洗。您可以在后端编写一个工具函数,清除所有非 GSM-7 字符,或将它们替换为最接近的 GSM-7 等效字符。
以下是使用简单的正则表达式模式和字符串替换规则在不同编程语言中实现该功能的方法。
Python 实现
在 Python 中,您可以使用 unicodedata 模块来对字符串进行归一化处理,清除重音符号并将智能引号转换回标准的直引号:
import unicodedata
import re
def clean_for_gsm7(text):
# Replace common smart quotes and dashes
replacements = {
u'\u201c': '"', u'\u201d': '"',
u'\u2018': "'", u'\u2019': "'",
u'\u2013': '-', u'\u2014': '-'}
}
for unicode_char, gsm_char in replacements.items():
text = text.replace(unicode_char, gsm_char)
# Normalize and strip accents
normalized = unicodedata.normalize('NFKD', text)
ascii_text = normalized.encode('ascii', 'ignore').decode('utf-8')
# Remove any remaining non-GSM-7 characters
gsm7_regex = re.compile(r'[^
a-zA-Z0-9^{}\\[~]|€$@!"#%&'()*+,-./:;<=>?_]')
cleaned_text = gsm7_regex.sub('', ascii_text)
return cleaned_text
message = "Hello! Your appointment is scheduled for tomorrow at 3 PM. See you there! 😊"
print(clean_for_gsm7(message))
# Output: "Hello! Your appointment is scheduled for tomorrow at 3 PM. See you there! "
Node.js (JavaScript) 实现
对于 JavaScript 开发者,您可以使用类似的方法,通过正则表达式清除任何不符合 GSM-7 标准的字符:
function sanitizeToGSM7(text) {
const smartReplacements = {
'[\u201c\u201d]': '"',
'[\u2018\u2019]': "'",
'\u2013': '-',
'\u2014': '-'
};
let cleaned = text;
for (const [pattern, replacement] of Object.entries(smartReplacements)) {
cleaned = cleaned.replace(new RegExp(pattern, 'g'), replacement);
}
// Remove accents
cleaned = cleaned.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
// Keep only GSM-7 compatible characters
const gsm7Pattern = /[^
a-zA-Z0-9^{}\\[~]|€$@!"#%&'()*+,-.\/:;<=>?_]/g;
return cleaned.replace(gsm7Pattern, '');
}
const rawMessage = "Your order is ready for pickup! 🚗";
console.log(sanitizeToGSM7(rawMessage));
// Output: "Your order is ready for pickup! "
步骤 3:将智能引号和重音符号转换为 GSM-7 等效字符
通常,Unicode 字符是通过从 Microsoft Word 或 Google Docs 等文字处理器复制粘贴而悄悄混入您的消息中的。这些处理器会自动将标准的直引号(' 和 ")转换为弯曲的“智能”引号(‘、’、“、”)。
为了防止您的系统因这些细微的变化而发送多条短信,您可以建立一个字符映射表。这可以让您在保留文本可读性的同时,避免触发 70 个字符的 UCS-2 限制。
- 将 ‘ 和 ’ 转换为标准单引号 '
- 将 “ 和 ” 转换为标准双引号 "
- 将破折号(—)和连接号(―)转换为标准连字符(-)
- 将带重音符号的字符(如 é、á、í)转换为不带重音的对应字符 e、a、i
通过明确映射这些字符,您既能保持消息的专业外观,又能严格限制在单分段字数内。这对于牙科诊所、维修店和语言学校等本地服务型企业特别有帮助,因为它们需要在发送自动预约更新的同时,保持极低的运营成本。
步骤 4:切换到采用固定费率分段计费的短信网关
虽然清除 Unicode 字符是一个可行的临时解决方案,但它迫使您在品牌形象和表达上做出妥协。在 2026 年,客户期望更加自然的沟通方式,这通常包括表情符号、本地化重音和专业的排版。仅仅为了避免高昂的电信账单而将与客户的沟通限制在基础的 ASCII 字符上,这已经没有必要了。
传统的云端短信集成商(如 Twilio、Plivo 和 MessageBird)强制执行严格的按分段计费,因为它们必须为每个数据包向运营商支付费用。此外,使用这些传统平台需要处理复杂的 A2P SMS 注册、10DLC 运营商审批以及每月产生的经常性费用。
一个越来越受欢迎的替代方案是使用基于 Android 的短信网关,例如 MySMSGate。MySMSGate 可以将您自己的 Android 手机和 SIM 卡转变为功能齐全的短信发送设备。因为您的消息是直接通过手机的 SIM 卡发送的(SIM 卡通常包含无限量或高折扣的本地短信套餐),从而完全绕过了传统按分段计费的模式。
MySMSGate 收取 每条发送短信 $0.02 的固定费率,无论您的消息中是否包含 Unicode 字符、表情符号,还是跨越多个分段。没有月租订阅、没有合同限制,也没有运营商注册带来的延迟。如果消息发送失败,您的余额将自动退还。
如果您正在寻找用于群发短信对比、可靠性和送达率的 最佳 SMS API 替代方案,那么转向 Android 短信网关可以从源头上彻底避开 Unicode 计费问题。
步骤 5:设置多手机号码短信管理
对于在多个地点运营的本地服务型企业,管理短信基础设施很快就会变得复杂。如果您正在管理多个分支机构——例如五家牙科诊所或三家汽车维修店——您需要一个支持从单个中央界面进行多手机号码短信管理的系统。
通过 MySMSGate,您可以将无限数量的 Android 设备连接到同一个账户控制面板。这使您能够无缝管理多个号码:
- 创建您的账户:在 MySMSGate 注册以获取您的 API 密钥。
- 安装 Android 应用:在您的 Android 设备上下载 MySMSGate 配套应用程序。
- 通过二维码连接:使用每部手机的摄像头扫描网页控制面板上显示的二维码。这会立即将设备链接到您的中央账户,无需手动输入复杂的 API 密钥。
- 管理双卡双待(Dual SIMs):如果您的手机支持双卡,您可以直接在控制面板或 API 调用中精确选择从哪个 SIM 卡槽发送消息。
这种多设备结构允许您通过客户已熟悉的本地化号码来发送通知,从而显著提高打开率和回复率。所有收到的回复都会自动转发回基于网页的 Web Conversations(网页会话)控制面板,使您能够直接在电脑上进行实时的双向聊天。
步骤 6:通过 REST API 发送您的第一条 Unicode 安全短信
如果您是独立开发者、自由职业者或技术型企业主,将 MySMSGate 集成到您的软件中是非常简单直接的。该平台提供了一个整洁的单端点 REST API,让您只需极少的设置即可触发短信通知。
以下是如何使用 cURL 发送 POST 请求以发送短信的示例。请注意,您可以包含表情符号和特殊的 Unicode 字符,而无需担心分段计费成本飙升:
curl -X POST https://mysmsgate.net/api/v1/send
-H "Authorization: Bearer YOUR_API_KEY"
-H "Content-Type: application/json"
-d '{
"to": "+1234567890",
"message": "Your vehicle is ready for pickup! 🚗 Please reply to this message if you have any questions.",
"device_id": "your_device_id",
"sim_slot": 1
}'若要了解更详细的语言实现,您可以浏览官方的 MySMSGate API 文档。其中包含适用于 Python、Node.js、PHP、Go 和 Ruby 的生产就绪型代码片段,以及适用于 Zapier、Make.com 和 n8n 等自动化平台的预构建连接器。
常见问题解答
以下是关于 Unicode 短信拆分、字符限制和计费结构最常见问题的解答。
为什么一个表情符号会导致我的短信作为多条消息发送?
标准短信使用 GSM-7 编码,每个分段最多允许 160 个字符。表情符号不属于 GSM-7 字符集。当您添加表情符号时,运营商必须将整条消息切换为 UCS-2 (Unicode) 编码,这会将分段限制降低到 70 个字符。如果您的消息超过 70 个字符,它就会被拆分为多个分段,而传统的 API 会对每个分段进行收费。
如何在发送前检查我的文本是否包含 Unicode 字符?
您可以使用在线短信长度计算器,或者在代码中运行简单的正则表达式搜索来检测非 GSM-7 字符。或者,您可以编写验证脚本,在将数据传递到发送短信队列之前,标记或清除数据库中的非 GSM-7 字符。
MySMSGate 会对 Unicode 或多分段消息收取额外费用吗?
不会。与 Twilio 或 Vonage 等按 160 或 70 字符分段计费的传统 API 不同,MySMSGate 每发送一条消息收取 $0.02 的固定费用。因为消息是直接通过您的 Android 手机 SIM 卡发送的,所以您无需按分段付费,从而使您能够发送表情符号和长消息,而不必担心隐藏费用。
使用 Android 短信网关需要运营商或 10DLC 注册吗?
不需要。因为 MySMSGate 通过您自己的实体 Android 手机和 SIM 卡路由消息,所以您的消息是以标准的个人对个人 (P2P) 流量发送的。这意味着您无需进行复杂、昂贵且耗时的 A2P 10DLC 注册,也无需等待运营商的审批。
Comments (0)
Be the first to comment!