Unicom360.GSM (Unicom360 v0.1.0)

Copy Markdown View Source

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

issue()

@type issue() :: :empty | :too_long | :non_gsm

A problem validate_sms/1 reports: :empty, :too_long or :non_gsm.

Functions

charset()

@spec charset() :: String.t()

The gateway's GSM-7 character set, as one string.

gsm7?(text)

@spec gsm7?(String.t()) :: boolean()

Whether every character of text is in the gateway's GSM-7 set. "" is GSM-7.

length(text)

@spec length(String.t()) :: non_neg_integer()

The length the gateway counts: code points, with each CR LF pair ("\r\n") counted once.

max_length()

@spec max_length() :: 1200

The longest text the gateway accepts, in characters (1200).

non_gsm_characters(text)

@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).

unit_length()

@spec unit_length() :: 160

The characters per billing unit (160).

units(text)

@spec units(String.t()) :: pos_integer()

The billing units per recipient: max(1, ceil(length / 160)). These are not GSM segments.

validate_sms(text)

@spec validate_sms(String.t()) :: [issue()]

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.