Bom dia a todos! Eu acho que este artigo será interessante para todos que usam o Noção, mas, por algum motivo, não conseguiu avançar completamente.
Pré-história
Estou desenvolvendo
meu projeto . Na página de destino após inserir o e-mail, é emitido um link para uma pesquisa social baseada no Formulários Google. As respostas são registradas na placa de identificação no Google Drive.
O problema é que tudo o que
carrego comigo guardo em Noção. É brega mais conveniente. Manipulado por copiar e colar, enquanto houve poucas críticas. Depois, havia mais deles - e era necessário inventar alguma coisa. Quem se importa com o que aconteceu - bem-vindo ao gato.
O problema
O Google Forms registra respostas apenas na placa de identificação - ou seja, não há outra receita aqui. Portanto, eu tinha um plano: vamos ouvir no IFTTT as atualizações dos tablets, enviar novos dados ao webhook, processá-los de alguma forma e enviá-los para o Noção.
Para aqueles que não estão familiarizados com o IFTTT: este é um serviço que permite que você faça cadeias de ações. Digamos, “o post veio em telegramas” - “nós o exportamos no VKontakte”.
O plano começou a falhar: o Noion não possui uma API oficial. Mas alguém o inverteu e criou
uma API não oficial .
O plano final era o seguinte:- Criamos o applet no IFTTT: “Uma linha foi adicionada ao tablet - envie-a para o servidor
- Nós criamos diretamente o servidor que recebe dados e os envia para o Noção
O segundo problema surgiu quando se descobriu que o IFTTT havia quebrado a integração com o Planilhas Google e, portanto, o applet não funcionou.

Portanto, tive que mudar o plano: desenvolvemos o csv'shku com o Google Sheets, o analisamos no servidor e lançamos tudo de novo no Notion. O IFTTT é usado como um gatilho para todo o processo.
Parte 1. CSV com o Planilhas Google
Esta parte é talvez a mais fácil. Abrimos a tabela para visualização (para que você não precise se preocupar com cookies). Em seguida, pegue e copie o link para exportar CSV. Para fazer isso, basta pressionar Ctrl no teclado e digite Ctrl + Shift + J (ou seja, abra o console do desenvolvedor), vá para a guia Rede. Em seguida, clique em Arquivo - Download - CSV. Vemos a solicitação e copiamos o link.
Parte 2. Escrevendo um Servidor
Como temos uma biblioteca Python, escreveremos no Django.
Agora um pouco sobre a estrutura da minha mesa especificamente. Uma tabela no Noção, diferente da tabela no Planilhas Google, possui uma coluna "Referência". Este é um link para outra tabela (no meu caso, uma descrição das funções que os usuários gostaram). O resto é geralmente claro: apenas colunas com apenas dados.
Vamos ao Notion, já familiarizados com Ctrl + Shift + J, abra o console, vamos para Application - Cookies, copie token_v2 e chame-o de TOKEN. Então vamos para a página que precisamos com a placa e copiamos o link para ela. Ligue para NOTION. Se você também possui Relação, vá para a página Relação, copie o link e chame, por exemplo, NOTION_FUNCTIONS
Em seguida, escreva o seguinte código (noção de pré-importação):
def index(request): if request.method == "POST": client = NotionClient(token_v2=TOKEN) database = client.get_collection_view(NOTION) current_rows = database.default_query().execute() database_functions = client.get_collection_view(NOTION_FUNCTIONS) current_rows_functions = database_functions.default_query().execute()
Nele, conectamos o NotionClient, dizemos „bancos de dados? Dê dois! ”E obtemos diretamente os dados dessas duas placas (por solicitação padrão, mas é possível com a classificação, para mais detalhes, consulte a documentação da biblioteca).
Em seguida, devemos fazer o seguinte: solicitar um CSV do Google e analisá-lo. Vamos fazê-lo pandas.
result = requests.get(SHEET).content pandas_result = pd.read_csv(io.StringIO(result.decode('utf-8'))) timestamps = pandas_result[[" "]].values ages = pandas_result[[" "]].values sexes = pandas_result[[" "]].values cities = pandas_result[[" "]].values socials = pandas_result[[" ( )"]].values agreements = pandas_result[[" , - ."]].values control_usages = pandas_result[[" "]].values health_usages = pandas_result[[" "]].values prices = pandas_result[[" . :)"]].values mentions = pandas_result[[", , "]].values
Então, precisamos analisar todos os dados desta placa e verificar se eles foram adicionados ao Noção ou ainda não. Para isso, solicitamos dados das placas.
def checkTimestamp(rows, timestamp): for i in range(0, len(rows)): row = rows[i] if row.name == timestamp: return True return False
Separadamente, vale a pena mencionar sobre "row.name", porque um leitor atento provavelmente perguntará: o que é?
Este é o nome da coluna no Noção (onde os tempos de gravação são armazenados). De alguma forma, não consegui adicionar nomes russos, então mudei todos os nomes para inglês e os adicionei.

