#zapier
#zapier
Вопрос:
Я получаю ежедневное электронное письмо, в котором перечислены предстоящие встречи и их продолжительность. Количество встреч меняется изо дня в день.
Электронные письма выглядят следующим образом:
================
Сегодняшнее расписание
9:30 утра
3 часа
Бразильский выброс
[Имя клиента # 1]
12:30 вечера
1 час
Женская версия
[Имя клиента 2]
18:00
45m
Мужской крой
[Имя клиента # 3]
Прогнозируемый доход
===================
Я хочу создать событие в календаре Google для каждой встречи, и, похоже, zapier СМОЖЕТ это сделать, но все справочные ресурсы, которые я могу найти, носят очень общий характер.
Возможно ли это на Zapier? Если да, то любые подсказки в правильном направлении были бы замечательными.
Любые мысли с благодарностью.
Комментарии:
1. Насколько надежно отформатировано это электронное письмо? Если общая структура остается статичной и изменяется только количество записей, это было бы вполне достижимо с помощью модуля code, предлагаемого Zapier.
2. Да, это стандартное электронное письмо, меняется только количество встреч. Я действительно понятия не имею, с чего начать поиск хороших ресурсов по модулю code или примеров, сделанных другими людьми, чтобы я мог увидеть, как это работает. Вся онлайновая документация носит очень общий характер … как обзор, на самом деле это не руководство. Любой толчок в правильном направлении был бы потрясающим.
Ответ №1:
У меня было немного времени, чтобы убить его и насладиться необычным испытанием. Итак, я собрал решение, которое должно делать то, что вы ищете. Я разберу его по шагам.
ШАБЛОН
Триггер Zapier — Шаг 1
Тип: Модуль запуска
: Gmail
Критерии: Зависит от пользователя
Комментарии: Для запуска zap вам потребуется использовать специальный триггер Gmail, что-то вроде «выполнить триггер для электронных писем с названием ‘xyz'» или «электронных писем с пометкой ‘xyz'», если вы настроили фильтр в своем почтовом ящике.
Действие Zapier — Шаг 2
Тип: Действие
Модуль: Код (Python 3)
Комментарии: Код, предлагаемый Zapier, выполняет любой (правильно написанный) код, который вы размещаете в его контейнере. Это особенно удобно, поскольку позволяет вам включать в него данные из предыдущих шагов с помощью словарной переменной под названием ‘input_data’. Zapier предлагает модуль Code на двух языках: Javascript и Python. Поскольку я лучше всего знаком с Python, мое решение для этого шага было написано на Python. Я добавлю код в конец этого ответа. Используя данные, хранящиеся в теле электронного письма (полученные на шаге 1), мы можем выполнить некоторые манипуляции со строками и преобразования даты и времени, чтобы разбить электронное письмо на составные части и передать их на следующий шаг действия: Создать событие календаря.
Действие Zapier — Шаг 3
Тип: Действие
Модуль: Календарь Google — Создать событие
Комментарии: Используя данные, полученные на предыдущем шаге кода, мы можем заполнить необходимые поля для создания новой встречи.
Скриншот ввода: Вывод скриншота:
КОД PYTHON
from datetime import timedelta, date, datetime
'''
Goal: Extract individual appointment details from variable length email
Steps:
Remove all extraneous and new line characters.
Isolate each individual appointment and group its relevant details.
Derive appointment start and end times using appointment time and duration.
Return all appointments in a list.
'''
def format_appt_times(appt_dict):
appt_start_str = appt_dict.get("appt_start")
appt_dur_str = appt_dict.get("appt_length")
# isolate hour and minutes from appointment time
appt_s_hour = int(appt_start_str[:appt_start_str.find(":")])
if ("pm" in appt_start_str.lower()):
appt_s_hour = 12 if appt_s_hour 12 >= 24 else appt_s_hour 12
appt_s_min = int(appt_start_str[appt_start_str.find(":") 1 :
appt_start_str.find(":") 3])
# isolate hour and minutes from duration time
appt_d_hour = 0
appt_d_min = 0
if ("h" in appt_dur_str):
appt_d_hour = int(appt_dur_str[:appt_dur_str.find("h")])
if ("m" in appt_dur_str):
appt_d_min = int(appt_dur_str[appt_dur_str.find("m") - 2 : appt_dur_str.find("m")])
# NOTE: adjust timedelta hours depending on your relation to UTC
# create datetime objects for appointment start and end times
time_zone = timedelta(hours=0)
tdy = date.today() - time_zone
duration = timedelta(hours=appt_d_hour, minutes=appt_d_min)
appt_start_dto = datetime(year=tdy.year,
month=tdy.month,
day=tdy.day,
hour=appt_s_hour,
minute=appt_s_min)
appt_end_dto = appt_start_dto duration
# return properly formatted datetime as string for use in next step.
return (appt_start_dto.strftime("%Y-%m-%dT%H:%M"),
appt_end_dto.strftime("%Y-%m-%dT%H:%M"))
def partition_list(target, part_size):
for data in range(0, len(target), part_size):
yield target[data : data part_size]
def main():
# Remove all extraneous and new line characters.
email_body = input_data.get("email_body")
head,delin,*email_body,delin,foot = [text for text in email_body.splitlines() if text != ""]
appointment_list = []
# Isolate each individual appointment and group its relevant details.
for text in partition_list(email_body, 4):
template = {
"appt_start" : text[0],
"appt_end" : None,
"appt_length" : text[1],
"appt_title" : text[2],
"appt_client" : text[3]
}
appointment_list.append(template)
for appt in appointment_list:
appt["appt_start"], appt["appt_end"] = format_appt_times(appt)
return appointment_list
return main()
Я не уверен в вашем знакомстве с Python или программированием в целом, но комментарии в коде объясняют, что делает каждый раздел. Если у вас есть какие-либо конкретные вопросы, касающиеся аспектов кода, дайте мне знать. Предполагая, что ваш шаблон электронного письма не изменится, эта настройка должна работать точно так, как необходимо. Дайте мне знать, если что-то неясно.
Обновить
Я подумал, что лучше всего ответить на ваш вопрос в исходном ответе, если у кого-нибудь еще возникнут подобные вопросы.
объяснение того, как этот код удаляет лишние символы:
На самом деле в первой строке происходит изрядная часть, поэтому я сделаю все возможное, чтобы разбить ее на части и предоставить ресурсы там, где это необходимо.
Рассматриваемый код:
head,delin,*email_body,delin,foot = [text for text in email_body.splitlines() if text != ""]
Первым шагом здесь было разбить текст на управляемые фрагменты. Я сделал это со строкой email_body.splitlines()
, которая по умолчанию разбивает строки на список при каждом найденном символе новой строки (вы можете указать свой собственный разделитель).
Если бы мы проверяли список в этот момент, его содержимое было бы примерно следующим:
["================", "", "Today's Schedule", "", "9:30 AM", "", "3h", ..., "[Client #3 name]", "", "Projected Revenue", "", "==================="]
Вы заметите, что там содержится достаточное количество информации, которая нам действительно не нужна.
Сначала давайте посмотрим на элементы «». Они остаются из-за пустых строк между каждой строкой текста, которые, хотя и являются пустыми, все равно содержат символы новой строки в конце. Существует несколько способов решить эту проблему в python. Мы могли бы просто написать цикл for для прохождения и копирования всех элементов, которые не являются «», в новый список.
Для меня это было похоже на дополнительную работу, и, кроме того, Python предлагает понимание списка именно для такого сценария. Я не буду углубляться в понимание списка, поскольку об этом можно многое сказать, и более глубокими способами, чем я мог бы собрать, но по сути это позволяет вам использовать логику для набора «данных» для формирования списка. В этом случае я специально хотел отфильтровать элементы «», возвращаемые вызовом splitlines().
Итак, вы увидите, что я обращаюсь к этому с помощью следующей строки
[text for text in email_body.splitlines() if text != ""]
Таким образом, у нас есть список, как указано выше, за вычетом элементов «». Теперь мы должны обратить наше внимание на более «динамичные» строки мусора. Опять же, есть несколько способов сделать это. Не особенно гибким вариантом может быть простое сохранение строк, которые мы хотим удалить, в переменных, что-то вроде:
garb_1 = "==================="
garb_2 = "Projected Revenue"
garb_3 = ...
и еще раз отфильтруйте список с помощью еще одного цикла for. Вместо этого я решил использовать идиому распаковки списков Python. Который позволяет нам «распаковывать» объекты списка (и, я полагаю, кортежи) в переменные. В качестве примера:
one, two, three = ["a", "b", "c"]
Я уверен, вы можете догадаться, что происходит выше, пока мы предоставляем то же количество переменных, что и в списке, мы можем «распаковать» его таким образом. Но подождите! В нашем случае мы не знаем, какой длины будет список, поскольку это полностью зависит от количества назначенных вами встреч на каждый данный день. Что ж, именно здесь начинается распаковка star для повышения функциональности. Используя мой код в качестве примера:
head,delin,*email_body,delin,foot = [text for text in email_body.splitlines() if text != ""]
* на простом английском языке говорит: «Я не знаю, сколько элементов ожидать, просто дайте мне их все в списке». Поскольку мы знаем, что в начале и конце электронного письма всегда будут две строки мусора, мы можем назначить их для удаления переменных и захвата всего, что находится между ними, используя наш контейнер переменной длины * email_body.
После завершения всего этого у нас теперь есть список, содержащий только те данные, которые мы хотим получить. Если, как вы говорите, есть дополнительные строки мусора до или после email_body, вы можете просто добавить дополнительные переменные выброса для их учета.
Еще раз, не стесняйтесь задавать любые дополнительные вопросы.
Майкл
Ресурсы
Комментарии:
1. Вау, это потрясающе! Спасибо! Я не могу дождаться, чтобы просмотреть его, когда у меня будет немного свободного времени. Я немного разбираюсь в Python, поэтому я думаю, что это именно то, чему мне нужно было научиться. Я уверен, что у меня возникнет пара вопросов, но хотел бы сразу поблагодарить вас за помощь!
2. Хорошо, у меня действительно есть вопрос, потому что в предоставленном мной образце электронного письма действительно есть дополнительный мусор до и после него. Не могли бы вы объяснить более подробно (или указать мне на справочный материал), объясняющий, как этот код удаляет лишние символы и прочее? Я бы хотел научиться ловить рыбу здесь….
3. Я обновил свой ответ, чтобы подробнее объяснить свой код, надеюсь, в нем есть какой-то смысл!