В этом материале расскажем, как автоматизировать отправку сообщений-уведомлений по данным из таблицы.
Допустим, есть заранее приготовленная база данных в CMS, куда попадают заявки от покупателей — возможно, это заказ товаров или в ресторане. Наша задача: используя указанный номер телефона, уведомить пользователя о том, что его заказ готов к выдаче. Добавим, что нам потребуется имя покупателя и адрес пункта выдачи.
Основная идея работы заключается в том, чтобы связать базу данных с формой SMS-рассылки. Она, в свою очередь, использует API Exolve для отправки ранее заготовленного сообщения. Для упрощения задачи мы расскажем про реализацию проекта с применением Google Таблиц, но благодаря одному из наших прошлых гайдов можно легко произвести привязку к CMS.
Форму рассылки из браузера мы уже реализовали ранее — это метод упрощения передачи данных, который позволяет не влезать в тонкости программирования, если нужно срочно отправить сообщение.
Именно поэтому алгоритм работы будет следующий:
-
Создать Excel-файл со всей необходимой информацией (имя, адрес, номер телефона, номер заказа).
-
Создать форму для автоматической отправки сообщений (с автоматической подстановкой данных, кодом авторизации).
-
Сделать привязку Excel-файла к форме для автоматической передачи данных каждые 20 секунд.
-
Profit.
Это решение может показаться немного «костыльным» из-за формы — без нее можно обойтись, автоматизировав чтение и отправку сообщений.
Для того, чтобы система работала в автоматическом режиме, потребуется сервер. Нагрузка не очень большая, можно использовать даже просто рабочий ноутбук — из требований к серверу можно выделить только go 1.20, наличие SSL (https), а также маршрутизацию.
Этап 1. Создание Excel-файла
Лучший вариант — воспользоваться онлайн-системой по типу Google Docs. Это потребует постоянного подключения к интернету или общей сети, но гарантирует практически моментальный отклик при необходимости.
Из обязательных полей можно выделить:
-
номер получателя;
-
имя покупателя;
-
текст для рассылки («Ваш заказ номер НН готов»);
-
адрес получения («подойдите туда-то»);
-
номер отправителя (если внутри Exolve арендовали несколько номеров для разных филиалов, например).
Итоговый вариант таблицы может выглядеть следующим образом:
При необходимости можно добавить несколько полей и реализовать это в программном коде. Также MTC Exolve позволяет использовать имя отправителя для юрлиц, чтобы пользователи в поле отправителя видели не просто номер, а название организации — для этого нужно лишь подтвердить аккаунт и заключить договор.
Также нужно создать программу, которая будет обрабатывать данные этой таблицы — считывать их и переводить далее. Для этого нужно скачать любой компилятор Python, вставить в него следующий код и сохранить файл:
import asyncio import json import requests as requests from google.oauth2 import service_account from googleapiclient.discovery import build async def send_message_client(data): url = 'https://api.exolve.ru/messaging/v1/SendSMS' # для сайта response = requests.post(url=url, headers={ "Authorization": "”Код авторизации”", }, json=data) print(type(response.json)) print(response.json) print(response) return response class GoogleSheetData: def __init__(self): # Путь к файлу JSON с учетными данными self.SERVICE_ACCOUNT_FILE = 'credentials.json' # Создание учетных данных из файла JSON self.creds = service_account.Credentials.from_service_account_file( self.SERVICE_ACCOUNT_FILE, scopes=[ 'https://www.googleapis.com/auth/spreadsheets', 'https://www.googleapis.com/auth/drive', ] ) # Создание клиента API self.service = build('sheets', 'v4', credentials=self.creds) # ID вашей таблицы Google Sheets self.spreadsheet_id = 'ID' async def processing_google_sheet(self): try: # открываем файл JSON, читаем данные и записываем их в переменную 'data' # если файл не найден, создаем новую пустую переменную 'data' try: with open('data.json', "r") as file: data = json.load(file) except FileNotFoundError: data = {1: ['Имя', 'Ваш заказ номер НН готов', 'подойдите туда-то', 'Номер']} # получаем номер строки с которым будем работать row = int(list(data.keys())[0]) + 1 # Запрос на получение данных из таблицы Google Sheets(получаем определенную строку в range) response = self.service.spreadsheets().values().get( spreadsheetId=self.spreadsheet_id, range=f"Лист1!A{row}:E{row}", ).execute() # получаем строку с данными values = response.get('values', []) print(values) # проверяем на наличие данных if not values: print('No data found.') elif len(values[0]) >= 5 and '' not in values[0]: data_excel = {"number": values[0][4], "destination": values[0][0], "text": f"{values[0][1]}, Ваш заказ номер {values[0][2]} готов, подойдите {values[0][3]}"} print(data_excel) result_send_message = await send_message_client(data_excel) data = {row: values[0]} print(data) # записываем новые данные в файл 'data.json' with open('data.json', "w") as file: json.dump(data, file, indent=4, ensure_ascii=False) except Exception as e: print(f"An error occurred: {e}") async def run_processing_google_sheet(google_sheet_req): while True: await google_sheet_req.processing_google_sheet() await asyncio.sleep(20) if __name__ == "__main__": google_sheet_req = GoogleSheetData() asyncio.run(run_processing_google_sheet(google_sheet_req))
Мы постарались расписать все шаги максимально понятно, чтобы даже рядовой пользователь мог скопировать код и попробовать его на своей таблице. В итоге мы получаем таблицу с полным доступом для программы, которая считывает данные и передает их в форму отправки. Помимо этого, мы сделали обработку на наличие пустых клеток (тогда код просто пропустит такие строки), а также уже отработанных заявок. Проверка производится раз в 20 секунд, но можно установить собственное значение.
Этап 2. Создание формы отправки
Несмотря на то, что мы уже создали связь таблицы с API Exolve для отправки сообщений, для перестраховки и ручной отправки мы соберем форму. Значения в нее будут подставляться автоматически. Также это защитит нашу программу от сбоев при неправильном заполнении полей.
В первую очередь займемся написанием кода обработки, а после дополним его внешней составляющей — кстати, кастомизировать ее можно по своему усмотрению и даже включить в пользовательский интерфейс.
Для удобства дальнейшего использования мы написали код работы формы на Python. Остается вставить его в любой компилятор и сохранить в виде отдельного файла:
import asyncio import json import re import requests as requests from google.oauth2 import service_account from googleapiclient.discovery import build from quart import Quart, render_template, request app = Quart(__name__) async def send_message_client(data): url = 'https://api.exolve.ru/messaging/v1/SendSMS' # для сайта response = requests.post(url=url, headers={ "Authorization": "Код авторизации", }, json=data) return response @app.route('/', methods=['GET', 'POST']) def index(): if request.method == 'POST': data = dict(request.form) for key in request.form: if request.form[key] == '': return render_template('index.html', error='Не все поля заполнены!') if key == 'destination': if not re.match('7\d{9}', request.form[key]): return render_template('index.html', error='Неправильный формат номера телефона') result_send_message = send_message_client(data) if "error" in result_send_message.json: return render_template('index.html', error=f"Ошибка, вид ошибки: {result_send_message.json()}") return render_template('index.html', error=f"Запрос обработан!, id message: {result_send_message.json()}") return render_template('index.html') if __name__ == "__main__": app.run()
Этот код, помимо отправки сообщений, еще может проверять поля на корректность заполнения — правильно ли указан номер телефона, например. В остальном же это потребует параллельного запуска с основным табличным файлом.
Формируем файл JavaScript, в котором распишем, что должна делать эта форма: в частности, получать значения в специальные поля и передавать их в API Exolve:
async function postData(formProps) { const url = 'https://api.exolve.ru/messaging/v1/SendSMS'; const data = { number: number, destination: destination, text: text }; try { console.log(JSON.stringify(data)); const response = await fetch(url, { method: "POST", body: JSON.stringify(formProps), headers: { "Authorization": "Код авторизации", }, }); const json = await response.json(); console.log("Успех:", JSON.stringify(json)); } catch (error) { console.error("Ошибка:", error); } } function logSubmit(event) { event.preventDefault(); const formData = new FormData(event.target); const formProps = Object.fromEntries(formData); postData(formProps); } const form = document.getElementById("form"); form.addEventListener("submit", logSubmit);
Более подробно о том, что за что отвечает, и как именно мы собирали эту форму, вы можете прочитать в одной из наших прошлых статей.
В процессе настройки наша форма будет выглядеть следующим образом:
Рабочий, но не очень эстетичный момент, не так ли? Последний шаг — добавить визуальную составляющую — стиль в CSS.
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; } body { min-height: 100vh; padding: 50px; display: flex; align-items: center; justify-content: center; background-color: #18191c; color: #FFFFFF; font-family: 'Kanit', sans-serif; font-family: 'Roboto', sans-serif; font-size: 18px; } h4 { color: red; margin-bottom: 2vh; } input, textarea{ width: 100%; padding: 12px; margin-bottom: 25px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; resize: vertical; } label { display: flex; align-items: center; justify-content: space-between; margin-bottom: 25px; } .input, .button { width: 350px; } .input { border: 1px solid #ffffff; border-radius: 6px; padding: 10px 15px; background-color: transparent; color: #ffffff; font-family: inherit; font-size: inherit; font-weight: 300; -webkit-appearance: none; appearance: none; } .input:focus { border-color: #FFD829; outline: none; } .button { display: block; min-width: 210px; border: 2px solid transparent; border-radius: 6px; margin-left: auto; padding: 9px 15px; color: #000000; font-size: 18px; font-weight: 300; font-family: inherit; transition: background-color 0.2s linear; } .button:hover { background-color: #FF0032; cursor: pointer; transition: background-color 0.2s linear; } .button:focus-visible { border: 2px solid #ffffff; outline: none; } .button:focus { border: 2px solid #ffffff; outline: none; } .button-yellow { background-color: #FFD829; } .button:disabled { opacity: 0.5; cursor: not-allowed; } .hidden { display:none; } @media (max-width: 768px) { body { padding: 30px; } label { display: block; } .input, .button { display: block; width: 100%; } }
Для того, чтобы получить доступ к форме, нужно вручную запустить сайт — потребуется подключение к Интернету, а также запущенный ранее созданный нами файл. При желании можно «вшить» код в пользовательский интерфейс, а также настроить.
Этап 3. Настройка
Чтобы все работало корректно и не требовало доработок, необходимо дополнительно создать файл настройки с актуализацией версий используемых библиотек:
aiofiles==23.2.1 anyio==4.1.0 beautifulsoup4==4.12.2 blinker==1.7.0 cachetools==5.3.2 certifi==2023.11.17 charset-normalizer==3.3.2 click==8.1.7 Flask==3.0.0 google==3.0.0 google-api-core==2.15.0 google-api-python-client==2.111.0 google-auth==2.25.2 google-auth-httplib2==0.2.0 google-auth-oauthlib==1.2.0 googleapis-common-protos==1.62.0 greenlet==3.0.2 h11==0.14.0 h2==4.1.0 hpack==4.0.0 httpcore==1.0.2 httplib2==0.22.0 httpx==0.25.2 Hypercorn==0.15.0 hyperframe==6.0.1 idna==3.6 itsdangerous==2.1.2 Jinja2==3.1.2 MarkupSafe==2.1.3 oauth2client==4.1.3 oauthlib==3.2.2 priority==2.0.0 protobuf==4.25.1 pyasn1==0.5.1 pyasn1-modules==0.3.0 pyparsing==3.1.1 python-telegram-bot==20.7 Quart==0.19.4 requests==2.31.0 requests-oauthlib==1.3.1 rsa==4.9 six==1.16.0 sniffio==1.3.0 soupsieve==2.5 SQLAlchemy==2.0.17 typing_extensions==4.9.0 uritemplate==4.1.1 urllib3==2.1.0 Werkzeug==3.0.1 wsproto==1.2.0
Для всех желающих оставляем ссылку на готовый код в GitHub с полной сборкой и всеми составляющими.
Работу алгоритма можно представить следующим образом: сотрудник заполняет соответствующую форму (создается автоматически для рабочего интерфейса или с помощью Google Форм), которая передает данные в общую таблицу. Возможно также ручное заполнение — например, если нужно вносить правки в уже созданные заявки.
После этого автоматический алгоритм каждые 20 секунд (возможно увеличить срок до 20 минут, часа и так далее) проверяет, появились ли новые строки. И если они есть, считывает их, отправляя значения в форму отправки. Она, в свою очередь, проверяет корректность ввода и служит для того, чтобы сотрудник мог также самостоятельно вводить и отправлять данные.
Последний шаг — непосредственная работа API Exolve для отправки сообщения на указанный номер телефона. В коде уже прописаны автоматические комментарии к полям («подойдите туда-то»), их можно изменить самостоятельно. Как итог — покупатели получат следующие сообщения:
Мы повторимся, что этот код можно упростить, автоматизировав его и убрав форму — то есть, передавать данные напрямую в API. Но в таком случае исключается возможность ручного воздействия — изменения данных и отправки сообщений «вне очереди».
ссылка на оригинал статьи https://habr.com/ru/articles/842106/
Добавить комментарий