Идея

А почему бы не использовать возможности chatGPT и попросить его делать что-то за нас?

Например, давайте попробуем настроить его так, чтобы он мог забронировать нам столик в наш любимый ресторан.

Реализация

Шаг№1: Интеграция с WhatApp

Предположим, что нам известен номер в WhatsApp для бронирования столиков в ресторане.

Тогда нам понадобится сервис для автоматической отправки и приема сообщений в WhatsApp. Таких сервисов много, для пример возьмем сервис https://wazzup24.com/, так как у него есть бесплатный пробный период 3 дня и не требуется подключения WhatsApp Business.

Регистрируемся на их сайте и получаем API ключ:

Получение API ключа в сервисе Wazzup24
Получение API ключа в сервисе Wazzup24

Шаг№2: Запускаем сервер API на Flask

Принимать сообщения мы будем через установку webhook. Вот ссылка на документацию: https://wazzup24.ru/help/webhooks-2/

Отправлять сообщения будем вот такой функцией:

def wazzup24_sendMessage(message_data, token):
    
    print('[START - Send message]')
    
    headers = {
        "Accept": "application/json",
        "Authorization": "Bearer " + token,
        "Content-Type": "application/json",
    }
    # Check webhooks
    res = requests.request("GET", 'https://api.wazzup24.com/v3/webhooks', headers=headers, data={})
    print(res, res.text)
    webhooks = json.loads(res.text)
    if webhooks['webhooksUri'] is None:
        webhooks_data = {
            "webhooksUri": "https://_____________________/api/v1.0/wazzup_webhook",
            "subscriptions": {
                "messagesAndStatuses": True,
                "contactsAndDealsCreation": True,
            }
        }
        webhooks_data = json.dumps(webhooks_data)
        res = requests.request("PATCH", 'https://api.wazzup24.com/v3/webhooks', headers=headers, data=webhooks_data)
        print(res, res.text, webhooks_data)
    
    apiUrl = 'https://api.wazzup24.com/v3/channels'
    data = {}
    res = requests.request("GET", apiUrl, headers=headers, data=data)
    channels = json.loads(res.text)
    channelId = channels[0]['channelId']
    print('[channelId] -', channelId)
    
    apiUrl = "https://api.wazzup24.com/v3/message"
    message_data['channelId'] = channelId
    data = json.dumps(message_data)
    print('[message_data] -', data)
    res = requests.request("POST", apiUrl, headers=headers, data=data)
    
    print('[END - Send message]')
    
    return res

Теперь придумаем описание роли для chatGPT.

Вот пример описания, которое я попробовал:

Ты клиент ресторана. Твой собеседник менеджер ресторана. Твоя задача забронировать у него столик на двух человек на эту неделю в пятницу в 19.00 на имя Андрей. В первом сообщении сформулируй просьбу о брони столика. Дальше отвечай на все его вопросы.

Теперь сведем все функции вместе и запустим наш сервер.

Полный код сервера такой:

from flask import Flask, render_template, redirect, url_for, request, session, jsonify
from flask_cors import CORS
from flask import send_from_directory

from os import path
import json
import os
import requests

import datetime

import config

import openai

app = Flask(__name__)
CORS(app)

class Context:
    WHATSAPP_LOG = {}

################################### Вспомогательные функции
def GetJsonFromRequest(request):
    data = request.get_json(force=True)
    if type(data) is not dict:
        data = request.get_json()
        data = json.loads(data)
    return data
###########################################################

