أُخرج لوحاتي من Miro إلى Obsidian
زر Export في Miro يمنحك ملف PNG أو PDF — صورة فوتوغرافية للبيانات، لا البيانات نفسها. إن كانت لوحاتك خرائط تفكير حاملة للأثقال تراكمت على مدى سنوات، فمكانها Obsidian: قابلة للتحرير، قابلة للبحث، في vault محلي. إليك كيف أخرجت اللوحات من Miro عبر REST API وحوّلتها إلى Excalidraw / Obsidian Canvas — مع الحفاظ على المواضع والألوان والخطوط والموصّلات المنحنية وعُقد الخرائط الذهنية — والدرس أوسع من Miro: كل SaaS يستحق خطة خروج قبل أن تفتحه أصلاً.
أي أداة تعيش داخل المتصفح تحتجزك رهينةً لواجهتها. خاصةً بعد أن تكون قد صببت فيها الوقت والبطاقات واللوحات — ثم تدرك أن خريطة تفكيرك بأكملها قابعة على خادم شخص آخر، بصيغة لا يمكنك فتحها من دون تحميل صفحتهم.
لديّ بضع لوحات في Miro أصبحت منذ زمن حاملةً للأثقال — تأملات وخطط وخرائط ذهنية تراكمت على مدى سنوات. زر Export يمنحك ملف PNG أو PDF. هذه ليست بيانات، بل صورة فوتوغرافية للبيانات.
لماذا تُخرجها من هناك
قفل المورّد ليس مشكلة نظرية. إنه ملموس تماماً: كي تُنزّل بياناتك أنت عبر الـ API، عليك الترقية إلى فئة Expert. أي أنك تدفع مقابل الإذن باستعادة ما هو ملكك أصلاً.
أعيش منذ زمن طويل وفق مبدأ Obsidian-first: كل ما هو مهم يقبع في vault محلي، في ملفات نصية صِرفة أستطيع وضعها في git والبحث فيها بـ grep وقراءتها بعد عشر سنوات. الأداة التي لا تصدّر إلى تلك الصيغة أداةٌ يجب أن تبتعد عنها قبل أن تصبح التبعية مستحيلة الفكاك.
لماذا لا ينقذك زر Export
زر Export في Miro يمنحك ملف PNG أو PDF. هذا نقطي (raster) — البنية ضاعت. لا تستطيع تغيير النص داخل صندوق. لا تستطيع سحب شكل. لا تستطيع البحث بـ grep عن عنوان. إنها بطاقة نعي للوحة، لا اللوحة نفسها.
في Obsidian بديلان يعيشان داخل الـ vault: إضافة Excalidraw وكذلك Canvas الأصلي. كلاهما JSON. كلاهما قابل للتحرير. كلاهما قابل للبحث. كلاهما يقبع في vault-ك بجانب ملاحظاتك، ويمكنك البحث في النص بـ grep من داخل Obsidian مباشرةً.
كيف تُخرجها حين لا يوجد زر 'Export to Obsidian'
حين لا يعطيك Export في الواجهة ما تحتاجه، تغوص في الـ API. لدى Miro واجهة REST API: تعيد وصفاً بصيغة JSON لكل شكل على اللوحة. وExcalidraw وObsidian Canvas كلاهما JSON بصيغة مفتوحة. وبينهما يقع التحويل (mapping).
كتبتُ سكربتَين بلغة Python. miro_to_excalidraw.py وmiro_to_canvas.py. المكتبة القياسية فقط — صفر تبعيات. تُشغّلهما برمز مصادقة ومعرّف لوحة، فتحصل على ملف، ترميه في الـ vault.
ما الذي نجا من التحويل
لم تكن المهمة مجرد نقل الأشكال — بل الحفاظ على المظهر البصري كي تُقرأ اللوحة تماماً كما كانت داخل Miro.
- المواضع والأحجام — إحداثيات كل شكل بنسبة 1:1
- الألوان مع شفافية التعبئة (الأصفر بنسبة 40% يبقى أصفر بنسبة 40%)
- الحدود — اللون، العرض، النمط (solid / dashed)
- الخطوط والمحاذاة — monospace يبقى monospace، وcenter يبقى center
- الموصّلات — الأسهم تلتصق عند النقاط ذاتها التي ثبّتها Miro
- الموصّلات المنحنية — أقواس bow بدلاً من الخطوط المستقيمة
- الصور مضمّنة داخل الملف (لا روابط URL خارجية)
- عُقد الخرائط الذهنية — النص مستخرَج عبر واجهة Mindmap API التجريبية
- ترتيب الطبقات (Z-ordering) — التداخلات لا تتشابك
أين صار الأمر شائكاً
في واجهة Miro API ثغرتان أو ثلاث اضطُررت إلى الالتفاف حولها بالهندسة العكسية.
- الموصّلات المنحنية — لا يكشف Miro نقاط التحكم عبر الـ API. لذا بدلاً من المنحنى الأصلي بدقّته، أصطنع bow — قوساً بنصف قطر ثابت بين الطرفَين. قريب بصرياً، لكنه mathematically غير مطابق.
- Z-index — واجهة Miro API لا تعيد حقل z إطلاقاً. أيُّ شكل يعلو وأيُّها يقبع تحت؟ الاستدلال التقريبي: المساحة الأكبر = أبعد إلى الخلف. وهذا ينجح لأن الحاويات الكبيرة في اللوحات الحقيقية تقبع عادةً تحت العناصر الأصغر.
- الخرائط الذهنية — نص عُقد الخريطة الذهنية لا يمكن الوصول إليه عبر items API المعتادة. تحتاج إلى نداء منفصل إلى نقطة نهاية Mindmap التجريبية. العُقد المملوءة تصير صناديق، وغير المملوءة تصير نصاً صِرفاً.
Excalidraw مقابل Canvas — كيف تختار
إن كنت تفكّر على هيئة رسومات — خطوط تخطيطية، إحساس مرسوم باليد، تركيبات حرة الشكل — فاختر Excalidraw. إضافة Excalidraw تعرض الملف بالأسلوب الجمالي ذاته الذي رأيته على الـ whiteboards.
إن كانت لوحاتك في معظمها مستطيلات فيها نص موصولة بأسهم، وكنت تعيش في Obsidian بوصفه دماغك الثاني — فاختر Canvas. إن Canvas أصلي، يُفتح بنقرة واحدة، ومنسوج مع backlinks وtags الخاصة بالـ vault.
أحوّل بعض اللوحات إلى Excalidraw (حين يهمّ الأسلوب البصري)، وأخرى إلى Canvas (حين تهمّ السرعة والإحساس الأصلي). المستودع يدعم كلتا الصيغتين — تختار عند التشغيل.
الخلاصة
Python 3، المكتبة القياسية فقط. لا pip install، لا virtualenv، لا node_modules. python3 miro_to_excalidraw.py 'BOARD_ID' 'output.excalidraw' — والملف بين يديك.
المستودع: github.com/oleksiimazurenko/miro-to-obsidian. رخصة MIT. طلبات الدمج مرحّب بها — خصوصاً للحالات الحدّية التي لم أصادفها بعد.
الدرس أكبر من Miro
قفل المورّد في SaaS مخدّر. الأشهر الأولى مجانية. بعد ستة أشهر يصير عادة. بعد سنة تعيش بياناتك في صيغة لا يقرؤها إلا واجهتهم. بعد سنتين تدفع مقابل فئة Expert كي تستخرج ما هو ملكك أصلاً.
الخلاصة ليست «لا تستخدم SaaS». الخلاصة أن كل أداة تسمح لها بأن تصبح حاملةً للأثقال تحتاج إلى خطة خروج قبل أن تفتحها للمرة الأولى أصلاً. سؤال «كيف أخرج من هنا حين أحتاج» يزن تماماً بثقل سؤال «ما مدى لطافة الواجهة». الأداة التي لا تملك تصديراً بنص صِرف أو واجهة API مفتوحة أداةٌ ببطاقة سعر خفية ستدفعها بعد سنتين.
Obsidian-first ليس لأن Obsidian مثالي. بل لأن ملفات markdown النصية الصِرفة صيغة ستُعمّر أطول من Obsidian نفسه. تماماً كما سيُعمّر ملف Excalidraw JSON العاري أطول من الإضافة نفسها. تماماً كما سيُعمّر سكربت Python هذا أطول من Miro.