{"id":797,"date":"2020-02-07T13:49:48","date_gmt":"2020-02-07T12:49:48","guid":{"rendered":"https:\/\/www.tiraquelibras.com\/blog\/?p=797"},"modified":"2021-02-02T10:43:24","modified_gmt":"2021-02-02T09:43:24","slug":"envio-smtp-con-contenido-html-o-texto-plano-y-soporte-para-ssl-tls-y-starttls","status":"publish","type":"post","link":"https:\/\/blog.tiraquelibras.com\/?p=797","title":{"rendered":"Env\u00edo SMTP con contenido HTML o Texto plano y soporte para SSL\/TLS y STARTTLS"},"content":{"rendered":"\n<p>Programa desarrollado en&nbsp;<strong>Python 3<\/strong> para el env\u00edo de mensajes con contenido&nbsp;<strong>HMTL<\/strong> o<strong> Texto plano<\/strong> y con soporte para <strong>SSL\/TLS<\/strong> o&nbsp;<strong>STARTTLS<\/strong>&nbsp;y archivos adjuntos.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_76 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Tabla de contenidos<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a0cb9102e37b\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a0cb9102e37b\"  aria-label=\"Alternar\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-1 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=797\/#Introduccion\"  rel=\"nofollow\" target=\"_blank\">Introducci\u00f3n<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-2 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=797\/#Requisitos\"  rel=\"nofollow\" target=\"_blank\">Requisitos<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-3 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=797\/#Instalacion\"  rel=\"nofollow\" target=\"_blank\">Instalaci\u00f3n<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-4 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=797\/#Configuracion\"  rel=\"nofollow\" target=\"_blank\">Configuraci\u00f3n<\/a><ul class='ez-toc-list-level-2' ><li class='ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=797\/#Dentro_del_ejecutable\"  rel=\"nofollow\" target=\"_blank\">Dentro del ejecutable<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=797\/#Usando_las_opciones_del_programa_prioritario\"  rel=\"nofollow\" target=\"_blank\">Usando las opciones del programa (prioritario)<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-7 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=797\/#Ejecucion\"  rel=\"nofollow\" target=\"_blank\">Ejecuci\u00f3n<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-8 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=797\/#Ejemplo\"  rel=\"nofollow\" target=\"_blank\">Ejemplo<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-9 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=797\/#Enlaces_de_interes\"  rel=\"nofollow\" target=\"_blank\">Enlaces de inter\u00e9s<\/a><\/li><\/ul><\/nav><\/div>\n<h1 class=\"md-end-block md-heading wp-block-heading\"><span class=\"ez-toc-section\" id=\"Introduccion\"><\/span><span class=\"md-plain\">Introducci\u00f3n<\/span><span class=\"ez-toc-section-end\"><\/span><\/h1>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Programa para realizar env\u00edos de correo con contenido en formato <\/span><span class=\"\"><strong><span class=\"md-plain\">HTML<\/span><\/strong><\/span><span class=\"md-plain\"> o <\/span><span class=\"\"><strong><span class=\"md-plain\">Texto plano<\/span><\/strong><\/span><span class=\"md-plain\">, a partir de un archivo con extensi\u00f3n <\/span><span class=\"\"><strong><em><span class=\"md-plain\">.html<\/span><\/em><\/strong><\/span><span class=\"md-plain\"> o <\/span><span class=\"\"><strong><em><span class=\"md-plain\">.txt<\/span><\/em><\/strong><\/span><span class=\"md-plain\"> respectivamente.<\/span><\/p>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Dispone de soporte para <\/span><span class=\"\"><strong><span class=\"md-plain\">SSL\/TLS<\/span><\/strong><\/span><span class=\"md-plain\"> y <\/span><span class=\"\"><strong><span class=\"md-plain\">STARTTLS<\/span><\/strong><\/span><span class=\"md-plain\">.<\/span><\/p>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Posibilidad de enviar a uno o varios destinatarios, incluidos en <\/span><span class=\"\"><strong><span class=\"md-plain\">CC<\/span><\/strong><\/span><span class=\"md-plain\">, y con cambio de identidad, si el proveedor del servicio de correo lo permite, <\/span><u><span class=\"md-plain\">aunque no recomendamos el uso de esta pr\u00e1ctica<\/span><\/u><span class=\"md-plain\">.<\/span><\/p>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Tambi\u00e9n tenemos la opci\u00f3n de adjuntar uno o varios archivos en el mismo env\u00edo.<\/span><\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h1 class=\"md-end-block md-heading wp-block-heading\"><span class=\"ez-toc-section\" id=\"Requisitos\"><\/span><span class=\"md-plain\">Requisitos<\/span><span class=\"ez-toc-section-end\"><\/span><\/h1>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">El programa est\u00e1 desarrollado para ser usado con <\/span><span class=\"\"><strong><span class=\"md-plain\">Python 3.x<\/span><\/strong><\/span><span class=\"md-plain\">.<\/span><\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h1 class=\"md-end-block md-heading wp-block-heading\"><span class=\"ez-toc-section\" id=\"Instalacion\"><\/span><span class=\"md-plain\">Instalaci\u00f3n<\/span><span class=\"ez-toc-section-end\"><\/span><\/h1>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">No se requiere la instalaci\u00f3n de m\u00f3dulos adicionales, ya que se encuentran incluidos por defecto en la versi\u00f3n del lenguaje en el que se ha desarrollado. Por lo tanto, tampoco ser\u00e1 necesario ejecutar en un <\/span><span class=\"\"><strong><em><span class=\"md-plain\">entorno virtual<\/span><\/em><\/strong><\/span><span class=\"md-plain\"> de <\/span><span class=\"\"><strong><span class=\"md-plain\">Python<\/span><\/strong><\/span><span class=\"md-plain\">.<\/span><\/p>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Para clonar el repositorio nos ubicamos en el directorio en donde queramos instalar el programa y usamos el siguiente comando para clonarlo:<\/span><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">git clone https:\/\/sergiobr@bitbucket.org\/sergiobr\/smtp-contenido-html-o-texto-plano-desde-python.git<\/code><\/pre>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Y ya estar\u00eda listo para su uso en el directorio en donde lo hayamos clonado.<\/span><\/p>\n\n\n\n<p>Tambi\u00e9n podemos crear el fichero con el contenido del programa, pues fue desarrollado en un mismo archivo, aunque te recomiendo hacer el clonado por si se suben actualizaciones a&nbsp;<strong>BitBucket<\/strong>. Contenido:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">import os\nfrom os.path import basename\n# Options\nfrom optparse import OptionParser\n# Email\nfrom email.utils import formatdate\n#from email.mime.image import MIMEImage\nimport smtplib\nfrom email.mime.application import MIMEApplication\nfrom email.mime.multipart import MIMEMultipart\nfrom email.mime.text import MIMEText\n\n\n# VARIABLES\n################\n\n# Email server.\nemailHost = ''\n# Int.\nemailPort = 25\n# True\/False.\nemailTLS = False\nemailSSL = False\n# Email credentials.\nemailUser = ''\nemailPwd = ''\n# Email subject.\nemailSubject = ''\n# Email From info.\nemailFrom = ''\n# Email To and CC.\nemailTo = ''\nemailToCc = ''\n# Attachment\/s.\nemailAttachment = ''\n# Replay header.\nemailReplyTo = ''\n\n\n# CLASSES\n#######################\n\n# Options parser\ndef programParser():\n      try:\n            # Description and version variables.\n            usage = \"python %prog [options] bodyContentFile.[html|txt]\"\n            description = \"Program to send email with HTML or Plain text content, with also attachments.\\n\\nConfigure the variables section to connect to your email server, or use the options to change any of these.\\n\\nSpecify the body content in a .html or .txt file, depending on the format you choose.\\n\\nNever use single quotes ('') in each option value. If you not add white spaces quotes are not neccesary, but if you use it only double quotes (\\\"\\\") are allowed.\"\n            version = '%prog: version 1.0'\n\n            # Parser init.\n            parser = OptionParser(usage,version=version,description=description,add_help_option=True)\n\n            # Parser options.\n            parser.add_option('-H', '--host', dest = 'host', help = 'SMTP server.')\n            parser.add_option('-p', '--port', dest = 'port', help = 'SMTP port.')\n            parser.add_option('--tls', action = 'store_true', help = 'TLS security on.')\n            parser.add_option('--ssl', action = 'store_true', help = 'SSL security on.')\n            parser.add_option('--nosecurity', action = 'store_true', help = 'No TLS or SSL security.')\n            parser.add_option('-u', '--username', dest = 'username', help = 'Username login.')\n            parser.add_option('-P', '--password', dest = 'password', help = 'Password login.')\n            parser.add_option('-s', '--subject', dest = 'subject', help = 'Email subject, between double quotes (\\\"\\\").')\n            parser.add_option('-f', '--from', dest = 'emailFrom', help = 'Email from. Different than Username could be considered as Email Spoofing. If it is not defined it will be the same than the user name.')\n            parser.add_option('-t', '--to', dest = 'emailTo', help = 'Email destination. More than one separated by comas (,), with no white spaces.')\n            parser.add_option('-c', '--carboncopy', dest = 'emailToCc', help = 'Email destination copy. More than one separated by comas (,), with no white spaces.')\n            parser.add_option('-a', '--attachment', dest = 'emailAttachment', help = 'Attach a file or files, separated by comas (,) and between double quotes (\\\"\\\").')\n            parser.add_option('-r', '--replyto', dest = 'emailReplyTo', help = 'Email to reply. If it is not defined it will be the email from.')\n\n            return parser\n\n      except Exception as e:\n            raise ValueError('Function - creating program parser: %s' % str(e))\n\n# Check parser to change file variables.\ndef checkParserOptionsArguments(options,args):\n      try:\n            # ARGUMENTS, only 1 is available. No arguments or more than one show an error.\n            if len(args) == 0:\n                  raise ValueError('No argument has been indicated.')\n            elif len(args) &gt; 1 or len(args) &lt; 0:\n                  raise ValueError('Only one argument is allowed.')\n            else:\n                  # Check the argument extension. Only .html or .txt are available.\n                  extension = args[0].split('.')\n                  fileExt = extension[1].lstrip('\\'').rstrip('\\'')\n                  \n                  # Other extensions than .html or .txt extension show an error.\n                  if fileExt != 'html' and fileExt != 'txt':\n                        raise ValueError('Only files with extensions .html or .txt are allowed.')\n                  else:\n\n                        # Identify email type by the file extension (HTML or Plain text).\n                        global emailType\n                        if fileExt == 'html':\n                              emailType = 'html'\n                        elif fileExt == 'txt':\n                              emailType = 'plain'\n\n            # Parser options added.\n            # Email Host.\n            if options.host:\n                  global emailHost\n                  emailHost = str(options.host.lstrip('\\'').rstrip('\\''))\n            \n            # Email Port.\n            if options.port:\n                  global emailPort\n                  emailPort = int(options.port.lstrip('\\'').rstrip('\\''))\n            \n            # Security, only one or none allowed.\n            if options.tls and options.ssl:\n                  raise ValueError('Only one option is available, --ssl or --tls, or nothing.')\n            elif options.nosecurity:\n                  global emailSSL\n                  global emailTLS\n                  emailTLS = False\n                  emailSSL = False                  \n            else:                  \n                  if options.tls:\n                        emailTLS = True\n                        emailSSL = False\n                  if options.ssl:\n                        emailSSL = True\n                        emailTLS = False\n            \n            # Email Username\n            if options.username:\n                  global emailUser\n                  emailUser = str(options.username.lstrip('\\'').rstrip('\\''))\n\n            # Email password\n            if options.password:\n                  global emailPwd\n                  emailPwd = str(options.password.lstrip('\\'').rstrip('\\''))\n\n            # Email subject.\n            if options.subject:\n                  global emailSubject\n                  emailSubject = str(options.subject.lstrip('\\'').rstrip('\\''))\n            \n            # Email from.\n            if options.emailFrom:\n                  global emailFrom\n                  emailFrom = str(options.emailFrom)\n\n            # Email\/s to.\n            if options.emailTo:\n                  global emailTo\n                  emailTo = str(options.emailTo.lstrip('\\'').rstrip('\\''))\n\n            # Email\/s in Carbon Copy.\n            if options.emailToCc:\n                  global emailToCc\n                  emailToCc = str(options.emailToCc.lstrip('\\'').rstrip('\\''))\n\n            # Email attachment\/s.\n            if options.emailAttachment:\n                  global emailAttachment\n                  emailAttachment = str(options.emailAttachment.lstrip('\\'').rstrip('\\''))\n\n            # Email reply header.\n            if options.emailReplyTo:\n                  global emailReplyTo\n                  emailReplyTo = str(options.emailReplyTo.lstrip('\\'').rstrip('\\''))\n\n      except Exception as e:\n            raise ValueError('Function - checking parser variables: %s' % str(e))\n      \n\n# Email Class\nclass emailClass():\n\n      # Constructor with email config variables.\n      def __init__(self,emailHost,emailPort,emailTLS,emailSSL,emailUser,emailPwd,emailSubject,emailFrom,emailTo,emailToCc,emailReplyTo):\n            self.emailHost = emailHost\n            self.emailPort = emailPort\n            self.emailTLS = emailTLS\n            self.emailSSL = emailSSL\n            self.emailUser = emailUser\n            self.emailPwd = emailPwd\n            self.emailSubject = emailSubject\n\n            self.emailFrom = emailFrom\n            if not self.emailFrom:\n                  self.emailFrom = self.emailUser\n            elif not '@' in self.emailFrom:\n                  self.emailFrom = self.emailFrom + \" &lt;\" + self.emailUser + \"&gt;\"\n            \n            self.emailTo = emailTo\n            self.emailToCc = emailToCc\n            \n            self.emailReplyTo = emailReplyTo\n            if not self.emailReplyTo:\n                  self.emailReplyTo = self.emailFrom\n\n            self.mailRcpt = self.emailTo.split(',') + self.emailToCc.split(',')\n\n            if self.emailTLS and self.emailSSL:\n                  raise ValueError('Check variables for SSL and TLS in the program, only one or nothing are availables.')\n\n      # Send the email from config variables (from file or command options).\n      def emailSend(self,type,bodyContent,attach=None):\n            try:\n                  # Type (HTML or Plain text).\n                  if type == 'html':\n                        msg = MIMEMultipart('related')\n                  elif type == 'plain':\n                        msg = MIMEMultipart()\n                  else:\n                        raise ValueError('Class - Error declaring email type (html or plain).')\n                  \n                  # Message info.\n                  msg['Subject'] = self.emailSubject\n                  msg['From'] = self.emailFrom\n                  msg['To'] = self.emailTo\n                  msg['Cc'] = self.emailToCc\n                  msg[\"Date\"] = formatdate(localtime=True)\n                  msg[\"Reply-To\"] = self.emailReplyTo\n\n                  # Body content.\n                  with open(bodyContent) as f:\n                        body = f.read()\n                  if type == 'html':\n                        part2 = MIMEText(body,'html')\n                  elif type == 'plain':\n                        part2 = MIMEText(body,'plain')\n                  else:\n                        raise ValueError('Class - Error declaring email type (html or plain).')\n                  msg.attach(part2)\n\n                  # Attach file\/s, it it has been indicated.\n                  if attach:\n                        for f in attach.split(','):                                                   \n                              with open(f, \"rb\") as file:\n                                    part = MIMEApplication(file.read(), Name=basename(f))\n                              part['Content-Disposition'] = 'attachment; filemane=%s' % basename(f)\n                              msg.attach(part)\n\n                  # Create message.\n                  textBody = msg.as_string()\n\n\n                  # Configure security, if it has been configured.\n                  if self.emailSSL:\n                        connection = smtplib.SMTP_SSL(self.emailHost,self.emailPort)\n                        connection.ehlo()\n                  else:\n                        connection = smtplib.SMTP(self.emailHost,self.emailPort)\n                        connection.ehlo()\n                        if self.emailTLS:\n                              connection.starttls()\n\n                  # Email credentials, if it has been configured.\n                  if self.emailUser:\n                        connection.login(self.emailUser,self.emailPwd)\n\n                  # Send the email.\n                  connection.sendmail(self.emailFrom,self.mailRcpt,textBody)\n\n                  # Close connection.\n                  connection.quit()\n\n            except Exception as e:\n                  raise ValueError('Class error: %s' % (str(e)))\n\n\n# PROGRAM\n###########\n\ntry:\n\n      # Parse argument and options, if exists.\n      parser = programParser()\n      (options, args) = parser.parse_args()\n\n      # Check parser options and argument.\n      checkParserOptionsArguments(options,args)\n\n      email = emailClass(emailHost,emailPort,emailTLS,emailSSL,emailUser,emailPwd,emailSubject,emailFrom,emailTo,emailToCc,emailReplyTo)\n\n      # html or plain \/ html body file or plain text body, and the attachment if is required.\n      email.emailSend(emailType,args[0].lstrip('\\'').rstrip('\\''),emailAttachment)\n\n      # If no error is shown, print ok.\n      print('Email sent!!!')\n\nexcept Exception as e:\n      print('ERROR - %s' % (str(e)))\nfinally:\n      print('\\nPowered by https:\/\/blog.tiraquelibras.com')<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h1 class=\"md-end-block md-heading wp-block-heading\" id=\"Configuraci%C3%B3n\"><span class=\"ez-toc-section\" id=\"Configuracion\"><\/span><span class=\"md-plain\">Configuraci\u00f3n<\/span><span class=\"ez-toc-section-end\"><\/span><\/h1>\n\n\n\n<h2 class=\"md-end-block md-heading wp-block-heading\" id=\"Dentro-del-ejecutable\"><span class=\"ez-toc-section\" id=\"Dentro_del_ejecutable\"><\/span><span class=\"md-plain\">Dentro del ejecutable<\/span><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Dentro del archivo <strong><span class=\"md-plain\">envio.py<\/span><\/strong> tenemos al comienzo la secci\u00f3n <strong><span class=\"md-plain\">VARIABLES<\/span><\/strong> en donde podemos indicar los datos de acceso al buz\u00f3n de correo para realizar el env\u00edo, incluido\/s el\/los destinatario\/s del mensaje.<\/span><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\"># Email server.\nemailHost = ''\n# Int.\nemailPort = 25\n# True\/False.\nemailTLS = False\nemailSSL = False\n# Email credentials.\nemailUser = ''\nemailPwd = ''\n# Email subject.\nemailSubject = ''\n# Email From info.\nemailFrom = ''\n# Email To and CC.\nemailTo = ''\nemailToCc = ''\n# Attachment\/s.\nemailAttachment = ''\n# Replay header.\nemailReplyTo = ''<\/code><\/pre>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">En esta secci\u00f3n configuramos:<\/span><\/p>\n\n\n\n<ul class=\"ul-list wp-block-list\"><li><strong>emailHost<\/strong> Servidor de email. <\/li><li><strong>emailPort <\/strong>Puerto del servidor de email. <\/li><li><strong>emailSSL\/emailTLS<\/strong> Seguridad SSL\/TLS o STARTTLS, si tuviera alguno.<\/li><li><strong>emailUser\/emailPwd <\/strong>Credenciales del buz\u00f3n para realizar el env\u00edo. <\/li><li><strong>emailSubject<\/strong> Asunto del mensaje. <\/li><li><strong>emailFrom<\/strong> Informaci\u00f3n del origen o From. <\/li><li><strong>emailTo\/emailCc<\/strong> Destinatarios y destinatarios en copia. <\/li><li><strong>emailAttachment<\/strong> Adjuntos, si los tuviera. <\/li><li><strong>emailReplyTo<\/strong> Cabecera de respuesta. <\/li><\/ul>\n\n\n\n<h2 class=\"md-end-block md-heading wp-block-heading\" id=\"help\"><span class=\"ez-toc-section\" id=\"Usando_las_opciones_del_programa_prioritario\"><\/span><span class=\"md-plain\">Usando las opciones del programa (prioritario)<\/span><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Tambi\u00e9n podemos indicar estos par\u00e1metros en las opciones del programa, <\/span><span class=\"\"><strong><u><span class=\"md-html-inline\" spellcheck=\"false\"><span class=\"md-plain\" style=\"color: #ff0000;\">las cuales tienen prioridad sobre lo que se configure en el archivo, comentado justo encima de estas l\u00edneas, en la secci\u00f3n&nbsp;<\/span><span class=\" md-link\"><a class=\"md-inner-link\" spellcheck=\"false\" href=\"#Dentro-del-ejecutable\"><span class=\"md-plain\">Dentro del ejecutable<\/span><\/a><\/span><\/span><\/u><\/strong><\/span><span class=\"md-plain\">.<\/span><\/p>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Estas ser\u00edan las opciones:<\/span><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">Options:\n--version             show program's version number and exit\n-h, --help           show this help message and exit\n-H HOST, --host=HOST SMTP server.\n-p PORT, --port=PORT SMTP port.\n--tls                 TLS security on.\n--ssl                 SSL security on.\n--nosecurity         No TLS or SSL security.\n-u USERNAME, --username=USERNAME\n                      Username login.\n-P PASSWORD, --password=PASSWORD\n                      Password login.\n-s SUBJECT, --subject=SUBJECT\n                      Email subject, between double quotes (\"\").\n-f EMAILFROM, --from=EMAILFROM\n                      Email from. Different than Username could be\n                      considered as Email Spoofing. If it is not defined it\n                      will be the same than the user name.\n-t EMAILTO, --to=EMAILTO\n                      Email destination. More than one separated by comas\n                      (,), with no white spaces.\n-c EMAILTOCC, --carboncopy=EMAILTOCC\n                      Email destination copy. More than one separated by\n                      comas (,), with no white spaces.\n-a EMAILATTACHMENT, --attachment=EMAILATTACHMENT\n                      Attach a file or files, separated by comas (,) and\n                      between double quotes (\"\").\n-r EMAILREPLYTO, --replyto=EMAILREPLYTO\n                      Email to reply. If it is not defined it will be the\n                      email from.<\/code><\/pre>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">El listado de opciones mostradas son las siguientes:<\/span><\/p>\n\n\n\n<figure class=\"wp-block-table is-style-regular\"><table class=\"has-subtle-light-gray-background-color has-fixed-layout has-background\"><thead><tr><th>Opci\u00f3n<\/th><th>Variante<\/th><th class=\"has-text-align-left\" data-align=\"left\">Descripci\u00f3n<\/th><\/tr><\/thead><tbody><tr><td><\/td><td>&#8211;version<\/td><td class=\"has-text-align-left\" data-align=\"left\">Muestra la versi\u00f3n del programa.<\/td><\/tr><tr><td>-h<\/td><td>&#8211;help<\/td><td class=\"has-text-align-left\" data-align=\"left\">Muestra la ayuda del programa.<\/td><\/tr><tr><td>-H&nbsp;&lt;host&gt;<\/td><td>&#8211;host=&lt;host&gt;<\/td><td class=\"has-text-align-left\" data-align=\"left\">Servidor de correo para realizar el env\u00edo.<\/td><\/tr><tr><td>-p&nbsp;&lt;port&gt;<\/td><td>&#8211;port=&lt;port&gt;<\/td><td class=\"has-text-align-left\" data-align=\"left\">Puerto del servidor de correo.<\/td><\/tr><tr><td><\/td><td>&#8211;tls<\/td><td class=\"has-text-align-left\" data-align=\"left\">Seguridad STARTTLS.<\/td><\/tr><tr><td><\/td><td>&#8211;ssl<\/td><td class=\"has-text-align-left\" data-align=\"left\">Seguridad SSL.<\/td><\/tr><tr><td><\/td><td>&#8211;nosecurity<\/td><td class=\"has-text-align-left\" data-align=\"left\">Anular cualquier tipo de seguridad.<\/td><\/tr><tr><td>-u<br>&nbsp;&lt;username&gt;<\/td><td>&#8211;username=&lt;username&gt;<\/td><td class=\"has-text-align-left\" data-align=\"left\">Login de usuario.<\/td><\/tr><tr><td>-P&nbsp;&lt;passwd&gt;<\/td><td>&#8211;password=&lt;passwd&gt;<\/td><td class=\"has-text-align-left\" data-align=\"left\">Contrase\u00f1a de usuario.<\/td><\/tr><tr><td>-s&nbsp;&lt;subject&gt;<\/td><td>&#8211;subject=&lt;subject&gt;<\/td><td class=\"has-text-align-left\" data-align=\"left\">Asunto del mensaje.<\/td><\/tr><tr><td>-f&nbsp;&lt;from&gt;<\/td><td>&#8211;from=&lt;from&gt;<\/td><td class=\"has-text-align-left\" data-align=\"left\">Informaci\u00f3n del From del mensaje.<\/td><\/tr><tr><td>-t&nbsp;&lt;to&gt;<\/td><td>&#8211;to=&lt;to&gt;<\/td><td class=\"has-text-align-left\" data-align=\"left\">Destinatario\/s, separados por comas (,).<\/td><\/tr><tr><td>-c&nbsp;&lt;cc&gt;<\/td><td>&#8211;carboncopy=&lt;cc&gt;<\/td><td class=\"has-text-align-left\" data-align=\"left\">Destinatario\/s en copia, separados por comas(,).<\/td><\/tr><tr><td>-a &lt;file\/s&gt;<\/td><td>&#8211;attachment=&lt;file\/s&gt;<\/td><td class=\"has-text-align-left\" data-align=\"left\">Archivo\/s adjunto\/s, separados por comas (,).<\/td><\/tr><tr><td>-r&nbsp;&lt;reply-to&gt;<\/td><td>&#8211;replyto=&lt;reply-to&gt;<\/td><td class=\"has-text-align-left\" data-align=\"left\">Cabecera de respuesta. Si no se indica coincidir\u00e1 con la direcci\u00f3n de&nbsp;<em>From<\/em>.<\/td><\/tr><\/tbody><\/table><figcaption>Opciones de ejecuci\u00f3n preferentes<\/figcaption><\/figure>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h1 class=\"md-end-block md-heading wp-block-heading\"><span class=\"ez-toc-section\" id=\"Ejecucion\"><\/span><span class=\"md-plain\">Ejecuci\u00f3n<\/span><span class=\"ez-toc-section-end\"><\/span><\/h1>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Para ejecutar el programa utilizamos el siguiente comando:<\/span><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">python3 envio.py &lt;argumento&gt; &lt;opciones&gt;<\/code><\/pre>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Siendo en nuestro caso:<\/span><\/p>\n\n\n\n<ul class=\"ul-list wp-block-list\"><li><strong><span class=\"md-plain\">python3<\/span><\/strong><span class=\"md-plain\" style=\"font-size: inherit;\"> la versi\u00f3n de Python instalada, en nuestro caso python3<\/span>.<\/li><li><strong>envio.py <\/strong>es el archivo que contiene nuestro c\u00f3digo del programa.<\/li><li><strong>&lt;<span class=\"md-plain\">argumento<\/span>&gt;<\/strong><span class=\"md-plain\" style=\"font-size: inherit;\"> archivo.html o archivo.txt<\/span> con el contenido del email. <\/li><li><strong>&lt;<span class=\"md-plain\">opciones<\/span>&gt;<\/strong><span class=\"md-plain\" style=\"font-size: inherit;\"> las opciones que veremos m\u00e1s adelante en la ayuda.<\/span> <\/li><\/ul>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Por ejemplo:<\/span><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">python3 envio.py archivo.html<\/code><\/pre>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Para consultar las opciones del programa disponemos de una ayuda contextual agregando la opci\u00f3n <strong><em><span class=\"md-plain\">-h<\/span><\/em><\/strong> o <strong><em><span class=\"md-plain\">&#8211;help<\/span><\/em><\/strong>. <strong><u><span class=\"md-html-inline\" spellcheck=\"false\"><span class=\"md-plain\" style=\"color: #ff0000;\">Recordar que estas tienen prioridad sobre las variables configuradas en el mismo ejecutable, comentado en la secci\u00f3n anterior de&nbsp;<\/span><span class=\" md-link\"><a class=\"md-inner-link\" spellcheck=\"false\" href=\"#Configuraci%C3%B3n\"><span class=\"md-plain\">Configuraci\u00f3n<\/span><\/a><\/span><\/span><\/u><\/strong>:<\/span><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">python3 envio.py archivo.html --help<\/code><\/pre>\n\n\n\n<p class=\"md-end-block md-p\">La explicaci\u00f3n de cada opci\u00f3n la puedes ver en la <a href=\"#help\">secci\u00f3n anterior<\/a>.<\/p>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Indicar que las opciones en formato <strong><em><span class=\"md-plain\">string<\/span><\/em><\/strong> no deben de contener espacios en blanco, o si los contienen como por ejemplo el <strong><span class=\"md-plain\">asunto<\/span><\/strong> se deben de utilizar comillas dobles (<strong><span class=\"md-plain\">\u00bb \u00ab<\/span><\/strong>), <\/span><u><span class=\"md-plain\"><strong>nunca usar comillas simples (<span class=\"md-plain\">&#8216; &#8216;<\/span>)<\/strong><\/span><\/u><span class=\"md-plain\">. El programa est\u00e1 dise\u00f1ado para sustituirlas, pero puede que alg\u00fan caso no se hubiera contemplado, dando un error como resultado final. Por ejemplo, si queremos enviar a m\u00e1s de un destinatario podemos indicar las direcciones sin comillas dobles y sin espacios en blanco:<\/span><\/p>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-link\" spellcheck=\"false\"><a href=\"mailto:email1@example.org\">email1@example.org<\/a><\/span><span class=\"md-plain\">,<\/span><span class=\"md-link\" spellcheck=\"false\"><a href=\"mailto:email2@example.org\">email2@example.org<\/a><\/span><\/p>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">O con comilla dobles, por ejemplo si usamos espacios como en el asunto:<\/span><\/p>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">\u00ab<\/span><span class=\"md-link\" spellcheck=\"false\"><a href=\"mailto:email1@example.org\">email1@example.org<\/a><\/span><span class=\"md-plain\">,<\/span><span class=\"md-link\" spellcheck=\"false\"><a href=\"mailto:email2@example.org\">email2@example.org<\/a><\/span><span class=\"md-plain\">\u00ab<\/span><\/p>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Para mostrar la versi\u00f3n del programa ejecutamos el comando:<\/span><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">python envio.py --version<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h1 class=\"md-fences md-end-block ty-contain-cm modeLoaded wp-block-heading\"><span class=\"ez-toc-section\" id=\"Ejemplo\"><\/span><span class=\"md-plain md-expand\">Ejemplo<\/span><span class=\"ez-toc-section-end\"><\/span><\/h1>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Creamos un archivo <strong><span class=\"md-plain\">prueba.html<\/span><\/strong> con el siguiente contenido:<\/span><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"markup\" class=\"language-markup\">&lt;!DOCTYPE html&gt;\n&lt;html lang=\"en\"&gt;\n&lt;head&gt;\n   &lt;meta charset=\"UTF-8\"&gt;\n   &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"&gt;\n   &lt;meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\"&gt;\n   &lt;title&gt;Document&lt;\/title&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n   &lt;h1&gt;Email de prueba&lt;\/h1&gt;\n   &lt;hr&gt;\n   &lt;p&gt;Esto es un email de prueba.&lt;\/p&gt;\n   &lt;br&gt;\n   &lt;p&gt;Saludos&lt;\/p&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Y lo enviamos ejecutando el comando de la siguiente forma, sin usar opciones, \u00fanicamente con las variables configuradas en el ejecutable:<\/span><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">python envio.py prueba.html<\/code><\/pre>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Siendo el resultado el siguiente:<\/span><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">$ python envio.py prueba.html\nEmail sent!!!\n\u200b\nPowered by https:\/\/blog.tiraquelibras.com<\/code><\/pre>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Y en el destino se ver\u00eda de la siguiente forma:<\/span><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"520\" height=\"337\" src=\"https:\/\/blog.tiraquelibras.com\/wp-content\/uploads\/2020\/02\/1.jpg\" alt=\"\" class=\"wp-image-799\"\/><figcaption>Ejemplo de env\u00edo<\/figcaption><\/figure><\/div>\n\n\n\n<p class=\"md-end-block md-p\"><span class=\"md-plain\">Lo mismo con un archivo de texto con extensi\u00f3n <\/span><span class=\"\"><strong><span class=\"md-plain\">.txt<\/span><\/strong><\/span><span class=\"md-plain md-expand\"> y texto plano en su interior.<\/span><\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h1 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Enlaces_de_interes\"><\/span>Enlaces de inter\u00e9s<span class=\"ez-toc-section-end\"><\/span><\/h1>\n\n\n\n<p>Acceso al <a href=\"https:\/\/bitbucket.org\/sergiobr\/smtp-contenido-html-o-texto-plano-desde-python\/src\/master\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\" class=\"external external_icon\">repositorio en BitBucket.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Programa desarrollado en&nbsp;Python 3 para el env\u00edo de mensajes con contenido&nbsp;HMTL o Texto plano y con soporte para SSL\/TLS o&nbsp;STARTTLS&nbsp;y archivos adjuntos. Introducci\u00f3n Programa para<span class=\"read-more-link\"><a class=\"read-more\" href=\"https:\/\/blog.tiraquelibras.com\/?p=797\">Read More<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":582,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,22],"tags":[99,27,98],"class_list":["post-797","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programacion","category-ti","tag-html","tag-python","tag-smtp"],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/posts\/797","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=797"}],"version-history":[{"count":0,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/posts\/797\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/media\/582"}],"wp:attachment":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=797"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=797"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=797"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}