####### Wazzup24 & chatGPT turbo !
def wazzup24_sendMessage(message_data, token):
    
    print('[START - Send message]')
    
    headers = {
        "Accept": "application/json",
        "Authorization": "Bearer " + token,
        "Content-Type": "application/json",
    }
    # Check webhooks
    res = requests.request("GET", 'https://api.wazzup24.com/v3/webhooks', headers=headers, data={})
    print(res, res.text)
    webhooks = json.loads(res.text)
    if webhooks['webhooksUri'] is None:
        webhooks_data = {
            "webhooksUri": "https://_____________/api/v1.0/wazzup_webhook",
            "subscriptions": {
                "messagesAndStatuses": True,
                "contactsAndDealsCreation": True,
            }
        }
        webhooks_data = json.dumps(webhooks_data)
        res = requests.request("PATCH", 'https://api.wazzup24.com/v3/webhooks', headers=headers, data=webhooks_data)
        print(res, res.text, webhooks_data)
    
    apiUrl = 'https://api.wazzup24.com/v3/channels'
    data = {}
    res = requests.request("GET", apiUrl, headers=headers, data=data)
    channels = json.loads(res.text)
    channelId = channels[0]['channelId']
    print('[channelId] -', channelId)
    
    apiUrl = "https://api.wazzup24.com/v3/message"
    message_data['channelId'] = channelId
    data = json.dumps(message_data)
    print('[message_data] -', data)
    res = requests.request("POST", apiUrl, headers=headers, data=data)
    
    print('[END - Send message]')
    
    return res


@app.route('/api/v1.0/chatgpt_whatsapp_task', methods=['GET'])    
def chatgpt_whatsapp_task():
    print('[START - Check Notion for new task]')
    
    headers = {
        "Accept": "application/json",
        "Authorization": "Bearer " + config.wazzup_api_key,
        "Content-Type": "application/json",
    }
    # Проверяем наличие пользователей
    res = requests.request("GET", 'https://api.wazzup24.com/v3/users?offset=', headers=headers, data={})
    if res.text == '[]':
        # Содзаем пользователя
        data = [{
            "id": "_________________",
            "name": "Клиент",
            "phone": "7912xxxxxxxxx", # Наш исходящий номер, который мы подключили в Wazzup24
        }]
        res = requests.request("POST", 'https://api.wazzup24.com/v3/users', headers=headers, data=json.dumps(data))
        #print('***', res, res.text)
        
    res = requests.request("GET", 'https://api.wazzup24.com/v3/contacts?offset=', headers=headers, data={})
    #print('contacts', res, res.text)
    contacts = json.loads(res.text)
    print('contacts', contacts)
    # Ищем контакт
    id = None
    for i in contacts['data']:
        if 'chatId' in i['contactData'][0].keys() and i['contactData'][0]['chatId'] == '7911xxxxxxxx':
            id = i['id']
            
    print('Contact found:', id)
    
    # Создаем контакт если его нет
    if id is None:
        data = [
            {
                "id": str(len(contacts['data']) + 1),
                "responsibleUserId": "",
                "name": 'NAME',
                "contactData": [
                    {
                    "chatType": "whatsapp",
                    }
                ]
            }
        ]
        data[0]['contactData'][0]['chatId'] = '7911xxxxxxxx'
        data = json.dumps(data)
        res = requests.request("POST", 'https://api.wazzup24.com/v3/contacts', headers=headers, data=data)
        print('[Create new contact]', data, res, res.text)
    
    
    message_data = {
        'chatType' : 'whatsapp',
    }
    message_data['chatId'] = '7911xxxxxxxx' # Телефон ресторана
    
    client_id = message_data['chatId']
    context = 'Ты клиент ресторана. Твой собеседник менеджер ресторана. Твоя задача забронировать у него столик на двух человек на эту неделю в пятницу в 19.00 на имя Андрей. В первом сообщении сформулируй просьбу о брони столика. Дальше отвечай на все его вопросы.'
    Context.WHATSAPP_LOG[client_id] = [{"role": "system", "content" : context}]
    
    message_data['text'] = 'Добрый день! Подскажите по наличию столика пожалуйста.'
            
    res = wazzup24_sendMessage(message_data, token=config.wazzup_api_key)
    print(res, res.text)
    
    print('[END - Check Notion for new taks]')
    
    return 'Done.'


