Как отправлять SMS с помощью AWS Lambda, SNS и Python 3

Illustration of a robotic arm interacting with a laptop while a man observes closely, hinting at a concept of automation or robotic programming.
Обновлено: | Опубликовано:

Вступление

В этой статье мы поговорим о том, как отправлять и получать СМС с помощью AWS. Мы начнем с создания логгера сообщений, который будет получать сообщения и записывать их содержание и отправителя. Затем мы создадим echo-сервис, который будет отвечать на любое сообщение полученным текстом. И наконец, мы назначим ежедневное сообщение на указанный номер телефона. Мы будем использовать СМС и различные сервисы AWS. Обратите внимание, что в рамках данной статьи мы взаимодействуем со всеми сервисами только через их веб-интерфейсы. Полноценные приложения в данном случае управляли бы кодом и службами с помощью технологий контроля версий, непрерывной интеграции/непрерывной доставки и инфраструктуры-как-кода, например Terraform или AWS CloudFormation. Однако для практики в использовании сервисов будет достаточно только интерактивной консоли AWS.

Amazon Web Services (AWS) предоставляют Lambda — бессерверную среду, позволяющую программистам выполнять дискретные функции без сервера. Написать и развернуть функцию AWS Lambda можно очень быстро, и она не нуждается в такой в поддержке, как, например, приложение, работающее на виртуальном сервере типа EC2. Функции в Lambda дешевы: обычно Amazon просит 20 центов (13 рублей) за миллион запросов (каждое выполнение функции считается запросом), а первый миллион запросов в месяц является бесплатным всегда и для всех пользователей. AWS предлагает множество методов для запуска этих дешевых и простых функций. В данной статье мы расскажем, как использовать AWS Lambda для отправки и получения СМС.

SMS (Short Message Service — служба коротких сообщений, СМС) — старейший протокол, используемый в миллиардах мобильных устройств по всему миру. Некоторые из его свойств могут выглядеть странно в сравнении с интернет-протоколами. Например, у каждого номера телефона есть код региона. В данной статье мы рассматриваем сервисы AWS в США и, соответственно, используем американский телефонный номер с кодом региона +1. Также этой устаревшей инфраструктурой можно объяснить тот факт, что СМС, в отличие от AWS Lambda, — довольно дорогой сервис. Когда все бесплатные сообщения израсходованы, вы вынуждены платить 0.0075$ (48 копеек) за получение и 0.00645$ (41 копейку) за отправку сообщения. Чтобы протестировать функции, описанные в этой статье, бесплатных сообщений будет достаточно, но подумайте хорошенько, подходит ли СМС-сервис для вашего приложения, принимая во внимание его цену. Например, приложение, которое отправляет всего одно СМС тысяче пользователей каждый день будет стоить вам почти 200$ (13 000 рублей) в месяц.

Получение СМС

Прежде всего, вам нужен аккаунт в AWS. Этот аккаунт даст вам доступ ко всем сервисам AWS, а также к «бесплатному уровню», позволяющему по доступной цене или абсолютно бесплатно попробовать большую часть продуктов и даже запустить небольшие приложения. Зайдите в аккаунт, перейдите к Lambda и создайте новую функцию.

Создание функции в Lambda

Имя функции может быть любым. Выберите Python 3.7, самый стабильный релиз Python 3, в качестве среды исполнения. AWS оперирует всеми своими сервисами, используя разрешения на основе ролей, систему, о которой в рамках этой статьи мы говорить не будем (хотя мы и рассмотрим ее позже). Для этой функции, выберите "Create a new role with basic Lambda permissions", и AWS все сделает за вас. После настройки параметров, кликните "Create Function", чтобы попасть на страницу редактирования функции.

Дизайнер функции в Lambda

В этом окне есть несколько важных кнопок. Самая важная — "Save" сохраняет любые изменения в Lambda-функции, а "Test" дает вам писать и выполнять тесты для вашей функции. Если вы не нажмете кнопку "Save", изменения в вашей функции не будут сохранены.

