Comience a ganar dinero con el software: creando mini-digital-business



Sentado en forma independiente, vi muchas veces la tarea de recopilar la base de datos. La mayoría de las veces solicitan recopilar información sobre empresas o solicitudes específicas en Google, mapas Yandex.

Hay una demanda, creemos ofertas, pero primero lo primero.

En este artículo, propongo desarrollar un bot de Telegram que tome el nombre de la ciudad (en la que se realizará la búsqueda) y la solicitud (por la cual se realizará la búsqueda.

Por ejemplo: Bar, Café, Restaurante, etc.). Aprovechamos la oportunidad de hacer una donación, pagar el servicio de recopilación de la base de datos y enviarla a los clientes por correo electrónico.

Tecnologías utilizadas:

  1. API de Telegram;
  2. Yandex API;
  3. Pagos API.

Estas tecnologías o herramientas se seleccionan por su facilidad de uso, la capacidad de implementar y automatizar tareas rápidamente.
Este programa no es comercial. Implementado como ejemplo, como Las reglas de Yandex prohíben guardar datos
Lo mismo puede decirse de las reglas que de las leyes: su multiplicidad se demuestra no tanto por el cumplimiento como por la violación de ellas. © Dube

Formación


Para mayor comodidad, dividimos el proyecto en 3 archivos. Crea bot.py , yandex.py , send_email.py .

Implementación


