hermes-skills/communication/email-send-from-arif-fazil/SKILL.md
Send email from [email protected] using secrets from /root/AAA/secrets/email.env. Handles the execute_code sandbox env-var visibility issue.
npx skillsauth add ariffazil/openclaw-workspace email-send-from-arif-fazilInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
execute_code (hermes_tools sandbox) CANNOT see env vars set by email.env via source /root/AAA/secrets/email.env. The sandbox has its own environment — os.environ.get('GMAIL_APP_PASSWORD', '') returns empty string inside execute_code, even though terminal() can see it fine.
Always use terminal() Python for email send, not execute_code().
File: /root/AAA/secrets/email.env
[email protected]
GMAIL_APP_PASSWORD=<16-char app password>
Use terminal() with inline Python that reads the password file directly:
python3 << 'EOF'
import smtplib, os
from email.message import EmailMessage
# Read password directly from file (bypasses sandbox env-var issue)
password = None
with open('/root/AAA/secrets/email.env') as f:
for line in f:
if 'GMAIL_APP_PASSWORD' in line and '=' in line:
password = line.strip().split('=', 1)[1].strip()
break
user = "[email protected]"
msg = EmailMessage()
msg["From"] = user
msg["To"] = "[email protected]"
msg["Subject"] = "Subject here"
msg.set_content("Body text here")
with smtplib.SMTP("smtp.gmail.com", 587) as server:
server.starttls()
server.login(user, password)
server.send_message(msg)
print("SENT OK")
EOF
starttls() — works from af-forge VPSSMTP_SSLzclv — if wrong, Gmail returns 535 Username and Password not acceptedSending FROM [email protected] requires separate SMTP config — currently not set up. All outgoing email via this method only sends FROM [email protected].
The Problem:
Gmail SMTP can silently REJECT your email at the auth layer. If your code saves to the Sent folder before calling server.send_message(), a Sent folder entry exists even when the SMTP call throws SMTPAuthenticationError. This creates a false "success" state — you see the email in Sent, but it was NEVER delivered to any recipient.
Error signature:
SMTPAuthenticationError: (535, b'5.7.8 Username and Password not accepted.')
Why it happens:
Correct verification pattern — do BOTH:
all_recipients = to_list + cc_list # flatten first!
try:
with smtplib.SMTP("smtp.gmail.com", 587) as server:
server.starttls()
server.login(GMAIL_USER, GMAIL_APP_PASSWORD)
# send_message returns {} on success, dict of failures on partial/total failure
result = server.send_message(msg, to_addrs=all_recipients)
if result:
print(f"⚠️ PARTIAL FAILURES: {result}")
else:
print(f"✅ DELIVERED to all {len(all_recipients)} recipients")
except smtplib.SMTPAuthenticationError as e:
print(f"❌ AUTH FAILED — email NOT sent. Fix app password at: https://myaccount.google.com/apppasswords")
raise # re-raise so you see the error
except Exception as e:
print(f"❌ SMTP ERROR: {e}")
raise
Key rules:
to_addrs — send_message(to_addrs=to_list + cc_list), not nested listsSMTPAuthenticationError specifically — it's the most common Gmail failure modesend_message() return value — empty dict {} = all delivered; non-empty = failures per recipientIf auth keeps failing, check:
/root/AAA/secrets/email.env with the new passwordBatch send (TO + CC + BCC):
TO = ["[email protected]", "[email protected]"]
CC = ["[email protected]", "[email protected]"]
BCC = ["[email protected]"]
msg["To"] = ", ".join(TO)
msg["Cc"] = ", ".join(CC)
# BCC goes only to send_message, not in headers
all_recipients = TO + CC + BCC
server.send_message(msg, to_addrs=all_recipients)
development
Governed intelligence skill for AAA as the abstraction, attestation, and abduction control plane across arifOS, APEX, A-FORGE, GEOX, WEALTH, WELL, and the ariffazil profile repository. Use when the user asks to explain or design AAA, route agentic work, reduce chaos/entropy in an arifOS federation task, create AREP/task declarations, classify risk, plan multi-repo changes, review governance boundaries, or translate human intent into evidence-backed, authority-safe, recursively agentic workflows. Provides deterministic F1-F13 floor checking, bounded abduction, and FederationReceipt composition.
development
Check every skill’s “use when” and “do not use when” clauses for collisions, missing negatives, and vague verbs like “help,” “assist,” or “improve.” Load when linting, reviewing, or validating trigger boundaries.
development
Bootstrap, design, and package new skills. Load when capturing user intent for a new skill or drafting its initial instruction framework.
content-media
Diagnose which federation services are up, down, or drifting. Produce a prioritized remediation plan.