Рубрики
Без рубрики

Автоматизируйте вознаграждения клиентов, используя Python, PostgreSQL и Africas Talking

Некоторое время назад меня, и друг (кричал Ньямбуре для этой удивительной идеи) говорили о … Tagged с Python, Tuperial, Postgres, Africastalking.

Некоторое время назад меня и друг (кричал Ньямбуре за эту удивительную идею) говорили о программах по вознаграждении клиентов и рекламных акциях. Обсуждение было в основном о том, как в настоящее время организации, как правило, делают вещи вручную, но в большинстве случаев уже есть какая -то цифровая система с бэкэнд базы данных, хранящей все их записи.

В этой статье мы будем частью маркетинговой команды нашей вымышленной цепочки Зоопарк супермаркеты. Нам поручено запустить программу вознаграждений клиентов, чтобы отпраздновать нашу 1 -летнюю годовщину. В частности, мы принимаем на себя задачу присуждения эфирного времени нашим клиентам, которые будут делать покупки выше определенной суммы в течение юбилейного периода.

Есть несколько проприетарных вариантов, включая аутсорсинг этой задачи, провайдеру 3-й стороны. Однако в Зоопарк Мы считаем себя франшизой «цифровой», поэтому мы решаем разработать собственное решение. Предполагается, что у нас есть система POS с бэкэнд базы данных PostgreSQL. Мы решили использовать Python в качестве нашего выбора и Потрясающий Африканское эфирное время API

Готовиться

Чтобы следить за этим постом и кодировать те же функции. Вам понадобится несколько вещей:

  • Python и PIP (в настоящее время я использую 3.9.2) Любая версия выше 3.5 должна работать.
  • А Африканский рассказ о разговоре Анкет

    • API -ключ и имя пользователя из вашей учетной записи. Создайте приложение и обратите внимание на ключ API.
      • Кроме того, вам нужно будет запросить их, чтобы включить доступ в эфирное время для вашей учетной записи. Напишите их команде Airtime для дальнейшего разъяснения

    Как только вы отсортировали выше:

    • Создайте новый каталог и измените его.

      • Создайте новую виртуальную среду для проекта или активируйте предыдущую.
      • Используя диспетчер пакетов Python (PIP), установка: Africastalking Python SDK, библиотеки Python-Dotenv, SQLachemy, Psycopg2 и Sqlachemy-Utils Libraries.
      • Сохраните установленные библиотеки в файле Teletine.txt

Как упоминалось выше, мы используем PostgreSQL в качестве нашей базы данных по выбору, поэтому нам нужна библиотека для взаимодействия с базой данных, PSYCOPG2 является хорошим вариантом, хотя есть и другие. Хотя мы не обязательно будем использовать SQLALCHEMY как наш объект отношения Mapper (ORM). Это позволяет нам использовать объекты Python (классы, функции) для совершения транзакций вместо необработанного SQL.

Установить Postgresql База данных для моделирования бэкэнда с деталями клиента. В зависимости от того, на какой платформе вы кодируете, вы можете сделать это изначально в своей системе. Лично я использую Docker Поскольку легко управлять контейнерами и предотвратить загроможден мою систему. Это Статья это потрясающий ресурс о том, как установить PostgreSQL и PGADMIN4 в качестве контейнеров. Также вы можете использовать инструмент администрирования базы данных, такой как PGADMIN4 или Dbeaver для пользовательского интерфейса для взаимодействия с Postgres Server.

В качестве альтернативы, проверьте готовый код на GitHub

Конфигурация в течение нескольких дней

Согласно нашему текущему предположению, у нас есть база данных данных о клиентах и в производстве, которые определенно должны иметь место с резервными копиями. Однако для этой витрины мы создадим примерную базу данных и таблицы. Это облегчит объяснение потока программы.

Этот шаг совершенно необязательно, вы можете так же легко создать DB вручную, используя клиент базы данных, такой как Dbeaver . Однако использование кода является оптимальным маршрутом. Давайте создадим .env Файл, чтобы удерживать все переменные нашей среды, которые мы не хотим раскрывать всем. Введите следующее изменение заполнителей с соответствующими полномочиями.

    touch .env