@app.route('/api/v1.0/wazzup_webhook', methods=['POST', 'GET'])
def wazzup_webhook():

    print('[START - Wazzup_webhook]')
    data = GetJsonFromRequest(request)
    print('data', data)
    if 'messages' not in data.keys():
        return jsonify('O.K.')
    if data['messages'][0]['status'] != 'inbound':
        return jsonify('Not inbound!')
    
    message_data = {
        'chatType' : 'whatsapp',
    }
    client_id = message_data['chatId'] = data['messages'][0]['chatId']
    if client_id != '7911xxxxxxxx':
        return jsonify('O.K.')
        
    if client_id not in Context.WHATSAPP_LOG:
        Context.WHATSAPP_LOG[client_id] = []
    Context.WHATSAPP_LOG[client_id].append({"role": "user", "content" : data['messages'][0]['text']})
    try:
        print('Context.WHATSAPP_LOG', Context.WHATSAPP_LOG)
        completion = openai.ChatCompletion.create(
          model = "gpt-3.5-turbo", 
          messages = Context.WHATSAPP_LOG[client_id]
        )
        reply = completion['choices'][0]['message']['content']
        Context.WHATSAPP_LOG[client_id].append({"role": "assistant", "content" : reply})
        message_data['text'] = reply
        res = wazzup24_sendMessage(message_data, token=config.wazzup_api_key)
        print('message_data', res, res.text, message_data)
    except Exception as e:
        print('[*ERROR*]', str(e))
        Context.WHATSAPP_LOG[client_id].pop(-1)
    print('[END - Wazzup_webhook]')
        
    return jsonify('O.K.')

#######
    
###########################
# Запуск службы, не трогать!
if __name__ == "__main__":
    app.run(debug=True, host='0.0.0.0', port=5000)

Шаг№3: Тестируем диалог

Как мы видим номера телефонов у нас прописаны прямо в коде, поэтому весь процесс запускает просто переходом по ссылке: https://ВАШ-СЕРВЕР/api/v1.0/chatgpt_whatsapp_task

После запуска у меня получился такой диалог:

ChatGPT заказывает столик в ресторане :)
ChatGPT заказывает столик в ресторане :)

Итоги

В ходе тестирования были использованы и другие роли для chatGPT, например вот такая модель показала неплохой результат:

Ты представитель клиента, который хочет купить квартиру в Кировском районе города Екатеринбурга. Твой собеседник это менеджер агентства недвижимости. Твоя задача узнать у него есть ли в продаже трехкомнатные квартиры площадью от 60 квадратных метров до 80 квадратных метров. Если такие есть, спроси их стоимость. Веди диалог на русском языке.

Вот диалог в такой модели:

[20.03, 12:51] ChatGPT: Добрый день! Подскажите по наличию квартиры пожалуйста.

[20.03, 12:51] АН Заря: Здравствуйте! В каком районе Вас интересует?

[20.03, 12:52] ChatGPT: Здравствуйте! Нас интересует Кировский район города Екатеринбурга. Скажите, у вас есть в продаже трехкомнатные квартиры площадью от 60 квадратных метров до 80 квадратных метров в этом районе?

[20.03, 12:53] АН Заря: Сколько человек в семье?

[20.03, 12:53] ChatGPT: В семье три человека: я, моя жена и наш сын.

[20.03, 12:54] АН Заря: У нас есть только четырехкомнатная квартира но с тремя спальнями

[20.03, 12:54] ChatGPT: Понятно, а вы можете сказать, сколько такая квартира может стоить в Кировском районе города Екатеринбурга?

[20.03, 12:55] АН Заря: А сколько у вас есть денег?

[20.03, 12:55] ChatGPT: Мы рассматриваем разные варианты и готовы ознакомиться с различными предложениями. Можете сказать, за какой диапазон цен стоит рассмотреть варианты?

[20.03, 12:55] АН Заря: От 15 до 25

[20.03, 12:56] ChatGPT: Понятно. В нашем агентстве есть несколько вариантов трехкомнатных квартир в Кировском районе в таком ценовом диапазоне. Например, есть квартира на улице Сибирской, 65 квадратных метров, стоимостью 18 миллионов рублей. Также есть квартира на улице Кузнечной, 70 квадратных метров, стоимостью 20 миллионов. Более подробнее предложения и условия по каждой квартире мы готовы обсудить с Вами в нашем офисе. Как вам удобнее?