E agora o código para verificar os dados e adicionar uma linha ao rótulo de noção:
for i in range(0, len(timestamps)): if not checkTimestamp(current_rows, timestamps[i]): row = database.collection.add_row() health_usage = health_usages[i][0] control_usage = control_usages[i][0] ticks = health_usage + "," + control_usage row.title = timestamps[i][0] row.age = ages[i][0] row.sex = sexes[i][0] row.social_network = checkEmptiness(socials[i][0]) row.can_we_write_you = checkEmptiness(agreements[i][0]) row.city = checkEmptiness(cities[i][0]) row.controlling_examples = checkEmptiness(control_usages[i][0]) row.health_examples = checkEmptiness(health_usages[i][0]) row.cost = checkEmptiness(prices[i][0]) row.noticements = checkEmptiness(mentions[i][0]) row.castdev_relation = findIds(current_rows_functions, ticks)
checkEmptiness é uma função que verifica se um item nulo foi passado para ele. De alguma forma, a noção funcionou com relutância quando eu o alimentei com zero campos, então vale a pena escrever.
Agora vamos para a análise de Relações, porque na documentação oficial eu não vi sobre isso. Para criar um link para uma linha a partir de outro banco de dados, é necessário pegá-lo (desta linha) e transferi-lo. Portanto, se uma matriz de links para seqüências de caracteres de outra placa estiver implícita, você precisará usar uma matriz de seus identificadores. Eu adicionei pessoalmente Relações por nomes de funções.
def findIds(current_rows, titles): print("titles", titles) print("current rows", current_rows) array = [] for a in range(0, len(current_rows)): if current_rows[a].name in titles: array.append(current_rows[a].id) print("Ids", array) return array
No final, depois de criar as linhas, adicionamos a resposta para que, no outro extremo, saibam que a solicitação chegou.
return HttpResponse("Hello, habr.")
Depois que o Taschemta com o servidor mais importante estiver concluído, vá para IFTTT.
Parte 3. IFTTT
Vá para a
guia criação de applet . Selecionamos o gatilho (no nosso caso, é Data e hora), definimos “a cada hora”. Selecionamos o Webhook acionado (ou seja, “isso”), indica nosso endereço local (até o momento) para testá-lo. Bem, é isso. Teste.
Parte 4. Heroku
Você pensou que estávamos mexendo com esse gatilho do IFTTT - isso não é para pagar. Heroku oferece uma taxa gratuita para hospedar nossas coisas. A principal coisa é que o serviço dorme pelo menos 6 horas. E ele definitivamente dormirá, porque o chamamos para trabalhar a cada hora, e não a cada minuto.

Além disso, fazemos o seguinte. Vá para heroku para
criar um novo projeto . Em seguida, instale
o cliente no sistema operacional. E então fazemos tudo de acordo com as instruções que apareceram após a criação do aplicativo.
Depois de baixar tudo no heroku, acesse nosso applet e edite o URL para um novo.
Agora a lista deve ser atualizada a cada hora. Hipoteticamente, o IFTTT pode dar um erro de que você tenha algum tipo de solicitação longa, mas isso não é tão importante.
Update
Acabou sendo importante. Quando o IFTTT captura erros persistentes, ele começa a pular applets.
Para resolver esse problema, basta iniciar um novo tópico para todo esse material, fornecendo a resposta imediatamente.
if request.method == "POST": thread = Thread(target=run_notion_import) thread.start() return HttpResponse("Hello, habr.")
Outra idéia que eu esqueci de expressar no artigo é verificar a nulidade usando o método padrão dos pandas.
Ou seja, seu cheque será mais ou menos assim:
if not pd.isna(health_usages[i][0]): row.health_examples = health_usages[i][0]