Yandex.py
  • :

    # -*- coding: utf-8 -*-
    import requests
    import xlwt, xlrd
    from xlutils.copy import copy as xlcopy

  • Yandex API , . maps api location api .
    api :
    apikey = '*******-***-****-****-************'
    apikey_location = '********-****-****-****-************'

  • - :
    def sum_taken_object(all_informations):
        try:
            found = str(all_informations['properties']['ResponseMetaData']['SearchResponse']['found'])
        except KeyError:
            found = '-'
        return found

  • :
    def get_all_infomations(text, city):
        value_low_upp, point = get_location(city)
        low = value_low_upp[0].split(',')
        upp = value_low_upp[1].split(',')
        informations = requests.get('https://search-maps.yandex.ru/v1/?'
                                    'apikey='+apikey+'&'
                                    'text='+text+'&'
                                    'lang=ru_RU&'
                                    'll='+point[0]+'&'
                                    'bbox='+low[1]+','+low[0]+'~'+upp[1]+','+upp[0]+'&'
                                    'results=500')
        return informations.json()
    requests.get bbox , ll . ll bbox, . .
    , 500 .
    - 500, . .

  • :

    def get_location(city):
        location = requests.get('https://geocode-maps.yandex.ru/1.x/?'
                                'apikey='+apikey_location+'&'
                                'geocode='+city.title()+'&'
                                'format=json')
        loc = location.json()
        loc = loc['response']['GeoObjectCollection']['featureMember']
        point = loc[0]['GeoObject']['Point']['pos'].split()
        value_lower = loc[0]['GeoObject']['boundedBy']['Envelope']['lowerCorner'].split()
        value_upper = loc[0]['GeoObject']['boundedBy']['Envelope']['upperCorner'].split()
        value_low_upp = [value_lower[1]+','+value_lower[0], value_upper[1]+','+value_upper[0]]
        return value_low_upp, point
    .
  • - :

    def get_information_limit(text,city):
        value_low_upp, point = get_location(city)
        low = value_low_upp[0].split(',')
        upp = value_low_upp[1].split(',')
        info = requests.get('https://search-maps.yandex.ru/v1/?'
                            'apikey='+apikey+'&'
                            'text='+text+'&'
                            'lang=ru_RU&'
                            'll='+point[0]+'&'
                            'bbox='+low[1]+','+low[0]+'~'+upp[1]+','+upp[0]+'&'
                            'results=5&'
                            'skip=5')
        information = info.json()
        information = information['features']
        list = {}
        i = 1
        for key in information:
            try:
                coordinates = str(key['geometry']['coordinates'])
            except KeyError:
                coordinates = '-'
            try:
                name = str(key['properties']['CompanyMetaData']['name'])
            except KeyError:
                name = '-'
            try:
                address = str(key['properties']['CompanyMetaData']['address'])
            except KeyError:
                address = '-'
            try:
                url = str(key['properties']['CompanyMetaData']['url'])
            except KeyError:
                url = '-'
            try:
                phones = key['properties']['CompanyMetaData']['Phones']
            except KeyError:
                phones = '-'
            try:
                hours = str(key['properties']['CompanyMetaData']['Hours']['text'])
            except KeyError:
                hours = '-'
    
            for k in phones:
                try:
                    phones = k['formatted']
                except TypeError:
                    pass
    
            list['object'+str(i)] = {'coordinates':coordinates,'name':name,'address':address,'url':url,'phones':phones,'hours':hours}
            i += 1
        return list
    5 . - , resul, skip requests.get.
  • Excel :

    def write_exl(text, city_name):
        try:
            name_excel_BD = creat_excel_file(name='{}_{}'.format(text, city_name))
            read_book = xlrd.open_workbook(name_excel_BD)  #   
            write_book = xlcopy(read_book)  #    ,      
            write_sheet = write_book.get_sheet(0)  #     
            # index = read_book.sheet_by_index(0).nrows #   
            url_maps = 'https://yandex.ru/maps/org/'
            info = get_all_infomations(text=text, city=city_name)
    
            for number, inf in enumerate(info['features']):
                try:
                    name_object = inf['properties']['CompanyMetaData']['name']
                except KeyError:
                    name_object = '-'
                try:
                    address = inf['properties']['CompanyMetaData']['address']
                except KeyError:
                    address = '-'
                try:
                    time_work = inf['properties']['CompanyMetaData']['Hours']['text']
                except KeyError:
                    time_work = '-'
                try:
                    id_organization = inf['properties']['CompanyMetaData']['id']
                except KeyError:
                    id_organization = '-'
    
                write_sheet.write(int(number), 0, city_name)  # 
                write_sheet.write(int(number), 1, name_object)  #  
                write_sheet.write(int(number), 2, address)  # 
                write_sheet.write(int(number), 3, time_work)  #  
                write_sheet.write(int(number), 4, url_maps + str(id_organization))  # Url  
            write_book.save(name_excel_BD)  #  
            return True, name_excel_BD
        except TypeError or KeyError as err:
            return False

  • Excel:

    def creat_excel_file(name):
        book = xlwt.Workbook('utf8')
        book.add_sheet('_{}'.format(name))
        book.save('BD_{}.xls'.format(name))
        return 'BD_{}.xls'.format(name)



Send_email.py
  • :

    #!/usr/bin/env python
    #   coding: utf8
    
    from smtplib import SMTP_SSL
    from email.mime.multipart import MIMEMultipart
    from email.mime.base import MIMEBase
    from email import encoders
    import os

  • :

    def send_mail(name_file, to_address):
        filepath = name_file
        address_from = "********@gmail.com"
        address_to = to_address
        password = '************'
        mail_adr = 'smtp.gmail.com'
        mail_port = 465
    
        # Compose attachment
        part = MIMEBase('application', "octet-stream")
        part.set_payload(open(filepath, "rb").read())
        encoders.encode_base64(part)
        part.add_header('Content-Disposition', "attachment", filename="%s" % os.path.basename(filepath))
    
        # Compose message
        msg = MIMEMultipart()
        msg['From'] = address_from
        msg['To'] = address_to
        msg.attach(part)
    
        # Send mail
        smtp = SMTP_SSL(mail_adr)
        smtp.set_debuglevel(1)
        smtp.connect(host=mail_adr, port=mail_port)
        smtp.login(address_from, password)
        smtp.sendmail(address_from, address_to, msg.as_string())
        smtp.quit()
    Gmail, Google – « , » , Gmail.


