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
Federation-wide gold (XAUUSD) trading capability. Python stack, OANDA broker, backtesting, macro signals, RSI strategy. Every organ has a role.
development
Capital claim state management — tracks claim lifecycle across WEALTH organ.
development
Archived constitutional warga placeholder retained only for audit provenance. Do not use for active work; use the live arifOS governance and constitutional skills instead.
testing
Warga (citizen) agent skills for AAA federation members. See subdirectories for specialized warga skills.