# .env 
postgres_db=enter your database here
postgres_host=localhost
postgres_port=5432
postgres_user=enter postgres_user
postgres_password=enter postgres_user password
at_username=enter your at_username
at_api_key=enter your api_key
phone_number=07xxxxxxxx

Мы создадим config.py Файл для удержания всех наших конфигураций. В нашем файле конфигурации давайте импортируем все наши необходимые библиотеки.

    #config.py
from sqlalchemy import create_engine, MetaData
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
import os
from dotenv import load_dotenv

Блок кода выше:

  1. Импортирует функцию Create_Engine для подключения к базе данных, а также объекту метаданных.
  2. Затем мы импортируем заводскую функцию Declarative_base, которая строит базовый класс для определений декларативного класса.
  3. Мы переходим к импорту класса SessionMaker, который обычно используется для создания конфигурации сеанса верхнего уровня, которая затем может использоваться во всем приложении без необходимости повторить аргументы конфигурации.
  4. Мы импортируем OS LIB, чтобы обеспечить доступ к переменным среды.
  5. Мы также импортируем функцию LOAD_DOTENV для загрузки значений из нашего .env файл.
    # config.py 
load_dotenv()
db = os.getenv('postgres_db')
db_host = os.getenv('postgres_host')
db_port = os.getenv('postgres_port')
db_user = os.getenv('postgres_user')
db_password = os.getenv('postgres_password')

Приведенный выше блок кода использует функцию LOAD_DOTENV, чтобы получить значения из нашего .env файл. Мы приступаем к созданию переменных для удержания наших конкретных значений среды.

Теперь мы перейдем к конкретной конфигурации базы данных. Код ниже:

  • Создает экземпляр функции Create_Engine, передающего необходимые параметры по отношению к DB.
  • Мы также создаем экземпляры функций метаданных, декларативных и сеансов для использования в нашей программе.
# config.py
engine = create_engine(f"postgresql+psycopg2://{db_user}:{db_password}@{db_host}:{db_port}/{db}", echo=True)
meta = MetaData()
Base = declarative_base()
Session = sessionmaker(bind=engine, autoflush=True)
session = Session()

Больше клиентов больше данных

Создайте новый сценарий Python с именем database_insert.py Это будет держать весь код для вставки данных для наших клиентов и транзакций продаж. Здесь мы определим, как наши данные будут храниться в нашей базе данных, это также будет служить хорошему праймеру при использовании операций SQLachemy для CRUD (Create Read Update Delete).

Внутри Database_insert.py Добавьте следующий код:

# database_insert.py
from sqlalchemy import Column, Integer, String, Unicode, ForeignKey, DateTime
import sqlalchemy as sa
from sqlalchemy_utils import PhoneNumber
import datetime as dt
import os
from dotenv import load_dotenv
from config import engine, Base, session

Приведенный выше код импортирует все наши необходимые библиотеки и предварительно определенную конфигурацию от config.py Для использования при доступе к нашей базе данных.

Теперь мы приступим к определению наших классов о том, как будут сохранены данные.

# database_insert.py

phone_number = '07XXXXXXXX'


class Customers(Base):
    __tablename__ = 'customers'
    customer_id = Column(Integer, primary_key=True)
    customer_first_name = Column(String)
    customer_last_name = Column(String)
    _phonenumber = Column(Unicode(20))
    country_code = Column(Unicode(8))
    phone_number = sa.orm.composite(
        PhoneNumber, _phonenumber, country_code
    )


class Sales_Transaction(Base):
    __tablename__ = 'sales_transaction'
    transaction_id = Column(Integer, autoincrement=True, primary_key=True)
    customer_id = Column(Integer, ForeignKey("customers.customer_id"))
    transaction_price = Column(Integer)
    transaction_date = Column(DateTime(timezone='EAT'))

