Sending SMSes
Django doesn’t have an abstraction for sending SMSes, however there is the
Django SMS package that basically
duplicates the email API for SMS. Wailer is based upon this package and even
provides its own backends.
Everything in the SMS API is very similar to the email API and we’ll write this
documentation assuming that you already know how emails work.
Building the class
Our example will be a simple SMS of courtesy, to be able to say hello.
SmsType
The first thing to do is to extend SmsType
.
from wailer.interfaces import SmsType
class HelloUser(SmsType):
pass
Sender
Next you need to give a sender. That entirely depends on your backend. If you’re
using Mailjet, you can just put there the name of your application. Other
providers will ask you to register different phone numbers for different
countries.
Overall the logic is entirely up to you. You’re free to implement any logic and
it will be passed down to the backend, without any validation (which makes it a
double-edged sword).
In our case, we’ll assume Mailjet and do something simple:
def get_from(self) -> str:
return "Wailer"
User and context
We’ll expect to receive in the data the user_id
, which we can then exploit in
particular when making the context.
@cached_property
def user(self):
return User.objects.get(pk=self.data["user_id"])
def get_context(self) -> Mapping[str, JsonType]:
return dict(
name=f"{self.user.first_name} {self.user.last_name}",
locale=self.user.locale,
)
Recipient
Now we’re sending this SMS to the user’s phone number. You obviously need it
somewhere. In our case, that’s in the user model.
def get_to(self) -> str:
return self.user.phone_number
It’s expected to be something that libphonenumber can parse.
Content
Just like for emails, you need to decide which locale you will use. The locale
will be activated during content render.
def get_locale(self) -> str:
return self.context["locale"]
def get_content(self) -> str:
return _(f"Hello %(name)s") % dict(name=self.context["name"])
Let’s also note that if you wanted to make a link to the website itself, it’s
easy to get an absolute URL to insert into your content:
def get_content(self) -> str:
return _("Hello %(name)s, come home to: %(url)s") % dict(
name=self.context["name"],
url=self.make_absolute("/"),
)
Registering the type
You need to register your email type in settings.py
, much like you would for
emails:
WAILER_SMS_TYPES = {
"hello-user": "my_app.sms.HelloUser",
}
Sending the SMS
In order to send the SMS from your code, you can simply:
Sms.send("hello-user", dict(user_id=user.id), user)
Conclusion
Sending SMSes is a simpler version of email sending with a very similar
interface and much less concern.
Let’s however note that depending on the backend you choose, you might be up to
a different range of difficulties, given how tight and variable the regulation
can be in various countries.