title: How do I send an email using Google App Scripts as a pdf with a python script?
body: <p>So I'm trying to make an invoice app where by entering a few details into the app, it'll automatically create a new sheet on a Google Sheet, update values, and send that particular sheet as a pdf via email.</p>
  <p>I have finished the Python app, however I could not find any modules that can email a google sheet as a pdf directly. That's when I stumbled across Google App Scripts where you can use js to create a trigger function on the google sheet. Ive set it up but whenever I enter &quot;use  the app&quot;, the google script sends 3 emails instead of 1. Tbh I only want to send an email once the new created sheet has been update, but I cannot find a way to do that yet.</p>
  <p>I tried using the onEdit() simple trigger, but that trigger does not support sending emails, so ive been forced to use the installable trigger. However, through a bit of testing i found that if I try to to use the onEdit installable trigger in conjunction with my python script, it doesn't &quot;count&quot; as an edit, but a change instead. So i was forced to use the onChange installable trigger.
  Here's the code:</p>
  <p>app script:</p>
  <pre><code>
    var sheet = SpreadsheetApp.getActiveSheet();
  
    console.log(sheet.getName())// check what the active sheet is
    
  
      if(SpreadsheetApp.getActiveSheet().getRange(33, 5).getValue() &gt; 0) //if (row=33, col=5) (final price) &gt; 0, execute 
      {
        console.log(SpreadsheetApp.getActiveSheet().getRange(33, 5).getValue())//testing to see what value is in this cell ('E33')
        var message = {
        to: &quot;myemail@gmail.com&quot;,
        subject: &quot;Monthly sales report&quot;,
        body: &quot;Hi team,\n\nPlease find the monthly report attached.\n\nThank you,\nBob&quot;,
        name: &quot;Bob&quot;,
        attachments: [SpreadsheetApp.getActiveSpreadsheet().getAs(MimeType.PDF).setName(&quot;Monthly sales report&quot;)]
      }
      console.log(message);
      // MailApp.sendEmail(message);
  
      }
      else
      { }
    }
  </code></pre>
  <p>python script:</p>
  <pre><code>import gspread
  from gspread_formatting import *
  from oauth2client.service_account import ServiceAccountCredentials
  from tkinter import *  # for gui
  
  # tkinter 2 step process: Create widget, display widget
  
  root = Tk()  # necessary for any gui
  
  qty = []
  desc = []
  unit = []
  
  canvas = Canvas(root, width=800, heigh=500)
  canvas.pack()
  frame = Frame(root, bg='#FFFF00')
  quantityListbox = Listbox(frame)
  descriptionListbox = Listbox(frame)
  unitListbox = Listbox(frame)
  quantityTextbox = Text(frame)
  descriptionTextbox = Text(frame)
  unitTextbox = Text(frame)
  
  
  # NOTE: 'template' sheet is the invoice template
  
  def sendToSheet(company, invNum, orderNum, job, date, address):
      scope = [&quot;https://spreadsheets.google.com/feeds&quot;, &quot;https://www.googleapis.com/auth/sprea...&quot;,
               &quot;https://www.googleapis.com/auth/drive...&quot;, &quot;https://www.googleapis.com/auth/drive&quot;]
      print('Sending')
      ##initialises stuff
      creds = ServiceAccountCredentials.from_json_keyfile_name(&quot;credentials.json&quot;)
      client = gspread.authorize(creds)
  
      ##everything below here rn is making the invoice template
      spreadsheet = client.open(&quot;InvoiceMe&quot;)  # opens spread sheet
  
      sst = spreadsheet.worksheet('template')  # opens up worksheet 1
  
      sst.duplicate(new_sheet_name=company)  # duplicates &quot;template&quot; and renames the new sheet
  
      currentss = spreadsheet.worksheet(company)  # gets/opens work sheet with name as parameter
  
      # update cells
      currentss.update('E11', invNum)
      currentss.update('E12', orderNum)
      currentss.update('E13', job)
      currentss.update('E14', date)
      currentss.update('C17', company)
      currentss.update('C18', address)
  
      ###updates quantity + amount
      for i, item in enumerate(qty):
          # print('B' + str(22 + i))
          currentss.update('B' + str(22 + i), item)
          # currentss.update('E' + str(22 + i), '=B' + str(22 + i) + '*' + 'D' + str(22 + i))
  
      ###udpates description
      for i, item in enumerate(desc):
          # print('B' + str(22 + i))
          currentss.update('C' + str(22 + i), item)
  
      #updates unit
      for i, item in enumerate(unit):
          # print('B' + str(22 + i))
          currentss.update('D' + str(22 + i), item)
  
  
  
      print('Invoice updated')
  
  
  ###adds values to global list
  def addToList(q, d, u):  # qty, desc, unit
      global qty, desc, unit
      qty.append(q)
      quantityListbox.insert(END, q)
      print(qty)  # test purposes
      quantityTextbox.delete('1.0', END)
  
      desc.append(d)
      descriptionListbox.insert(END, d)
      print(desc)  # test purposes
      descriptionTextbox.delete('1.0', END)
  
      unit.append(u)
      unitListbox.insert(END, '$' + u)
      print(unit)  # test purposes
      unitTextbox.delete('1.0', END)
  
  
  
  
  def gui():
      global frame, quantityListbox, descriptionListbox, unitListbox, \
          quantityTextbox, descriptionTextbox, unitTextbox
  
      frame.place(relwidth=1, relheight=1)
  
      titleLabel = Label(frame, text='InvoiceMe')
      titleLabel.place(anchor='n', relx=0.5, rely=0.02)
  
      # company
      companyLabel = Label(frame, text='To/Company')
      companyLabel.place(anchor='n', relx=0.18, rely=0.1)
  
      companyTextBox = Text(frame)
      companyTextBox.place(anchor='n', relx=0.18, rely=0.15, relwidth=0.35, relheight=0.05)
  
      # address
      addressLabel = Label(frame, text='Address')
      addressLabel.place(anchor='n', relx=0.55, rely=0.1)
  
      addressTextBox = Text(frame)
      addressTextBox.place(anchor='n', relx=0.55, rely=0.15, relwidth=0.35, relheight=0.05)
  
      # date
      dateLabel = Label(frame, text='Date')
      dateLabel.place(anchor='n', relx=0.85, rely=0.1)
  
      dateTextbox = Text(frame)
      dateTextbox.place(anchor='n', relx=0.85, rely=0.15, relwidth=0.20, relheight=0.05)
  
      # invoice number
      invoiceLabel = Label(frame, text='Invoice number')
      invoiceLabel.place(anchor='n', relx=0.85, rely=0.3)
  
      invoiceTextbox = Text(frame)
      invoiceTextbox.place(anchor='n', relx=0.85, rely=0.35, relwidth=0.20, relheight=0.05)
  
      # order num
      orderLabel = Label(frame, text='Order number')
      orderLabel.place(anchor='n', relx=0.85, rely=0.45)
  
      orderTextbox = Text(frame)
      orderTextbox.place(anchor='n', relx=0.85, rely=0.5, relwidth=0.20, relheight=0.05)
  
      # job num
      jobLabel = Label(frame, text='Job')
      jobLabel.place(anchor='n', relx=0.85, rely=0.6)
  
      jobTextbox = Text(frame)
      jobTextbox.place(anchor='n', relx=0.85, rely=0.65, relwidth=0.20, relheight=0.05)
  
      # submit button
      submit = Button(frame, text='Send Invoice', command=lambda: sendToSheet(companyTextBox.get('1.0', 'end'),
                                                                              invoiceTextbox.get('1.0', 'end'),
                                                                              orderTextbox.get('1.0', 'end'),
                                                                              jobTextbox.get('1.0', 'end'),
                                                                              dateTextbox.get('1.0', 'end'),
                                                                              addressTextBox.get('1.0', 'end')))
      submit.place(anchor='n', relx=0.85, rely=0.8, relwidth=0.15, relheight=0.1)
  
      quantityLabel = Label(frame, text='Quantity')
      quantityLabel.place(anchor='n', relx=0.11, rely=0.3)
  
      quantityTextbox.place(anchor='n', relx=0.11, rely=0.35, relwidth=0.1, relheight=0.05)
  
      quantityListbox.place(anchor='n', relx=0.11, rely=0.5, relwidth=0.1, relheight=0.4)
  
      descriptionLabel = Label(frame, text='Description')
      descriptionLabel.place(anchor='n', relx=0.36, rely=0.3)
  
      descriptionTextbox.place(anchor='n', relx=0.36, rely=0.35, relwidth=0.35, relheight=0.05)
  
      descriptionListbox.place(anchor='n', relx=0.36, rely=0.5, relwidth=0.35, relheight=0.4)
  
      unitLabel = Label(frame, text='Unit')
      unitLabel.place(anchor='n', relx=0.61, rely=0.3)
  
      unitTextbox.place(anchor='n', relx=0.61, rely=0.35, relwidth=0.1, relheight=0.05)
  
      unitListbox.place(anchor='n', relx=0.61, rely=0.5, relwidth=0.1, relheight=0.4)
  
      addButton = Button(frame, text='add', command=lambda: addToList(quantityTextbox.get('1.0', 'end-1c'),
                                                                      descriptionTextbox.get('1.0', 'end-1c'),
                                                                      unitTextbox.get('1.0', 'end-1c')))
      addButton.place(anchor='n', relx=0.61, rely=0.425, relwidth=0.075, relheight=0.05)
  
  
  # sendToSheet(company, invNum, orderNum, job, date, address):
  
  gui()
  
  root.mainloop()  # necessarry for gui
  </code></pre>
  <p>I should probably point out that I am new to python, and was looking for a project and this is what I decided to do. treat me as if i were a noob and any pointers will be appreciated :)</p>