В приведенном выше фрагменте мы создаем два класса: Клиенты и транзакция по продажам, которые наследуют от базового класса от SQLalchemy. Это позволяет нам легко сопоставить наши модели в наши таблицы. Если вам нужна дополнительная информация, Документация Обеспечивает отличное глубокое погружение.

# database_insert.py 
Base.metadata.create_all(engine)

temp = Customers(phone_number=PhoneNumber(f'{phone_number}', 'KE'))
c1 = Customers(customer_id=2, customer_first_name='babygirl',
               customer_last_name='nyambura', _phonenumber=temp.phone_number.e164)
c2 = Customers(customer_id=3, customer_first_name='zoo',
               customer_last_name='mwaura',
               _phonenumber=temp.phone_number.e164)
s2 = Sales_Transaction(customer_id=c1.customer_id,
                       transaction_price=5000, transaction_date=dt.date(2021, 4, 12))
s3 = Sales_Transaction(customer_id=c2.customer_id, transaction_price=2700,
                       transaction_date=dt.date(2021, 4, 15))

try:
    session.add_all([c1, c2])
    session.add_all([s2, s3])
    session.commit()
except Exception as e:
    print(f"We have a problem Houston: {e}")

session.close()

Приведенный выше фрагмент использует базовый класс для создания всех наших таблиц, как указано в наших классах. Мы приступаем к созданию темп переменная для удержания нашего неформатированного номера телефона. Мы используем функцию phonenermeman из sqlachemy_utils Библиотека, чтобы установить правильный тип нашего Phone_number. Затем мы добавляем переменные для вставки тестовых данных в базу данных. Данные, представленные для тестовых целей, используйте свои собственные по мере необходимости. Мы создали поле иностранного ключа в нашей таблице транзакций продаж, чтобы иметь связь между таблицей наших клиентов и таблицей продаж. Каждая транзакция должна иметь идентификатор клиента, чтобы легко определить, какой клиент создан какую транзакцию.

База данных должна напоминать диаграмму ниже:

Поиск начинается!

В этом разделе мы напишем запросы против нашей базы данных для клиентов, которых мы впоследствии вознаграждаем. Однако большую часть времени вам придется делать это в нативном коде SQL, однако у нас есть ORM, поэтому мы будем писать код Python, чтобы запросить нашу базу данных.

Внутри нашей рабочей папки создайте файл Python с именем customer_search.py Анкет Этот файл Так же, как подразумевает имя, будет использоваться для запроса данных наших клиентов. Нашей первоначальной задачей было вознаграждение клиентов в течение нашего юбилейного периода, которые совершили покупки выше определенной суммы. Мы установим наш период покупок до 12 марта 2021 года по 19 марта 2021 года, а покупки – равные и выше KES 2500.

# customer_search.py

from datetime import date
from config import session
from database_insert import Customers, Sales_Transaction

class CustomerQuery:
    def customer_query():
        start_dt = date(2021, 4, 12)
        end_dt = date(2021, 4, 19)
        print(start_dt)
        sq = session.query(
            Sales_Transaction.transaction_price, Customers.customer_first_name,
            Customers.customer_last_name, Customers.phone_number).
        join(Customers)
    customer_data = []
    for a, b, c, d in sq.filter(Sales_Transaction.transaction_price > 2500)
        .filter(Sales_Transaction.transaction_date >= start_dt)
        .filter(Sales_Transaction.transaction_date <= end_dt):
    cl = [a, b, c, d.e164]

    customer_data.extend([cl])

return customer_data


print(CustomerQuery.customer_query())

В нашем кодовом блоке выше мы импортируем дату из библиотеки DateTime, мы также получаем сеанс Наш файл конфигурации. Мы также получаем классы клиентов и Sales_transaction от Database_insert.py . Мы создаем класс CustomerQuery, определяем customer_query Функция, чтобы держать все наши запросы. Мы определяем начало ( start_dt ) и end ( end_dt ) Дата переменные, чтобы указать период между между ними (годовщина).

