{"id":"c10d2e9d-9a84-45c3-8e97-67cc625dae70","shortId":"SwpTpf","kind":"skill","title":"send-email-programmatically","tagline":"Send emails via SMTP, free APIs, or privacy-focused services. Use when: (1) Sending notifications and alerts, (2) Automated reports and summaries, (3) User communication workflows, or (4) Error logging via email.","description":"# Send Email Programmatically\n\nSend emails via SMTP, free APIs (Mailgun, SendGrid free tier), or privacy-focused services. Essential for notifications, alerts, automated reports, and user communication.\n\n## When to use\n\n- Use case 1: When the user asks to send email notifications or alerts\n- Use case 2: When you need to deliver automated reports or summaries\n- Use case 3: For error logging and monitoring alerts\n- Use case 4: When building user communication workflows (confirmations, updates)\n\n## Required tools / APIs\n\n- **curl** — For API-based email sending (pre-installed on most systems)\n- **sendmail** / **msmtp** — For SMTP email sending\n- **Mailgun API** — Free tier: 5,000 emails/month (requires API key)\n- **SendGrid API** — Free tier: 100 emails/day (requires API key)\n- **mail.tm** — Temporary email API (no API key required)\n\nInstall options:\n\n```bash\n# Ubuntu/Debian\nsudo apt-get install -y curl msmtp msmtp-mta\n\n# macOS (postfix is pre-installed, or use msmtp)\nbrew install msmtp\n\n# Node.js\nnpm install nodemailer\n```\n\n## Skills\n\n### send_email_via_smtp_curl\n\nSend email using SMTP via curl (works with Gmail, Outlook, custom SMTP servers).\n\n```bash\n# Gmail SMTP example (requires app password)\nSMTP_SERVER=\"smtp.gmail.com:587\"\nFROM_EMAIL=\"your-email@gmail.com\"\nTO_EMAIL=\"recipient@example.com\"\nSUBJECT=\"Test Email\"\nBODY=\"This is a test email sent via SMTP.\"\nAPP_PASSWORD=\"your-app-password\"\n\n# Send email\ncurl -v --url \"smtp://${SMTP_SERVER}\" \\\n  --mail-from \"${FROM_EMAIL}\" \\\n  --mail-rcpt \"${TO_EMAIL}\" \\\n  --user \"${FROM_EMAIL}:${APP_PASSWORD}\" \\\n  --upload-file - <<EOF\nFrom: ${FROM_EMAIL}\nTo: ${TO_EMAIL}\nSubject: ${SUBJECT}\n\n${BODY}\nEOF\n\n# Outlook/Office365 SMTP\ncurl --url \"smtp://smtp.office365.com:587\" \\\n  --mail-from \"your-email@outlook.com\" \\\n  --mail-rcpt \"recipient@example.com\" \\\n  --user \"your-email@outlook.com:your-password\" \\\n  --ssl-reqd \\\n  --upload-file - <<EOF\nFrom: your-email@outlook.com\nTo: recipient@example.com\nSubject: Hello from Outlook\n\nThis is an automated email.\nEOF\n```\n\n### send_email_via_mailgun_api\n\nSend email using Mailgun free tier (5,000 emails/month, no credit card required for sandbox).\n\n```bash\n# Set your Mailgun credentials\nMAILGUN_API_KEY=\"your-mailgun-api-key\"\nMAILGUN_DOMAIN=\"sandbox123.mailgun.org\"  # or your verified domain\n\n# Send email\ncurl -s --user \"api:${MAILGUN_API_KEY}\" \\\n  \"https://api.mailgun.net/v3/${MAILGUN_DOMAIN}/messages\" \\\n  -F from=\"Sender Name <mailgun@${MAILGUN_DOMAIN}>\" \\\n  -F to=\"recipient@example.com\" \\\n  -F subject=\"Hello from Mailgun\" \\\n  -F text=\"This is the plain text body\" \\\n  -F html=\"<h1>HTML Email</h1><p>This is the HTML body</p>\"\n\n# Send with attachment\ncurl -s --user \"api:${MAILGUN_API_KEY}\" \\\n  \"https://api.mailgun.net/v3/${MAILGUN_DOMAIN}/messages\" \\\n  -F from=\"notifications@${MAILGUN_DOMAIN}\" \\\n  -F to=\"user@example.com\" \\\n  -F subject=\"Report Attached\" \\\n  -F text=\"Please find the report attached.\" \\\n  -F attachment=@./report.pdf\n```\n\n**Node.js:**\n\n```javascript\nasync function sendEmailMailgun(options) {\n  const { apiKey, domain, from, to, subject, text, html } = options;\n  \n  const formData = new URLSearchParams({\n    from,\n    to,\n    subject,\n    text: text || '',\n    html: html || ''\n  });\n  \n  const auth = 'Basic ' + Buffer.from(`api:${apiKey}`).toString('base64');\n  \n  const res = await fetch(`https://api.mailgun.net/v3/${domain}/messages`, {\n    method: 'POST',\n    headers: {\n      'Authorization': auth,\n      'Content-Type': 'application/x-www-form-urlencoded'\n    },\n    body: formData\n  });\n  \n  if (!res.ok) {\n    const error = await res.text();\n    throw new Error(`Mailgun API error: ${error}`);\n  }\n  \n  return await res.json();\n}\n\n// Usage\n// sendEmailMailgun({\n//   apiKey: 'your-mailgun-api-key',\n//   domain: 'sandbox123.mailgun.org',\n//   from: 'Sender <mailgun@sandbox123.mailgun.org>',\n//   to: 'recipient@example.com',\n//   subject: 'Test Email',\n//   text: 'Plain text body',\n//   html: '<h1>HTML body</h1>'\n// }).then(result => console.log('Email sent:', result));\n```\n\n### send_email_via_sendgrid_api\n\nSend email using SendGrid free tier (100 emails/day).\n\n```bash\n# Set your SendGrid API key\nSENDGRID_API_KEY=\"your-sendgrid-api-key\"\n\n# Send email\ncurl -s --request POST \\\n  --url \"https://api.sendgrid.com/v3/mail/send\" \\\n  --header \"Authorization: Bearer ${SENDGRID_API_KEY}\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\n    \"personalizations\": [{\n      \"to\": [{\"email\": \"recipient@example.com\"}],\n      \"subject\": \"Hello from SendGrid\"\n    }],\n    \"from\": {\"email\": \"sender@example.com\", \"name\": \"Sender Name\"},\n    \"content\": [{\n      \"type\": \"text/plain\",\n      \"value\": \"This is the email body.\"\n    }]\n  }'\n\n# Send HTML email with attachment\ncurl -s --request POST \\\n  --url \"https://api.sendgrid.com/v3/mail/send\" \\\n  --header \"Authorization: Bearer ${SENDGRID_API_KEY}\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\n    \"personalizations\": [{\n      \"to\": [{\"email\": \"user@example.com\"}]\n    }],\n    \"from\": {\"email\": \"notifications@example.com\"},\n    \"subject\": \"Weekly Report\",\n    \"content\": [{\n      \"type\": \"text/html\",\n      \"value\": \"<h1>Weekly Report</h1><p>Attached is your report.</p>\"\n    }],\n    \"attachments\": [{\n      \"content\": \"'\"$(base64 -w 0 report.pdf)\"'\",\n      \"filename\": \"report.pdf\",\n      \"type\": \"application/pdf\"\n    }]\n  }'\n```\n\n**Node.js:**\n\n```javascript\nasync function sendEmailSendGrid(options) {\n  const { apiKey, from, to, subject, text, html, attachments = [] } = options;\n  \n  const payload = {\n    personalizations: [{\n      to: [{ email: to }],\n      subject\n    }],\n    from: { email: from },\n    content: [{\n      type: html ? 'text/html' : 'text/plain',\n      value: html || text\n    }]\n  };\n  \n  if (attachments.length > 0) {\n    payload.attachments = attachments.map(att => ({\n      content: att.content,  // base64 string\n      filename: att.filename,\n      type: att.type || 'application/octet-stream'\n    }));\n  }\n  \n  const res = await fetch('https://api.sendgrid.com/v3/mail/send', {\n    method: 'POST',\n    headers: {\n      'Authorization': `Bearer ${apiKey}`,\n      'Content-Type': 'application/json'\n    },\n    body: JSON.stringify(payload)\n  });\n  \n  if (!res.ok) {\n    const error = await res.text();\n    throw new Error(`SendGrid API error: ${error}`);\n  }\n  \n  return { success: true, status: res.status };\n}\n\n// Usage\n// sendEmailSendGrid({\n//   apiKey: 'your-sendgrid-api-key',\n//   from: 'sender@example.com',\n//   to: 'recipient@example.com',\n//   subject: 'Test Email',\n//   html: '<h1>Hello</h1><p>This is a test.</p>'\n// }).then(result => console.log('Email sent:', result));\n```\n\n### send_email_via_msmtp\n\nSend email using msmtp (lightweight SMTP client, good for automation).\n\n```bash\n# Configure msmtp (one-time setup)\ncat > ~/.msmtprc <<EOF\ndefaults\nauth           on\ntls            on\ntls_trust_file /etc/ssl/certs/ca-certificates.crt\nlogfile        ~/.msmtp.log\n\n# Gmail account\naccount        gmail\nhost           smtp.gmail.com\nport           587\nfrom           your-email@gmail.com\nuser           your-email@gmail.com\npassword       your-app-password\n\n# Set default account\naccount default : gmail\nEOF\n\nchmod 600 ~/.msmtprc\n\n# Send email\necho -e \"Subject: Test Email\\nFrom: your-email@gmail.com\\nTo: recipient@example.com\\n\\nThis is the email body.\" | msmtp recipient@example.com\n\n# Send email with file content\ncat report.txt | msmtp -t <<EOF\nTo: recipient@example.com\nFrom: sender@gmail.com\nSubject: Daily Report\n\n$(cat report.txt)\nEOF\n\n# Send HTML email\nmsmtp recipient@example.com <<EOF\nTo: recipient@example.com\nFrom: sender@gmail.com\nSubject: HTML Email\nContent-Type: text/html\n\n<html>\n<body>\n  <h1>Hello</h1>\n  <p>This is an HTML email.</p>\n</body>\n</html>\nEOF\n```\n\n### send_email_nodejs_nodemailer\n\nSend email using Node.js nodemailer library (supports all SMTP servers).\n\n**Node.js:**\n\n```javascript\nconst nodemailer = require('nodemailer');\n\nasync function sendEmail(config) {\n  const {\n    smtpHost,\n    smtpPort,\n    smtpUser,\n    smtpPassword,\n    from,\n    to,\n    subject,\n    text,\n    html,\n    attachments = []\n  } = config;\n  \n  // Create transporter\n  const transporter = nodemailer.createTransport({\n    host: smtpHost,\n    port: smtpPort,\n    secure: smtpPort === 465, // true for 465, false for other ports\n    auth: {\n      user: smtpUser,\n      pass: smtpPassword\n    },\n    connectionTimeout: 10000\n  });\n  \n  // Send email\n  const info = await transporter.sendMail({\n    from,\n    to,\n    subject,\n    text,\n    html,\n    attachments: attachments.map(att => ({\n      filename: att.filename,\n      path: att.path || undefined,\n      content: att.content || undefined\n    }))\n  });\n  \n  return {\n    success: true,\n    messageId: info.messageId,\n    response: info.response\n  };\n}\n\n// Usage - Gmail\n// sendEmail({\n//   smtpHost: 'smtp.gmail.com',\n//   smtpPort: 587,\n//   smtpUser: 'your-email@gmail.com',\n//   smtpPassword: 'your-app-password',\n//   from: '\"Sender Name\" <your-email@gmail.com>',\n//   to: 'recipient@example.com',\n//   subject: 'Hello',\n//   text: 'Plain text body',\n//   html: '<b>HTML body</b>',\n//   attachments: [\n//     { filename: 'report.pdf', path: './report.pdf' }\n//   ]\n// }).then(result => console.log('Email sent:', result));\n\n// Usage - Outlook\n// sendEmail({\n//   smtpHost: 'smtp.office365.com',\n//   smtpPort: 587,\n//   smtpUser: 'your-email@outlook.com',\n//   smtpPassword: 'your-password',\n//   from: 'your-email@outlook.com',\n//   to: 'recipient@example.com',\n//   subject: 'Test',\n//   text: 'This is a test email'\n// });\n```\n\n### advanced_email_with_retry\n\nProduction-ready email sending with retry logic and error handling.\n\n```bash\n#!/bin/bash\nsend_email_with_retry() {\n  local TO=\"$1\"\n  local SUBJECT=\"$2\"\n  local BODY=\"$3\"\n  local MAX_RETRIES=3\n  local RETRY_DELAY=5\n  \n  for i in $(seq 1 $MAX_RETRIES); do\n    if curl -fsS --max-time 30 \\\n      --url \"smtp://smtp.gmail.com:587\" \\\n      --mail-from \"sender@gmail.com\" \\\n      --mail-rcpt \"$TO\" \\\n      --user \"sender@gmail.com:app-password\" \\\n      --upload-file - <<EOF\nFrom: sender@gmail.com\nTo: $TO\nSubject: $SUBJECT\n\n$BODY\nEOF\n    then\n      echo \"Email sent successfully to $TO\"\n      return 0\n    else\n      echo \"Attempt $i failed, retrying in ${RETRY_DELAY}s...\" >&2\n      sleep $RETRY_DELAY\n    fi\n  done\n  \n  echo \"Failed to send email after $MAX_RETRIES attempts\" >&2\n  return 1\n}\n\n# Usage\nsend_email_with_retry \"user@example.com\" \"Alert\" \"System CPU usage is high\"\n```\n\n**Node.js:**\n\n```javascript\nasync function sendEmailWithRetry(config, maxRetries = 3) {\n  const { provider, ...emailConfig } = config;\n  \n  for (let attempt = 1; attempt <= maxRetries; attempt++) {\n    try {\n      let result;\n      \n      if (provider === 'mailgun') {\n        result = await sendEmailMailgun(emailConfig);\n      } else if (provider === 'sendgrid') {\n        result = await sendEmailSendGrid(emailConfig);\n      } else {\n        throw new Error(`Unknown provider: ${provider}`);\n      }\n      \n      return { success: true, attempt, result };\n      \n    } catch (err) {\n      console.error(`Attempt ${attempt} failed:`, err.message);\n      \n      if (attempt === maxRetries) {\n        throw new Error(`Failed to send email after ${maxRetries} attempts: ${err.message}`);\n      }\n      \n      // Exponential backoff\n      const delayMs = Math.min(1000 * Math.pow(2, attempt - 1), 10000);\n      await new Promise(resolve => setTimeout(resolve, delayMs));\n    }\n  }\n}\n\n// Usage\n// sendEmailWithRetry({\n//   provider: 'mailgun',\n//   apiKey: 'your-api-key',\n//   domain: 'sandbox123.mailgun.org',\n//   from: 'sender@sandbox123.mailgun.org',\n//   to: 'recipient@example.com',\n//   subject: 'Critical Alert',\n//   text: 'System requires attention'\n// }, 3).then(result => console.log('Email sent:', result));\n```\n\n## Rate limits / Best practices\n\n- ✅ **Use app passwords** — For Gmail/Outlook, create app-specific passwords instead of account passwords\n- ✅ **Free tier limits** — Mailgun: 5,000/month, SendGrid: 100/day, Gmail: 500/day\n- ✅ **Retry logic** — Implement exponential backoff for failed sends\n- ✅ **Error handling** — Catch and log errors, don't expose credentials in logs\n- ✅ **Validate emails** — Check recipient email format before sending\n- ✅ **SPF/DKIM** — Configure DNS records for custom domains to avoid spam\n- ⚠️ **Never hardcode credentials** — Use environment variables or secure vaults\n- ⚠️ **Rate limiting** — Add delays between bulk sends (1-2 seconds)\n- ⚠️ **Bounce handling** — Monitor bounces and remove invalid addresses\n\n## Agent prompt\n\n```text\nYou have email sending capability via SMTP and free APIs. When a user asks to send an email:\n\n1. Choose the best method based on requirements:\n   - **curl + SMTP** — For simple emails with Gmail/Outlook (requires app password)\n   - **Mailgun API** — For higher volume (5,000/month free, requires API key)\n   - **SendGrid API** — For moderate volume (100/day free, requires API key)\n   - **msmtp** — For automated scripts and cron jobs\n   - **nodemailer** — For Node.js applications with full SMTP support\n\n2. For Gmail/Outlook SMTP:\n   - Gmail: smtp.gmail.com:587 (requires app password from Google Account settings)\n   - Outlook: smtp.office365.com:587\n   - Always use app passwords, never account passwords\n\n3. For Mailgun:\n   - Free sandbox domain: 5,000 emails/month to authorized recipients\n   - Verified domain: Unlimited recipients (within free tier limits)\n   - No credit card required for sandbox\n\n4. For SendGrid:\n   - Free tier: 100 emails/day\n   - Requires account signup and API key\n\n5. Always:\n   - Validate recipient email format\n   - Use environment variables for credentials\n   - Implement retry logic (3 attempts with exponential backoff)\n   - Handle errors gracefully with clear messages\n   - Never log credentials or sensitive data\n\n6. Security:\n   - Store SMTP passwords in ~/.msmtprc (chmod 600) or environment variables\n   - Use TLS/SSL for all SMTP connections\n   - Validate and sanitize email content to prevent injection\n```\n\n## Troubleshooting\n\n**Error: \"authentication failed\" (Gmail)**\n- Symptom: SMTP auth fails with Gmail account password\n- Solution: Generate an app password at https://myaccount.google.com/apppasswords (requires 2FA enabled)\n\n**Error: \"530 5.7.0 Must issue a STARTTLS command first\"**\n- Symptom: Server requires TLS encryption\n- Solution: Add `--ssl-reqd` to curl command or use port 587/465\n\n**Error: \"554 5.7.1 Relay access denied\"**\n- Symptom: SMTP server rejects email relay\n- Solution: Authenticate with correct credentials, ensure FROM email matches authenticated account\n\n**Mailgun: \"Free accounts are for test purposes only\"**\n- Symptom: Mailgun sandbox restricts recipients\n- Solution: Add authorized recipients in Mailgun dashboard, or verify a custom domain\n\n**SendGrid: \"403 Forbidden\"**\n- Symptom: API key lacks permissions\n- Solution: Create new API key with \"Mail Send\" permissions in SendGrid dashboard\n\n**Emails going to spam:**\n- Symptom: Recipients don't receive emails or they're in spam folder\n- Solution: Configure SPF, DKIM, DMARC DNS records for custom domains; use verified sender emails\n\n**Timeout errors:**\n- Symptom: SMTP connection hangs or times out\n- Solution: Check firewall allows outbound connections on ports 587/465; increase timeout to 30 seconds\n\n## See also\n\n- [../using-telegram-bot/SKILL.md](../using-telegram-bot/SKILL.md) — Alternative notification method via Telegram\n- [../nostr-logging-system/SKILL.md](../nostr-logging-system/SKILL.md) — Decentralized logging alternative\n- [../user-aks-for-report/SKILL.md](../user-aks-for-report/SKILL.md) — Generate reports that can be emailed","tags":["send","email","programmatically","open","skills","besoeasy","agent-skills","ai-agents","claude-code","clawdbot","clawdbot-skill","llm-tools"],"capabilities":["skill","source-besoeasy","skill-send-email-programmatically","topic-agent-skills","topic-ai-agents","topic-claude-code","topic-clawdbot","topic-clawdbot-skill","topic-llm-tools","topic-mcp-server","topic-openai","topic-openclaw","topic-vibe-coding","topic-vibecoding"],"categories":["open-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/besoeasy/open-skills/send-email-programmatically","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add besoeasy/open-skills","source_repo":"https://github.com/besoeasy/open-skills","install_from":"skills.sh"}},"qualityScore":"0.505","qualityRationale":"deterministic score 0.51 from registry signals: · indexed on github topic:agent-skills · 111 github stars · SKILL.md body (15,626 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-02T12:55:04.676Z","embedding":null,"createdAt":"2026-04-18T22:10:53.388Z","updatedAt":"2026-05-02T12:55:04.676Z","lastSeenAt":"2026-05-02T12:55:04.676Z","tsv":"'-2':1396 '/.msmtp.log':820 '/.msmtprc':808,847,1579 '/apppasswords':1620 '/bin/bash':1083 '/etc/ssl/certs/ca-certificates.crt':818 '/messages':374,422,487 '/nostr-logging-system/skill.md':1780,1781 '/report.pdf':444,1035 '/user-aks-for-report/skill.md':1785,1786 '/using-telegram-bot/skill.md':1773,1774 '/v3/$':371,419,485 '/v3/mail/send':582,630 '/v3/mail/send'',':727 '0':667,708,1155 '000':139,332,1510 '000/month':1336,1451 '1':18,70,1090,1109,1183,1211,1275,1395,1427 '100':148,557,1534 '100/day':1338,1461 '1000':1271 '10000':972,1276 '2':23,83,1093,1166,1181,1273,1481 '2fa':1622 '3':28,95,1096,1100,1203,1306,1503,1556 '30':1119,1769 '4':33,104,1529 '403':1699 '465':958,961 '5':138,331,1104,1335,1450,1509,1542 '5.7.0':1626 '5.7.1':1652 '500/day':1340 '530':1625 '554':1651 '587':828,1008,1048 '587/465':1649,1765 '6':1573 '600':846,1581 'access':1654 'account':822,823,840,841,1329,1492,1501,1537,1610,1672,1675 'add':1390,1639,1687 'address':1405 'advanc':1067 'agent':1406 'alert':22,59,80,101,1190,1301 'allow':1760 'also':1772 'altern':1775,1784 'alway':1496,1543 'api':10,46,114,118,135,142,145,151,156,158,324,346,351,365,367,413,415,475,509,521,550,563,566,571,587,635,751,765,1291,1418,1446,1454,1457,1464,1540,1702,1709 'api-bas':117 'api.mailgun.net':370,418,484 'api.mailgun.net/v3/$':369,417,483 'api.sendgrid.com':581,629,726 'api.sendgrid.com/v3/mail/send':580,628 'api.sendgrid.com/v3/mail/send'',':725 'apikey':452,476,517,680,733,761,1288 'app':216,239,243,265,836,1014,1133,1318,1324,1443,1488,1498,1615 'app-password':1132 'app-specif':1323 'applic':1476 'application/json':593,641,737 'application/octet-stream':720 'application/pdf':672 'application/x-www-form-urlencoded':496 'apt':167 'apt-get':166 'ask':74,1422 'async':447,675,931,1198 'att':711,986 'att.content':713,993 'att.filename':717,988 'att.path':990 'att.type':719 'attach':409,434,441,443,622,659,663,686,945,984,1031 'attachments.length':707 'attachments.map':710,985 'attempt':1158,1180,1210,1212,1214,1243,1248,1249,1253,1264,1274,1557 'attent':1305 'auth':472,492,811,966,1606 'authent':1601,1663,1671 'author':491,584,632,731,1513,1688 'autom':24,60,89,317,799,1468 'avoid':1377 'await':481,503,513,723,745,977,1222,1230,1277 'backoff':1267,1345,1560 'base':119,1432 'base64':478,665,714 'bash':163,211,340,559,800,1082 'basic':473 'bearer':585,633,732 'best':1315,1430 'bodi':230,279,397,406,497,536,539,617,738,864,1027,1030,1095,1145 'bounc':1398,1401 'brew':185 'buffer.from':474 'build':106 'bulk':1393 'capabl':1413 'card':336,1525 'case':69,82,94,103 'cat':807,872,884 'catch':1245,1351 'check':1363,1758 'chmod':845,1580 'choos':1428 'clear':1565 'client':796 'command':1631,1645 'communic':30,64,108 'config':934,946,1201,1207 'configur':801,1370,1735 'confirm':110 'connect':1590,1752,1762 'connectiontimeout':971 'console.error':1247 'console.log':542,782,1038,1309 'const':451,460,471,479,501,679,688,721,743,927,935,949,975,1204,1268 'content':494,591,609,639,653,664,698,712,735,871,901,992,1595 'content-typ':493,590,638,734,900 'correct':1665 'cpu':1192 'creat':947,1322,1707 'credenti':344,1358,1381,1552,1569,1666 'credit':335,1524 'critic':1300 'cron':1471 'curl':115,171,197,203,247,283,362,410,575,623,1114,1435,1644 'custom':208,1374,1696,1742 'daili':882 'dashboard':1692,1717 'data':594,642,1572 'decentr':1782 'default':810,839,842 'delay':1103,1164,1169,1391 'delaym':1269,1283 'deliv':88 'deni':1655 'dkim':1737 'dmarc':1738 'dns':1371,1739 'domain':354,359,373,381,421,427,453,486,523,1293,1375,1508,1516,1697,1743 'done':1171 'e':851 'echo':850,1148,1157,1172 'els':1156,1225,1233 'email':3,6,37,39,42,77,120,132,155,194,199,222,225,229,235,246,256,261,264,273,276,318,321,326,361,401,532,543,547,552,574,597,604,616,620,645,648,692,696,773,783,787,791,849,854,863,868,889,899,909,912,916,974,1039,1066,1068,1074,1085,1149,1176,1186,1261,1310,1362,1365,1411,1426,1439,1546,1594,1660,1669,1718,1727,1747,1792 'emailconfig':1206,1224,1232 'emails/day':149,558,1535 'emails/month':140,333,1511 'enabl':1623 'encrypt':1637 'ensur':1667 'environ':1383,1549,1583 'eof':270,280,305,319,809,844,876,886,892,910,1138,1146 'err':1246 'err.message':1251,1265 'error':34,97,502,507,510,511,744,749,752,753,1080,1236,1257,1349,1354,1562,1600,1624,1650,1749 'essenti':56 'exampl':214 'exponenti':1266,1344,1559 'expos':1357 'f':375,382,385,390,398,423,428,431,435,442 'fail':1160,1173,1250,1258,1347,1602,1607 'fals':962 'fetch':482,724 'fi':1170 'file':269,304,817,870,1137 'filenam':669,716,987,1032 'find':438 'firewal':1759 'first':1632 'focus':14,54 'folder':1733 'forbidden':1700 'format':1366,1547 'formdata':461,498 'free':9,45,49,136,146,329,555,1331,1417,1452,1462,1506,1520,1532,1674 'fss':1115 'full':1478 'function':448,676,932,1199 'generat':1613,1787 'get':168 'gmail':206,212,821,824,843,1003,1339,1485,1603,1609 'gmail/outlook':1321,1441,1483 'go':1719 'good':797 'googl':1491 'grace':1563 'handl':1081,1350,1399,1561 'hang':1753 'hardcod':1380 'header':490,583,589,631,637,730 'hello':311,387,600,775,904,1023 'high':1195 'higher':1448 'host':825,952 'html':399,400,405,458,469,470,537,538,619,685,700,704,774,888,898,908,944,983,1028,1029 'implement':1343,1553 'increas':1766 'info':976 'info.messageid':999 'info.response':1001 'inject':1598 'instal':124,161,169,181,186,190 'instead':1327 'invalid':1404 'issu':1628 'javascript':446,674,926,1197 'job':1472 'json.stringify':739 'key':143,152,159,347,352,368,416,522,564,567,572,588,636,766,1292,1455,1465,1541,1703,1710 'lack':1704 'let':1209,1216 'librari':920 'lightweight':794 'limit':1314,1333,1389,1522 'local':1088,1091,1094,1097,1101 'log':35,98,1353,1360,1568,1783 'logfil':819 'logic':1078,1342,1555 'maco':176 'mail':253,258,287,291,1123,1127,1712 'mail-from':252,286,1122 'mail-rcpt':257,290,1126 'mail.tm':153 'mailgun':47,134,323,328,343,345,350,353,366,372,379,380,389,414,420,426,508,520,1220,1287,1334,1445,1505,1673,1682,1691 'mailgun@sandbox123.mailgun.org':527 'match':1670 'math.min':1270 'math.pow':1272 'max':1098,1110,1117,1178 'max-tim':1116 'maxretri':1202,1213,1254,1263 'messag':1566 'messageid':998 'method':488,728,1431,1777 'moder':1459 'monitor':100,1400 'msmtp':129,172,174,184,187,789,793,802,865,874,890,1466 'msmtp-mta':173 'mta':175 'must':1627 'myaccount.google.com':1619 'myaccount.google.com/apppasswords':1618 'n':859 'name':378,606,608,1018 'need':86 'never':1379,1500,1567 'new':462,506,748,1235,1256,1278,1708 'nfrom':855 'node.js':188,445,673,918,925,1196,1475 'nodej':913 'nodemail':191,914,919,928,930,1473 'nodemailer.createtransport':951 'notif':20,58,78,425,1776 'notifications@example.com':649 'npm':189 'nthis':860 'nto':857 'one':804 'one-tim':803 'option':162,450,459,678,687 'outbound':1761 'outlook':207,313,1043,1494 'outlook/office365':281 'pass':969 'password':217,240,244,266,298,833,837,1015,1054,1134,1319,1326,1330,1444,1489,1499,1502,1577,1611,1616 'path':989,1034 'payload':689,740 'payload.attachments':709 'permiss':1705,1714 'person':595,643,690 'plain':395,534,1025 'pleas':437 'port':827,954,965,1648,1764 'post':489,578,626,729 'postfix':177 'practic':1316 'pre':123,180 'pre-instal':122,179 'prevent':1597 'privaci':13,53 'privacy-focus':12,52 'product':1072 'production-readi':1071 'programmat':4,40 'promis':1279 'prompt':1407 'provid':1205,1219,1227,1238,1239,1286 'purpos':1679 'rate':1313,1388 'rcpt':259,292,1128 're':1730 'readi':1073 'receiv':1726 'recipi':1364,1514,1518,1545,1685,1689,1723 'recipient@example.com':226,293,309,384,529,598,770,858,866,878,891,894,1021,1058,1298 'record':1372,1740 'reject':1659 'relay':1653,1661 'remov':1403 'report':25,61,90,433,440,652,658,662,883,1788 'report.pdf':668,670,1033 'report.txt':873,885 'reqd':301,1642 'request':577,625 'requir':112,141,150,160,215,337,929,1304,1434,1442,1453,1463,1487,1526,1536,1621,1635 'res':480,722 'res.json':514 'res.ok':500,742 'res.status':758 'res.text':504,746 'resolv':1280,1282 'respons':1000 'restrict':1684 'result':541,545,781,785,1037,1041,1217,1221,1229,1244,1308,1312 'retri':1070,1077,1087,1099,1102,1111,1161,1163,1168,1179,1188,1341,1554 'return':512,754,995,1154,1182,1240 'sandbox':339,1507,1528,1683 'sandbox123.mailgun.org':355,524,1294 'sanit':1593 'script':1469 'second':1397,1770 'secur':956,1386,1574 'see':1771 'send':2,5,19,38,41,76,121,133,193,198,245,320,325,360,407,546,551,573,618,786,790,848,867,887,911,915,973,1075,1084,1175,1185,1260,1348,1368,1394,1412,1424,1713 'send-email-programmat':1 'sendemail':933,1004,1044 'sendemailmailgun':449,516,1223 'sendemailsendgrid':677,760,1231 'sendemailwithretri':1200,1285 'sender':377,526,607,1017,1746 'sender@example.com':605,768 'sender@gmail.com':880,896,1125,1131,1140 'sender@sandbox123.mailgun.org':1296 'sendgrid':48,144,549,554,562,565,570,586,602,634,750,764,1228,1337,1456,1531,1698,1716 'sendmail':128 'sensit':1571 'sent':236,544,784,1040,1150,1311 'seq':1108 'server':210,219,251,924,1634,1658 'servic':15,55 'set':341,560,838,1493 'settimeout':1281 'setup':806 'signup':1538 'simpl':1438 'skill':192 'skill-send-email-programmatically' 'sleep':1167 'smtp':8,44,131,196,201,209,213,218,238,250,282,795,923,1415,1436,1479,1484,1576,1589,1605,1657,1751 'smtp.gmail.com':826,1006 'smtp.gmail.com:587':220,1121,1486 'smtp.office365.com':1046 'smtp.office365.com:587':285,1495 'smtphost':936,953,1005,1045 'smtppassword':939,970,1011,1051 'smtpport':937,955,957,1007,1047 'smtpuser':938,968,1009,1049 'solut':1612,1638,1662,1686,1706,1734,1757 'source-besoeasy' 'spam':1378,1721,1732 'specif':1325 'spf':1736 'spf/dkim':1369 'ssl':300,1641 'ssl-reqd':299,1640 'starttl':1630 'status':757 'store':1575 'string':715 'subject':227,277,278,310,386,432,456,466,530,599,650,683,694,771,852,881,897,942,981,1022,1059,1092,1143,1144,1299 'success':755,996,1151,1241 'sudo':165 'summari':27,92 'support':921,1480 'symptom':1604,1633,1656,1681,1701,1722,1750 'system':127,1191,1303 'telegram':1779 'temporari':154 'test':228,234,531,772,779,853,1060,1065,1678 'text':391,396,436,457,467,468,533,535,684,705,943,982,1024,1026,1061,1302,1408 'text/html':655,701,903 'text/plain':611,702 'throw':505,747,1234,1255 'tier':50,137,147,330,556,1332,1521,1533 'time':805,1118,1755 'timeout':1748,1767 'tls':813,815,1636 'tls/ssl':1586 'tool':113 'topic-agent-skills' 'topic-ai-agents' 'topic-claude-code' 'topic-clawdbot' 'topic-clawdbot-skill' 'topic-llm-tools' 'topic-mcp-server' 'topic-openai' 'topic-openclaw' 'topic-vibe-coding' 'topic-vibecoding' 'tostr':477 'transport':948,950 'transporter.sendmail':978 'tri':1215 'troubleshoot':1599 'true':756,959,997,1242 'trust':816 'type':495,592,610,640,654,671,699,718,736,902 'ubuntu/debian':164 'undefin':991,994 'unknown':1237 'unlimit':1517 'updat':111 'upload':268,303,1136 'upload-fil':267,302,1135 'url':249,284,579,627,1120 'urlsearchparam':463 'usag':515,759,1002,1042,1184,1193,1284 'use':16,67,68,81,93,102,183,200,327,553,792,917,1317,1382,1497,1548,1585,1647,1744 'user':29,63,73,107,262,294,364,412,831,967,1130,1421 'user@example.com':430,646,1189 'v':248 'valid':1361,1544,1591 'valu':612,656,703 'variabl':1384,1550,1584 'vault':1387 'verifi':358,1515,1694,1745 'via':7,36,43,195,202,237,322,548,788,1414,1778 'volum':1449,1460 'w':666 'week':651,657 'within':1519 'work':204 'workflow':31,109 'y':170 'your-api-key':1289 'your-app-password':241,834,1012 'your-email@gmail.com':223,830,832,856,1010,1019 'your-email@outlook.com':289,295,307,1050,1056 'your-mailgun-api-key':348,518 'your-password':296,1052 'your-sendgrid-api-key':568,762","prices":[{"id":"90850387-86af-42bf-ae5e-d212b3e46acb","listingId":"c10d2e9d-9a84-45c3-8e97-67cc625dae70","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"besoeasy","category":"open-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T22:10:53.388Z"}],"sources":[{"listingId":"c10d2e9d-9a84-45c3-8e97-67cc625dae70","source":"github","sourceId":"besoeasy/open-skills/send-email-programmatically","sourceUrl":"https://github.com/besoeasy/open-skills/tree/main/skills/send-email-programmatically","isPrimary":false,"firstSeenAt":"2026-04-18T22:10:53.388Z","lastSeenAt":"2026-05-02T12:55:04.676Z"}],"details":{"listingId":"c10d2e9d-9a84-45c3-8e97-67cc625dae70","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"besoeasy","slug":"send-email-programmatically","github":{"repo":"besoeasy/open-skills","stars":111,"topics":["agent-skills","ai","ai-agents","claude-code","clawdbot","clawdbot-skill","llm-tools","mcp-server","openai","openclaw","vibe-coding","vibecoding"],"license":null,"html_url":"https://github.com/besoeasy/open-skills","pushed_at":"2026-03-31T13:05:30Z","description":"Battle-tested skill library for AI agents. Save 98% of API costs with ready-to-use code for crypto, PDFs, search, web scraping & more. No trial-and-error, no expensive APIs.","skill_md_sha":"35ad9d82a2c43136f047a82d59d0062da9d6e3a4","skill_md_path":"skills/send-email-programmatically/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/besoeasy/open-skills/tree/main/skills/send-email-programmatically"},"layout":"multi","source":"github","category":"open-skills","frontmatter":{"name":"send-email-programmatically","description":"Send emails via SMTP, free APIs, or privacy-focused services. Use when: (1) Sending notifications and alerts, (2) Automated reports and summaries, (3) User communication workflows, or (4) Error logging via email."},"skills_sh_url":"https://skills.sh/besoeasy/open-skills/send-email-programmatically"},"updatedAt":"2026-05-02T12:55:04.676Z"}}