我可以从电子邮件中提取信息列表吗?

问题描述 投票:0回答:1

我收到每日电子邮件,其中列出即将到来的约会及其长度。约会的数量每天都有所不同。

电子邮件是这样的:

================

今天的日程安排

上午9:30

3H

巴西井喷

[客户#1名称]

下午12:30

1H

女装剪裁

[客户2名]

下午6点

45米

男士剪裁

[客户#3名称]

预计收入

===================

我想在Google日历中为每个约会创建一个活动,看起来zapier可能会做到这一点,但我能找到的所有帮助资源都是非常通用的。

Zapier可以这样做吗?如果是这样,任何正确方向的推动都会很棒。

任何想法都非常感激。

zapier
1个回答
2
投票

我有时间杀死并享受奇怪的挑战。所以我已经制定了一个应该做你想要的解决方案。我会逐步分解它。

模板


Zapier Trigger - 第1步 类型:触发器 模块:Gmail 标准:用户依赖 注释:对于触发器zap,您将需要使用特定于Gmail的触发器,如果​​您在收件箱中设置了过滤器,则可以使用“在标题为'xyz'的电子邮件上执行触发器”或“标记为'xyz'的电子邮件”。

输入截图:enter image description here

输出截图:enter image description here

Zapier行动 - 第2步 类型:动作 模块:代码(Python 3) 注释:Zapier提供的代码执行您放置在容器中的任何(正确编写的)代码。它特别方便,因为它允许您通过使用名为'input_data'的字典变量来合并先前步骤中的数据。 Zapier以两种语言提供Code模块:Javascript和Python。由于我最熟悉Python,因此我使用Python编写了此步骤的解决方案。我会将代码附加到此答案的末尾。使用电子邮件正文中保存的数据(在步骤1中检索),我们可以执行一些字符串操作和日期时间转换,将电子邮件分解为其组成部分,并将其传递给以下操作步骤:创建日历事件。

输入屏幕截图:enter image description here

输出截图:enter image description here

Zapier行动 - 第3步 类型:动作 模块:Google日历 - 创建活动 注释:使用上一代码步骤输出的数据,我们可以填写创建新约会所需的字段。

输入屏幕截图:enter image description here输出屏幕截图:enter image description here

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或更普遍的编程,但代码中的注释解释了每个部分正在做的事情。如果您对代码的各个方面有任何具体问题,请告诉我。假设您的电子邮件模板未更改,则此设置应完全按照需要运行。如果有什么不清楚,请告诉我。

UPDATE


I thought it best to address your question in the original answer should anyone else have similar questions.

解释此代码如何删除多余的字符:

第一行实际上有一点点,所以我会尽力将其分解,并在必要时提供资源。

有问题的代码:

  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 != ""]

有了这个,我们有一个列表,上面少了“”元素。现在我们必须将注意力转向更“动态”的垃圾串。有很多方法可以做到这一点。 A,不是特别灵活的选项可以简单地将我们想要删除的字符串存储在变量中,以达到以下效果:

garb_1 = "==================="
garb_2 = "Projected Revenue"
garb_3 = ...

并再次使用另一个for循环过滤列表。我改为选择利用Python的列表解包成语。这允许我们将列表对象(我相信元组)“解包”成变量。举个例子:

one, two, three = ["a", "b", "c"]

我相信你可以猜出上面发生的事情,只要我们提供与列表中相同数量的变量,我们就可以以这种方式“解包”它。可是等等!在我们的案例中,我们不知道列表将持续多长时间,因为它完全取决于您在任何特定日期的约会数量。那么这就是明星拆包进入以提升功能的地方。使用我的代码作为示例:

head,delin,*email_body,delin,foot = [text for text in email_body.splitlines() if text != ""]

*,用简单的英语,说“我不知道有多少元素可以在列表中给我所有元素”。我们知道在电子邮件的开头和结尾总会有两行垃圾,我们可以指定它们扔掉变量并使用我们的可变长度* email_body容器捕获它们之间的所有内容。

完成所有这些后,我们现在有一个列表,其中只包含我们要捕获的数据。如果,正如您所说,在email_body之前或之后还有额外的垃圾行,您可以简单地添加额外的丢弃变量来解释它们。

再次随时问任何后续问题。

迈克尔

资源


List Comprehension Star Unpacking

© www.soinside.com 2019 - 2024. All rights reserved.