Дизайнер функции в Lambda позволяет вам выбрать, какие сервисы могут запускать функцию, и к каким из них функция может обращаться во время запуска. Мы будем использовать следующие сервисы: SNS (Simple Notification Service — Простой сервис уведомлений), CloudWatch Events для триггеров, а Amazon Pinpoint и Amazon CloudWatch Logs во время выполнения функции.

Чтобы добавить сервис в функцию, просто кликните на него в списке слева от дизайнера. Для начала добавьте SNS в качестве триггера. Вам нужно будет присвоить SNS роль, необходимую для запуска Lambda-функций (AWS предложит вам это сделать), затем сохранить функцию. Обновите страницу и прокрутите вниз, чтобы увидеть код функции.

Написание функции в Lambda

AWS предлагает онлайн-среду разработки для программирования функции в Lambda. Вы можете импортировать библиотеки и писать свои методы. Однако когда Lambda-функция срабатывает, на самом деле запускается функцияlambda_handler(). Этот основной метод принимает event и context в качестве параметров. event — огромный словарь, доступный функции, аcontext хранит собственно контекст выполнения. Нам нужно будет ссылаться только на event. Наша первая функция будет невероятно простой: она получает номер телефона и текст сообщения и записывает их в ваши логи CloudWatch.

import json
def lambda_handler(event, context):
    message = json.loads(event['Records'][0]['Sns']['Message'])
    words = message['messageBody']
    number = message['originationNumber']
    return {
        'statusCode': 200,
        'body': json.dumps("Phone number: {}\nMessage Text: {}".format(number, words))
    }

message — словарь, который мы выгружаем из event. Мы извлекаем тело сообщения (сам текст сообщения) и номер источника (номер, с которого отправлено СМС). Пока что просто скинем эту информацию в CloudWatch. В качестве теста можно отправить СМС на связанный с функцией номер. Для этого нужно активировать AWS Pinpoint. Хотите пропустить этот шаг? Ниже я объясню, как тестировать функцию, используя встроенную в Lambda службу тестирования, но важно понимать Pinpoint для, собственно, отправки сообщений.

Создание Pinpoint-проекта

После того, как вы активируете свой первый Pinpoint-проект, на экране настроек кликните "Manage" под "SMS and Voice".

Настройка Pinpoint-проекта

Запрос длинного (федерального) номера

Затем запросите длинный номер — телефонный номер специально для вашего проекта. Такие номера стоят 1 доллар (64 рубля) в месяц, так что не забудьте отказаться от него после окончания тестирования. Выберите нужную вам страну, куда будут отправляться сообщения, и установите тип вызова как «рекламный» ("Promotional") по умолчанию. После получения номера нужно будет добавить Pinpoint к роли IAM, связанной с Lambda-функцией, посредством добавления следующего разрешения к роли в консоли IAM.

Разрешения для Pinpoint

Теперь вы можете отправлять сообщения вашей Lambda-функции. Однако вместо этого вы можете имитировать отправку с помощью тестирования, встроенного в Lambda. В качестве шаблона выберите "Amazon SNS Topic Notification" и назовите событие, как вам захочется. Вставьте следующую строку в качестве значения, ассоциированного с ключом Message, как показано на картинке.

Настройка тестового события

"{\"originationNumber\": \"+19997771111\",\"messageBody\": \"This is the test message\",\"inboundMessageId\": \"EXAMPLE\",\"previousPublishedMessageId\": \"EXAMPLE\",\"messageKeyword\": \"keyword_example\",\"destinationNumber\": \"+10120120123\"}"

Не забывайте о том, что event — это просто словарь, и именно поэтому мы можем протестировать Lambda-функцию с помощью создания собственного события. Сохранив тест, нажмите "Test" в правом верхнем углу экрана, чтобы выполнить Lambda-функцию. При успешном выполнении консоль покажет вам, что вернула функция.

