class_docstr: Implementation for the emails table for Gmail
class_docstr_tok: ["Implementation","for","the","emails","table","for","Gmail"]
docstr: Sends reply emails using the Gmail "users.messages.send" API
  
  Parameters
  ----------
  query : ast.Insert
     Given SQL INSERT query
  
  Raises
  ------
  ValueError
      If the query contains an unsupported condition
docstr_tok: ["Sends","reply","emails","using","the","Gmail","``","users.messages.send","''","API","Parameters","--","--","--","--","--","query",":","ast.Insert","Given","SQL","INSERT","query","Raises","--","--","--","ValueError","If","the","query","contains","an","unsupported","condition"]
code: def insert(self, query: ast.Insert):
      """Sends reply emails using the Gmail "users.messages.send" API
  
      Parameters
      ----------
      query : ast.Insert
         Given SQL INSERT query
  
      Raises
      ------
      ValueError
          If the query contains an unsupported condition
      """
      columns = [col.name for col in query.columns]
  
      supported_columns = {
          "message_id",
          "thread_id",
          "to_email",
          "subject",
          "body",
      }
      if not set(columns).issubset(supported_columns):
          unsupported_columns = set(columns).difference(
              supported_columns
          )
          raise ValueError(
              "Unsupported columns for create email: "
              + ", ".join(unsupported_columns)
          )
  
      for row in query.values:
          params = dict(zip(columns, row))
  
          if not "to_email" in params:
              raise ValueError(
                  '"to_email" parameter is required to send an email'
              )
  
          message = EmailMessage()
          message["To"] = params["to_email"]
          message["Subject"] = (
              params["subject"] if "subject" in params else ""
          )
  
          content = params["body"] if "body" in params else ""
          message.set_content(content)
  
          # If threadId is present then add References and In-Reply-To headers
          # so that proper threading can happen
          if "thread_id" in params and "message_id" in params:
              message["In-Reply-To"] = params["message_id"]
              message["References"] = params["message_id"]
  
          encoded_message = urlsafe_b64encode(
              message.as_bytes()
          ).decode()
  
          message = {"raw": encoded_message}
  
          if "thread_id" in params:
              message["threadId"] = params["thread_id"]
          self.handler.call_gmail_api("send_message", {"body": message})
  
imports: import json
  from shutil import copyfile
  from collections import OrderedDict
  import requests
  from mindsdb.integrations.libs.response import HandlerStatusResponse, HandlerResponse
  from mindsdb.integrations.libs.const import HANDLER_CONNECTION_ARG_TYPE
  from mindsdb.integrations.utilities.sql_utils import extract_comparison_conditions
  from mindsdb.integrations.libs.api_handler import APIHandler, APITable
  from mindsdb_sql.parser import ast
  from mindsdb.utilities import log
  from mindsdb_sql import parse_sql
  from mindsdb.utilities.config import Config
  import os
  import time
  from typing import List
  import pandas
  from google.auth.transport.requests import Request
  from google.oauth2.credentials import Credentials
  from google_auth_oauthlib.flow import Flow
  from googleapiclient.discovery import build
  from googleapiclient.errors import HttpError
  from email.message import EmailMessage
  from base64 import urlsafe_b64encode, urlsafe_b64decode
  from .utils import AuthException, google_auth_flow, save_creds_to_file
label_desc: Use image node_id 3 for calling the EmailsTable obj's underlying member method code with example usage: obj.insert(query) without return types