flexigo-support-bot / scripts /build_static_site.py
victor34593993's picture
Release 2026-06-15/16: B2 billing-orphan fix + demo conversion (B1/B3/B4/B5) + conversation history (72h) + per-tenant teach-the-bot + onboarding videos
4778987 verified
Raw
History Blame
4.55 kB
"""Reproducibly build the atendyo.com STATIC site (Netlify) from source.
atendyo.com is served statically by Netlify (the backend only renders these same
pages). This regenerates the EXACT file tree the site needs so a landing/blog
change can be redeployed without hand-assembling files in /tmp:
index.html <- app/landing_ui/index.html (verbatim)
og.png <- app/landing_ui/og.png
blog/index.html <- render_index("es")
blog/en.html <- render_index("en")
blog/<slug>.html <- render_article(post) for every post
robots.txt, sitemap.xml <- regenerated, canonical on atendyo.com
_redirects <- the /demo -> backend redirect (load-bearing: every
cold-email demo link is atendyo.com/demo?d=...)
For static hosting the EN blog index lives at /blog/en (file blog/en.html), so we
rewrite the renderer's "/blog?lang=en" links to "/blog/en".
Usage: python -m scripts.build_static_site [output_dir] (default: dist/site)
"""
from __future__ import annotations
import shutil
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT))
from app.blog.posts import POSTS # noqa: E402
from app.blog.render import render_article, render_index # noqa: E402
SITE = "https://atendyo.com"
BACKEND = "https://victor34593993-flexigo-support-bot.hf.space"
LANDING = ROOT / "app" / "landing_ui" / "index.html"
OG = ROOT / "app" / "landing_ui" / "og.png"
LEGAL_DIR = ROOT / "app" / "legal_ui"
# Served at /legal/<page> (pretty URL). The privacy policy URL Meta needs is
# https://atendyo.com/legal/privacidad — must be a real, accessible page.
LEGAL_PAGES = ("aviso-legal", "privacidad", "cookies", "condiciones", "encargo")
def _static(html: str) -> str:
# the EN blog index is a file (/blog/en), not a query string, when static
return html.replace(f"{SITE}/blog?lang=en", f"{SITE}/blog/en")
def _robots() -> str:
return (
"User-agent: *\n"
"Allow: /$\n"
"Allow: /blog\n"
"Disallow: /admin\n"
"Disallow: /portal\n"
"Disallow: /preview\n"
"Disallow: /chat\n"
"Disallow: /widget-config\n"
f"Sitemap: {SITE}/sitemap.xml\n"
)
def _sitemap() -> str:
rows = [
f" <url><loc>{SITE}/</loc><changefreq>weekly</changefreq><priority>1.0</priority></url>",
f" <url><loc>{SITE}/blog</loc><changefreq>weekly</changefreq><priority>0.7</priority></url>",
]
for p in POSTS:
rows.append(
f" <url><loc>{SITE}/blog/{p.slug}</loc><lastmod>{p.date}</lastmod>"
"<changefreq>monthly</changefreq><priority>0.6</priority></url>"
)
return (
'<?xml version="1.0" encoding="UTF-8"?>\n'
'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n'
+ "\n".join(rows) + "\n</urlset>\n"
)
def _redirects() -> str:
# The ONLY redirect the site needs: atendyo.com/demo -> backend /demo (302,
# query string auto-forwarded). Load-bearing for every email demo link.
# MUST be a _redirects file in the publish root — a netlify.toml inside the
# deployed --dir is published as a plain file and NOT processed as config.
return f"/demo {BACKEND}/demo 302\n"
def build(out: Path) -> None:
if out.exists():
shutil.rmtree(out)
blog = out / "blog"
blog.mkdir(parents=True)
(out / "index.html").write_text(LANDING.read_text(encoding="utf-8"), encoding="utf-8")
shutil.copyfile(OG, out / "og.png")
legal = out / "legal"
legal.mkdir()
for page in LEGAL_PAGES:
(legal / f"{page}.html").write_text(
(LEGAL_DIR / f"{page}.html").read_text(encoding="utf-8"), encoding="utf-8")
(blog / "index.html").write_text(_static(render_index("es")), encoding="utf-8")
(blog / "en.html").write_text(_static(render_index("en")), encoding="utf-8")
for p in POSTS:
(blog / f"{p.slug}.html").write_text(_static(render_article(p)), encoding="utf-8")
(out / "robots.txt").write_text(_robots(), encoding="utf-8")
(out / "sitemap.xml").write_text(_sitemap(), encoding="utf-8")
(out / "_redirects").write_text(_redirects(), encoding="utf-8")
n = len(list(blog.glob("*.html")))
print(f"built site at {out}: index + {n} blog pages + {len(LEGAL_PAGES)} legal "
"pages + sitemap/robots/_redirects/og.png")
if __name__ == "__main__":
target = Path(sys.argv[1]) if len(sys.argv) > 1 else ROOT / "dist" / "site"
build(target)