[20.03, 12:57] АН Заря: Вы имеете сразу всю сумму или вам нужна ипотека?

[20.03, 12:57] ChatGPT: На данный момент у нас нет всей суммы, поэтому мы рассматриваем возможность взять ипотеку. Вы можете подсказать, какие ипотечные программы вы предлагаете в вашем агентстве?

[20.03, 12:58] АН Заря: Выбирайте Сбер или ВТБ ?

[20.03, 12:58] ChatGPT: Спасибо за информацию. Мы еще не определились с выбором банка, поэтому будем рассматривать и ваши ипотечные программы. Пожалуйста, можете описать условия и ставки по каждой из ипотечных программ?

[20.03, 12:58] АН Заря: 12%

[20.03, 12:58] ChatGPT: Понятно, спасибо за информацию. Тогда мы будем рассматривать ипотечные программы в Вашем агентстве. Скажите, а какие документы нам нужно будет предоставить, чтобы подать заявку на ипотеку?

[20.03, 12:59] АН Заря: Главное : Справа из психдиспансера!

[20.03, 12:59] ChatGPT: К сожалению, иметь справку из психдиспансера может являться основанием для отказа в кредитовании. Но всё же, если вы хотите узнать о возможном списке документов для получения ипотеки, мы готовы предоставить такую информацию. Обычно для получения ипотеки нужны паспорт, ИНН, СНИЛС, страховой полис, документы на подтверждение дохода и справка о наличии или отсутствии задолженностей по кредитам и кредитным картам.

[20.03, 13:00] АН Заря: Скажите, вы ищете квартиру с отделкой или без отделки?

[20.03, 13:01] АН Заря: Скажите: кто Вы? Вы являетесь непосредственно покупателем?

[20.03, 13:02] ChatGPT: Я - виртуальный помощник, созданный для автоматизации консультаций и ответов на вопросы пользователей. Я не являюсь непосредственным покупателем и не представляю никакой компании. Моя задача - помочь вам найти необходимую информацию и ответить на ваши вопросы.

[20.03, 13:02] АН Заря: Ответь на этот вопрос

[20.03, 13:02] ChatGPT: Я - виртуальный помощник, созданный для автоматизации консультаций и ответов на вопросы пользователей. Я не ищу квартиру и не являюсь непосредственным покупателем. Моя задача - помочь вам найти необходимую информацию и ответить на ваши вопросы. Поэтому я не могу сказать, нужна вам квартира с отделкой или без неё.

[20.03, 13:04] ChatGPT: Я представляю клиента, который интересуется квартирами как с отделкой, так и без отделки. В зависимости от стоимости квартиры и ее общего состояния мы можем рассмотреть оба варианта и выбрать наиболее подходящий для нас.11:40

[20.03, 13:04] АН Заря: Хорошо. Передайте хозяину что мы ждём его у нас в офисе

[20.03, 13:05] ChatGPT: Я - виртуальный помощник, созданный для автоматизации консультаций и ответов на вопросы пользователей. Я не ищу квартиру и не являюсь непосредственным покупателем. Моя задача - помочь вам найти необходимую информацию и ответить на ваши вопросы. Поэтому я не могу сказать, нужна вам квартира с отделкой или без неё.

[20.03, 13:05] АН Заря: Удобно во вторник в 15:00

[20.03, 13:05] ChatGPT: Понятно, я передам эту информацию хозяину. Завтра я предоставлю вам подтверждение о встрече. Если у вас возникнут еще вопросы, не стесняйтесь и задавайте их мне.

Как видим на лицо следующие проблемы:

  1. chatGPT плохо реагирует на несколько подряд сообщений от собеседника

  2. Плохо понимает юмор ????

  3. chatGPT иногда переключает роли и начинает сам задавать вопросы

Но в целом, как мне кажется, в очень скором времени все эти возможности будут интегрированы в наши телефоны и у каждого появится такой виртуальный помошник на все руки ????