Bot.py
  • :

    # -*- coding: utf-8 -*-
    import telebot
    from telebot.types import LabeledPrice
    import re
    
    import yandex
    from send_email import send_mail

  • token :

    token = '*********:**********************************'
    bot = telebot.TeleBot(token)

  • :

    @bot.message_handler(commands=['start', 'donation'])
    def send_welcom(message):
        if message.text == '/start':
            keyboard = telebot.types.InlineKeyboardMarkup()
            keyboard.row(telebot.types.InlineKeyboardButton(' ', callback_data='bd_get'))
            bot.send_message(message.chat.id, ' : ', reply_markup=keyboard)
    
        if message.text == '/donation':
            bot.send_invoice(message.chat.id,
                             title='Donation',
                             description='   .',
                             invoice_payload='donation',
                             provider_token='*********:TEST:*******',
                             currency='RUB',
                             prices=[LabeledPrice(label='Donation', amount=10000)],
                             start_parameter='pay_start',
                             photo_url='https://cdn.imgbin.com/22/0/5/imgbin-donation-computer-icons-'
                                       'fundraising-justgiving-charitable-organization-donation-'
                                       '5Yehm9UecF2cRWrqtms4e6emn.jpg',
                             photo_height=512,  # !=0/None or picture won't be shown
                             photo_width=512,
                             photo_size=512,
                             is_flexible=False)
    IF /start, IF /donation.
    invoice_payload , .

    bot.send_invoice token . , .
    token . , . token.
    : 123:TEST:XXXX
    : 123:LIVE:XXXX
  • :

    @bot.pre_checkout_query_handler(func=lambda query: True)
    def checkout(message):
        bot.answer_pre_checkout_query(message.id, ok=True,
                                      error_message="   CVV  , "
                                                    "      . "
                                                    "    , "
                                                    "   .")
    .. digital , , ok True. .

    , , . , , . , ok=True False , error_message.
  • :

    @bot.message_handler(content_types=['successful_payment'])
    def got_payment(message):
        if message.json['successful_payment']['invoice_payload'].split(',')[0] == 'buy':
            email = message.json['successful_payment']['order_info']['email']
            bot.send_message(message.chat.id,
                             '!     : `{} {}`.\n'
                             '   (`{}`)     .\n\n' \
                             '     @_'\
                             .format(message.successful_payment.total_amount / 100,
                                     message.successful_payment.currency,
                                     email),
                            parse_mode='Markdown')
            request_text = message.json['successful_payment']['invoice_payload'].split(',')[1]
            city = message.json['successful_payment']['invoice_payload'].split(',')[2]
            write_in_BD, name_excel_BD = yandex.write_exl(text=request_text, city_name=city)
            if write_in_BD == True:
                send_mail(name_file=name_excel_BD, to_address=email)
    
        elif message.json['successful_payment']['invoice_payload'] == 'donation':
            bot.send_video(message.chat.id, 'https://media0.giphy.com/media/QAsBwSjx9zVKoGp9nr/giphy.gif')

  • InlineKeyboardMarkup:

    @bot.callback_query_handler(func=lambda call: True)
    def callback_key(message):
        if message.data == 'bd_get':
            input_city(message)
        elif re.search(r'bd_yes/',message.data):
            location = re.sub('bd_yes/','',message.data)
            bot.answer_callback_query(message.id, text=location, show_alert=False)
            input_text(message, city=location)
        elif message.data == 'bd_no':
            input_city(message)
        elif re.search(r'pay', message.data):
            info_get_bd_limit = re.split(r'/',message.data)
            sent_text = info_get_bd_limit[1]
            sent_city = info_get_bd_limit[2]
            found = info_get_bd_limit[3]
            bot.answer_callback_query(message.id, text='', show_alert=False)
            pay(message, text=sent_text, city=sent_city, found=found)

  • :

    def pay(message, text, city, found):
        bot.send_invoice(message.from_user.id,
                         title=' ',
                         description='    .\n'
                                     ': '+text+'\n: '+city+'\n- : '+found,
                         invoice_payload='buy,{},{}'.format(text, city),
                         provider_token='*********:TEST:*******',
                         currency='RUB',
                         prices=[LabeledPrice(label=' ', amount=20000)],
                         start_parameter='pay_start',
                         photo_url='https://encrypted-tbn0.gstatic.com/images?q=tbn:'
                                   'ANd9GcRVUs3eGt4U9YSXZrsbOkJoNEdpcYUdq0vEzM-ci_oIxEWs1FK0',
                         photo_height=300,
                         photo_width=300,
                         photo_size=300,
                         need_email=True,
                         is_flexible=False)
    need_email , , .
  • , :

    def input_city(message):
        bot.send_message(message.from_user.id, ' :')
        bot.register_next_step_handler_by_chat_id(message.from_user.id, get_city)
        bot.answer_callback_query(message.id, text=' ', show_alert=False)

  • , :
    def get_city(message):
        get_location, get_location_point = yandex.get_location(message.text)
        keyboard = telebot.types.InlineKeyboardMarkup()
        keyboard.row(telebot.types.InlineKeyboardButton('', callback_data='bd_yes/'+message.text),
                     telebot.types.InlineKeyboardButton('', callback_data='bd_no'))
        bot.send_location(message.chat.id, get_location_point[1], get_location_point[0], reply_markup=keyboard)

  • , :

    def input_text(message, city=None):
        global location_city
        location_city = city
        info_message_id = bot.send_message(message.from_user.id, '  ( ): ')
        bot.register_next_step_handler_by_chat_id(message.from_user.id, get_bd_limit)

  • - :

    def get_bd_limit(message):
        information = yandex.get_information_limit(message.text, location_city)
        if information:
            found = yandex.sum_taken_object(yandex.get_all_infomations(message.text, location_city))
            bot.send_message(message.from_user.id, '    .\n'
                                                   '   5   .')
            i = 1
            text = ''
            for key, value in information.items():
                name = value['name']
                address = value['address']
                url = value['url']
                phones = value['phones']
                hours = value['hours']
                text = text + '' + str(i) + ') : '+name+'\n: '+address+'\n: '+url+\
                                            '\n: '+phones+'\n : '+hours+'\n----------\n'
                i += 1
            bot.send_message(message.from_user.id, text, disable_web_page_preview=True)
    
            keyboard = telebot.types.InlineKeyboardMarkup()
            keyboard.row(telebot.types.InlineKeyboardButton(' 200 .',
                                                            callback_data='pay/' + message.text+'/'+location_city+'/'+found))
            bot.send_message(message.from_user.id, '     : ' + found+''
                                                    '\n\n      .', reply_markup=keyboard)
        else:
            bot.send_message(message.from_user.id, '     !')
    

  • Telegram:
    while True:
        try:
            bot.polling(none_stop=True)
        except Exception as e:
            time.sleep(15)



Ahora Telegram admite 8 sistemas de pago. Para el mercado ruso, los más populares son Yandex Cash y Sberbank . Te aconsejo que uses Tranzzo , como usándolo puede guardar los datos de la tarjeta, usar su huella digital para pagos dentro de las 5 horas posteriores a la confirmación con una contraseña.

Cuando se usa el token de prueba de Sberbank, el proceso de facturación se cuelga, y cuando se usa Yandex Cash, todo está bien. No sé con qué está conectado esto, pero es un hecho.

imagen
imagen

Conclusión


Esta publicación está destinada no solo a mostrar las posibilidades de implementar un mini-negocio digital, sino también a despertar a un emprendedor en usted, para comenzar a generar nuevas ideas donde pueda aplicar esta funcionalidad.
Lo que ganó lo recibió: el baterista, pan y el holgazán, nada.

All Articles