Затем мы создаем запрос ( sq ) на нашем сеансе. Мы запрашиваем класс Sales_transaction и класс клиентов, затем создаем пустой список клиентов_дата, который добавляем наши результаты запроса. Поскольку мы преобразовали наш класс Phone_Number в PhonNembumber, мы можем легко попасть в формат E.164, как того требует Africastalking, позвонив в .e164 метод Затем мы возвращаем наш customer_data список, содержащий все наши необходимые данные.

Каждый получает награду!

Наконец, мы можем вознаградить наших уважаемых покупателей! Создайте файл customer_rewards.py .

Внутри файла добавьте следующий код:

# customer_rewards.py 

import africastalking as at
from dotenv import load_dotenv
import os

from customer_search import CustomerQuery

load_dotenv()
# get the environment values from the .env file
at_username = os.getenv('at_username')
at_api_key = os.getenv('at_api_key')

at.initialize(at_username, at_api_key)
airtime = at.Airtime
account = at.Application

print(account.fetch_application_data())

def customer_rewards():
    # Set The 3-Letter ISO currency code and the amount
    amount = "250"
    currency_code = "KES"
    for n in CustomerQuery.customer_query():
        print(n[1], n[2], n[-1])
        numbers.append(n[-1])
    print(numbers)
    for number in numbers:
        try:
            response = airtime.send(phone_number=number, amount=amount, currency_code=currency_code)
            print(response)
        except Exception as e:
            print(f"Encountered an error while sending airtime. More error details below\n {e}")

customer_rewards()

В приведенном выше блоке мы импортируем Африканскую библиотеку Python, а также функцию Load_dotenv, чтобы заставить наши Африки говорить об учетных данных. Мы приступаем к назначению переменных нашему ключу API и имени пользователя, затем инициализируем клиента Африки, передавая наши ценности в качестве аргументов. Затем мы назначаем класс эфирного времени переменной, а также с учетной записью. Мы получаем наш текущий баланс учетной записи, используя account.fetch_application_data () функция

Мы определяем функцию customer_rewards, внутри функции мы устанавливаем сумму, переменные кода валюты. Они будут иметь наше количество эфирного времени и трехзначный код ISO, требуемый для разговоров Африки. Читать дальше в Документация Анкет Мы пробираемся через данные клиента и получаем вознаграждение каждого номера. Затем мы вставляем блок Try-Catch, затем мы пытаемся отправить эфирное время каждому клиенту, используя Airtime.send функция Затем мы называем наш customer_rewards () функция Если все прошло хорошо, ваши клиенты должны получить эфирное время. Вуаля! Мы успешно разработали автоматический метод для эффективного и быстрого вознаграждения наших постоянных клиентов. Конечно, есть место для улучшения:

  1. Добавление журнала для отслеживания награжденных клиентов.
  2. Подключение к приложению фронта, чтобы визуализировать общее количество отправленного эфирного времени. В качестве альтернативы создание API вокруг программы вознаграждений.

Но это был скорее демонстрационный проект, чтобы проиллюстрировать жизнеспособность идеи. Одной из особенностей, которую я обнаружил удивительной, было то, что API, говорящие по эфирным времени в Африке, возвращают ошибку всякий раз, когда я отправлял эфирное время на одно и то же число более одного раза в течение 5 минут. Это было бы спасит жизнь, если у вас есть многочисленные клиенты для вознаграждения, это предотвратит двойные или тройные вознаграждения без какого-либо дополнительного кода с нашей стороны.

Если у вас есть какие -либо вопросы или комментарии. Дайте мне знать в комментариях или на Twitter Анкет Счастливого кодирования.

PS: массивный крик Энтони лимузин , Энн из Африки, говорящая эфирное время и по расширению команды эфирного времени. Процесс адаптации и KYC были быстрыми и безболезненными.

Оригинал: “https://dev.to/ken_mwaura1/automate-customer-rewards-using-python-postgresql-and-africas-talking-9dj”