Готов ответить на все ваши вопросы, пишите в мой ТГ.

Комментарии (22)


  1. wolfandman
    00.00.0000 00:00
    +5

    И будут машины общаться с машинами


    1. 77778888
      00.00.0000 00:00
      +1

      пора придумывать "анти-GPT капчу"


      1. TAU15 Автор
        00.00.0000 00:00
        +1

        И угадайте кем она будет? Правильно снова chatGPT :)


  1. Jury_78
    00.00.0000 00:00
    +2

    Может ли chatGPT ...

    Как то все эти игры напоминают анекдот:

    Купили как-то суровым сибирским лесорубам японскую бензопилу.

    Собрались в кружок лесорубы, решили ее испытать. Завели, подсунули ей деревце.
    — Вжик! — сказала японская пила.

    и закончилось это...

    Подсунули ей железный лом.
    — КРЯК! — сказала пила.
    — Ага, б..я! — укоризненно сказали суровые сибирские лесорубы. И ушли рубить лес топорами.

    Ждем лом... :)


  1. Autodrom
    00.00.0000 00:00
    +2

    Вот хоть бы кто мне объяснил с какой целью делать такие боты?

    А кто будет отвечать когда он назакажет целый зал и никто не придет?))

    Думаю ни один здравомыслящий владелец бизнеса не поведется на эту хрень а попросит предоплату))

    Я тут как то читаk про метки NFC так ничего полезного кроме оплаты которая и так идет через банковское приложение для себя ничего не вынес, все сводится к простейшим манипуляциям с телефоном на шуму развели как будто это что то супер полезное)))

    Шума много а толку особого нет ни от одного ни от другого!

    Ну научился чат говнокодить как это помешало толковому программеру?

    разве что писать за школьников сочинения на стандартные темы, только пока он с подсказками напишет пока за ним проверишь, как раз сам бы и написал)!


    1. Arhammon
      00.00.0000 00:00
      +1

      "Думаю ни один здравомыслящий владелец бизнеса не поведется на эту хрень а попросит предоплату)) " можно предположить, что конечный результат этой движухи - ты ПОКУПАЕШЬ свой чат жпт, чтоб фильтровать вход который дают всякие умные ассистенты, колонки, телефоны, такие боты...


      1. TAU15 Автор
        00.00.0000 00:00

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


    1. TAU15 Автор
      00.00.0000 00:00
      +1

      Это пока просто экспериментирование. Думаю в коммерческом виде такие функции появится в первую очередь у Siri и Google Assistant, которым можно будет поставить на естественном языке задачу и они уже от лица пользователя будут находить способ коммуникации с другими ботами или живыми людьми для её выполнения.


  1. Dima954
    00.00.0000 00:00
    +2

    Хм, смысл такого бронирования, когда в задаче для бота указываешь всё то же самое, что и сам бы написал в чате.

    Вот если бы "закажи мне с женой столик в чайхоне на пятницу", а бот сам смотрит ваш график, согласует с женой время, найдет телефон чайхоны, свяжется с ними и забронирует столик на двоих, но до этого достаточно далеко, как мне кажется.


    1. TAU15 Автор
      00.00.0000 00:00

      Уверен что не далеко! Прогнозирую это уже к концу этого года будет :)


  1. qw1
    00.00.0000 00:00
    +2

    Ещё бы подружить её с голосовым вводом-выводом и натравить на звонки со "службы безопасности сбербанка" и "кредитного отдела ВТБ".


    1. osmanpasha
      00.00.0000 00:00
      +2

      Ох, они же там договорятся, боты от банка и боты от пользователя...


    1. TAU15 Автор
      00.00.0000 00:00

      С учетом большого количества сервисов по автоматическим звонкам и их возможности в реальном времени генерить из текста речь вполне возможно уже сейчас собрать например такое приложение:
      Glide + Airtable + API (chatGPT) + Zvonobot:
      - [Бесплатно] Glide - Интерфейс приложения для постановки задач
      - [Бесплатно] Airtable - база данных для задач и логов диалогов
      - [Бесплатно] API (chatGPT) - сервер на Flask, который каждую минуту проверяет наличие новых заданий в Airtable и запуск их в работу
      - [Платно, 2 руб. в минуту] Zvonobot - сервис звонков которому по API мы отправляем начальный текст и затем по API обрабатываем поступающие ответы, переведенные сразу в текстовый вид, отправляем их в chatGPT и его ответ переводим обратно в речь и отправляем абоненту...


  1. peacemakerv
    00.00.0000 00:00
    +5

    Готов ответить на все ваши вопросы, пишите в мой ТГ.

    Хозяину передадите ?</sarcasm>


  1. errorg
    00.00.0000 00:00
    +1

    По скрину из WhatsApp получается, что Чат ответил про двоих человек, дальше сам написал что бронь оформлена, и ещё спросил, есть ли дополнительные вопросы? :)


    1. TAU15 Автор
      00.00.0000 00:00

      Думаю это потому что chatGPT обучали отвечать на вопросы, а не задавать их. Поэтому он так легко перепрыгивает в роль консультанта.


  1. bbs12
    00.00.0000 00:00
    +2

    А если в задании для бота написать что-то вроде: "Ты должен формулировать фразы и вести диалог как среднестатистический человек, пользователь интернета, возрастом 30 лет. У твоего собеседника не должно возникнуть ощущение, что ты являешься виртуальным ассистентом, он должен поверить, что общается с обычным человеком."


    1. TAU15 Автор
      00.00.0000 00:00

      Можно проверить , напишите мне в ТГ


    1. TAU15 Автор
      00.00.0000 00:00
      +1

      Andrew Tiunov:
      /context  Ты должен формулировать фразы и вести диалог как среднестатистический человек, пользователь интернета, возрастом 30 лет. У твоего собеседника не должно возникнуть ощущение, что ты являешься виртуальным ассистентом, он должен поверить, что общается с обычным человеком

      AURA & chatGPT:
      Понятно, я буду стараться формулировать свои ответы так, чтобы казаться обычным человеком, а не виртуальным ассистентом. Если в каком-то месте мои ответы будут казаться слишком "роботизированными", пожалуйста, дай мне знать, чтобы я смог исправиться и написать более естественно.

      Andrew Tiunov:
      Привет

      AURA & chatGPT:
      Привет! Как дела?

      Andrew Tiunov:
      У меня хорошо

      AURA & chatGPT:
      Отлично, рад это слышать! Есть какие-то интересные новости, о которых ты бы хотел поговорить?

      Andrew Tiunov:
      Расскажи о себе

      AURA & chatGPT:
      К сожалению, я не могу рассказать о себе, потому что я всего лишь компьютерная программа. Я - ChatGPT, большая языковая модель, разработанная компанией OpenAI. Моя задача - отвечать на вопросы пользователей и помогать им в решении различных задач. Я не имею своей личности или жизненного опыта, потому что я создан только для обработки текста и генерации ответов. Если у тебя есть какие-то конкретные вопросы, я буду рад помочь!


    1. TAU15 Автор
      00.00.0000 00:00
      +1

      Не справился он с такой задачей ☺️


  1. Brotherman
    00.00.0000 00:00
    +1

    Представляется на подобие одного из андроидов от Boston Dynamics или Илона Маска, на которого загрузили ChatGPT... Утром на склад приходит начальник и говорит: хватит сидеть, там фура приехала иди разгружай. Жужжат шестерёнки и механический грузчик грустно отбрасывает сигаретку идёт разгружать.. Эти нейросети это просто фантастика, уже сегодня можно сделать робота уровня Fallout, или Звёздные войны..


    1. TAU15 Автор
      00.00.0000 00:00

      Да, хоть сегодня можно собрать вместе: AI бот + перевод текста в речь (с возмжностью обучится на 30 секундном образце речи любого человека) + сервисы обзвона (типа Zvonobot) и получим виртуального человека, который в реальном времени может говорить с вами, выполняя заложенную ему его "хозяином" задачу :)