Отправка СМС

Мы уже научились получать СМС, так что теперь самое время поговорить об отправке. Этот шаг, в отличие от получения сообщений, требует, чтобы вы заранее настроили AWS Pinpoint для тестирования. Чтобы продемонстрировать процесс отправки и получения СМС, мы настроим простой echo-сервис: вы отправляете сообщение, на которое сервис отвечает вашим же текстом.

import json
import boto3
pinpoint = boto3.client('pinpoint')
def lambda_handler(event, context):
    message = json.loads(event['Records'][0]['Sns']['Message'])
    pinpoint.send_messages(
        ApplicationId='YOUR_PINPOINT_APPLICATION_ID',
        MessageRequest={
            'Addresses': {
                message['originationNumber']: {'ChannelType': 'SMS'}
            },
            'MessageConfiguration': {
                'SMSMessage': {
                    'Body': message['messageBody'],
                    'MessageType': 'PROMOTIONAL'
                }
            }
        }
    )

Импортboto3 позволяет нам инициализировать pinpoint-объект для отправки сообщений. Сообщение будет отправлено с того самого длинного телефонного номера, который вы запросили ранее. Все, что вам нужно сделать для настройки, это вставить ваш идентификатор приложения для Pinpoint.

Эту систему можно использовать для создания СМС-чатбота, например, виртуальной службы поддержки клиентов (хотя веб-чат будет в разы дешевле). Еще одна область применения — отправка отложенных СМС. Изменив триггер с SMS на события CloudWatch, можно создать приложение, каждое утро уведомляющее вашего босса о вашем опоздании с извинениями. Выберите "CloudWatch Events" в левом меню и настройте параметры, как показано на рисунке.

Настройка тестового события

import json
import boto3
import random
pinpoint = boto3.client('pinpoint')
def lambda_handler(event, context):
    messages = ['Стою в пробке, извините.',
                'Проблемы с машиной, скоро буду.',
                'Сын заболел.',
                'Вчера вечером остался в офисе допоздна, нужно было доделать контракт.']
    pinpoint.send_messages(
        ApplicationId='YOUR_PINPOINT_APPLICATION_ID',
        MessageRequest={
            'Addresses': {
                'BOSS_PHONE_NUMBER': {'ChannelType': 'SMS'}
            },
            'MessageConfiguration': {
                'SMSMessage': {
                    'Body': random.choice(messages),
                    'MessageType': 'PROMOTIONAL'
                }
            }
        }
    )

Оправдания получше, как и установка номера AWS Pinpoint в качестве вашего контакта в телефоне вашего начальника, лежат на ваших плечах. Я, конечно же, ни в коем случае не одобряю подобные вещи.

Теперь вы знаете, как отправлять и получать СМС с помощью AWS Lambda. У AWS Lambda много мощных и разнообразных функций, которые позволяют сделать гораздо больше, чем просто СМС-сообщения. СМС-сервис, если он необходим для вашего приложения, легко настроить и использовать, но его стоимость, а также проблемы с задержкой сообщений подойдут далеко не для всяких целей. Но это все еще лучший вариант для функций типа подтверждения номера телефона. К тому же, СМС поддерживается такими голосовыми помощниками, как Сири и Алекса. Если вашему клиенту необходимы СМС в его проекте, AWS Lambda — отличный выбор.

Давайте повторим, что мы сегодня использовали:

  • Lambda для бессерверных функций,
  • SNS для получения уведомлений и СМС,
  • Pinpoint для отправки СМС и получения телефонного номера,
  • IAM для управления доступом и разрешениями,
  • CloudWatch для процессов мониторинга, регистрации и запуска.

Subscribe to our Newsletter

Let us send you the best of what we've discovered in DevOps, Cloud and Kubernetes, as well us occasional event announcements.

We are also preparing some ways to learn together: weekly challenges, free courses and more. Subscribe now to be the first to get those.