Opt-in GSM-7 helpers: the gateway's own answers about an SMS text, before you send it.
The gateway accepts only GSM-7 text (the GSM basic set plus ^{}\[~]|€, with no form feed),
at most 1,200 characters, and bills max(1, ceil(length / 160)) units per recipient, where a
CR LF pair counts as one character. The SDK never checks this when sending; these helpers do
it when you ask:
iex> Unicom360.GSM.gsm7?("Hello €")
true
iex> Unicom360.GSM.length("Hi\r\nthere")
8
iex> Unicom360.GSM.units(String.duplicate("a", 161))
2
iex> Unicom360.GSM.non_gsm_characters("It’s")
[{"’", 2}]
iex> Unicom360.GSM.validate_sms("It’s ready")
[:non_gsm]Characters are Unicode code points (an emoji is one), not bytes.
Summary
Types
A problem validate_sms/1 reports: :empty, :too_long or :non_gsm.
Functions
The gateway's GSM-7 character set, as one string.
Whether every character of text is in the gateway's GSM-7 set. "" is GSM-7.
The length the gateway counts: code points, with each CR LF pair ("\r\n") counted once.
The longest text the gateway accepts, in characters (1200).
Every character outside the GSM-7 set, in order, as {character, index} with index the
0-based code point position (here a CR LF pair counts as two).
The characters per billing unit (160).
The billing units per recipient: max(1, ceil(length / 160)). These are not GSM segments.
The problems the gateway would refuse text for, in this order: :empty (empty, or only
spaces, tabs, CR and LF), :too_long (more than 1,200 characters), :non_gsm. An empty list
means the gateway would accept the text.
Types
@type issue() :: :empty | :too_long | :non_gsm
A problem validate_sms/1 reports: :empty, :too_long or :non_gsm.
Functions
@spec charset() :: String.t()
The gateway's GSM-7 character set, as one string.
Whether every character of text is in the gateway's GSM-7 set. "" is GSM-7.
@spec length(String.t()) :: non_neg_integer()
The length the gateway counts: code points, with each CR LF pair ("\r\n") counted once.
@spec max_length() :: 1200
The longest text the gateway accepts, in characters (1200).
@spec non_gsm_characters(String.t()) :: [{String.t(), non_neg_integer()}]
Every character outside the GSM-7 set, in order, as {character, index} with index the
0-based code point position (here a CR LF pair counts as two).
@spec unit_length() :: 160
The characters per billing unit (160).
@spec units(String.t()) :: pos_integer()
The billing units per recipient: max(1, ceil(length / 160)). These are not GSM segments.
The problems the gateway would refuse text for, in this order: :empty (empty, or only
spaces, tabs, CR and LF), :too_long (more than 1,200 characters), :non_gsm. An empty list
means the gateway would accept the text.