RapidSMS 0.21.0 release notes

Welcome to RapidSMS 0.21.0! These release notes cover the new features in 0.21.0 as well as some Backwards-incompatible changes in RapidSMS 0.21.0 you’ll want to be aware of when upgrading from RapidSMS 0.20.0.

What’s New

  • Fix ‘missing migration’ issues #459 and #460
  • (Fixed #465) Allow backends to specify failed identities back to router.
  • (Fixed #439) Allow newlines in KeywordHandler. [Thanks @knightsamar!]

Backwards-incompatible changes in RapidSMS 0.21.0

  • The fix for #460 involves dropping a table which was inadvertently created by a complicated bug. The table is the BackendMessage which should not have valuable data in it, and there is a migration included which should copy any data to the proper table, but we recommend that you back up your database before making this upgrade, especially if you have valuable data in the BackendMessage table.

  • The fix for #465 slightly alters the API between Backends and Routers. Previously, there was only one way for the Backend to communicate information about the status of outgoing messages back to the Router. It could raise an exception. The problem is that it’s possible that the Backend was responsible for sending a message to multiple identities and that some of those messages could be successful and some could fail. Routers that automatically retry failures (only the DatabaseRouter, currently) had no way of knowing which identities failed, so if they just retried all failures, then some identities would receive multiple messages. The fix for #465 allows Backends to add a failed_identities parameter to the exception, which allows the Router to retry failures more intelligently.

    What should you change? Changes are optional. Things should work as they did before without changes, but the following changes may improve reliability:

    • Router authors: Look at the DatabaseRouter for a working example of how to deal with failed_identities. Basically, it calls Router.send_to_backend, catching any Exception and looking for a failed_identities parameter. It then can retry only those identities.

    • Backend authors: Backend.send should try sending messages to all identities, keeping a list of failures and returning that list in the exception. If there are no failures, then it should return None. Making this change will allow specific Routers to behave more intelligently. See the new documentation for Backend.send, which is copied below:

      class rapidsms.backends.base.BackendBase(router, name, **kwargs)

      Base class for outbound backend functionality.

      send(id_, text, identities, context=None)

      Backend sending logic. The router will call this method for each outbound message. This method must be overridden by sub-classes. Backends typically initiate HTTP requests from within this method.

      If multiple identities are provided, the message is intended for all recipients.

      Any exceptions raised here will be captured and logged by the router. If messages to some identities failed while others succeeded, you can provide that information back to the router by adding a list of the identities which failed in a failed_identities parameter on the exception. If you do provide that parameter, then the router should assume that all identities not listed in failed_identities were successfully sent.

      def send(self, id_, text, identities, context):
          failures = []
          for identity in identities:
              result = send_my_message(identity, text, context)
              if result == 'failed':
          if failures:
              msg = '%d messages failed.' % len(failures)
              raise MessageSendingError(msg, failed_identities=failures)
      • id_ – Message ID
      • text – Message text
      • identities – List of identities
      • context – Optional dictionary with extra context provided by router to backend