העברת ארכיון הקלטות: מדריך מיגרציה בטוחה
ארכיון הקלטות ישן אינו בעיה של נפח. הוא בעיה של מטא-דאטה, כפילויות ושעונים - והדרך היחידה לדעת שההעברה הצליחה היא ספירה שנסגרת. הנוהל כאן נכתב אחרי הרצה אמיתית של הסוכן מול עץ קבצים מסונתז.
הכשל הנפוץ אינו קובץ שאבד בדרך. הוא ארכיון שהועבר במלואו, ואיש לא יודע לומר אם הוא שלם.
- מה נדרש
- גישת קריאה לארכיון, מכונה להרצה, וגיליון.
- מה קובע את הקצב
- איכות שמות הקבצים. לא הנפח ולא הרוחב פס.
- מה מקבלים
- ספירה שנסגרת, עם הסבר לכל פער ויעד שמירה לכל גל.
למה מיגרציה של ארכיון אינה כמו קליטה שוטפת
קליטה שוטפת מקבלת שיחה אחת בכל פעם, בזמן אמת, ממערכת שיודעת מה היא שולחת. מיגרציה מקבלת עשר שנים בבת אחת, ממערכת שכבר אין לה בעלים, בשמות שהשתנו שלוש פעמים בדרך. אותם כלים בדיוק מתנהגים אחרת בשני המצבים - ורוב ההפתעות במיגרציה הן התנהגויות שהן נכונות לקליטה שוטפת.
שלוש דוגמאות שנצפו בהרצה בפועל: זיהוי כפילויות שנעשה לפי שם הקובץ ולא לפי תוכנו, חותמת זמן שנלקחת מתאריך הקובץ כשאין תאריך בשם, וחלון סריקה שמוגבל לשבעה ימים אחורה. כל אחת מהן היא בחירה טובה בקליטה יומיומית וכל אחת מהן מזיקה במיגרציה. שלושתן תוקנו בסוכן בעקבות ההרצה הזו - הכפילות נחסמת לפי תוכן, מועד שנגזר מתאריך הקובץ מסומן ככזה או נדחה, והחלון ניתן לפתיחה מבוקרת - וההגדרות שמפעילות את זה מרוכזות בטבלה בהמשך.
אם עדיין לא בטוח שההקלטות שקיימות אצלכם מכסות את מה שצריך, כדאי להתחיל דווקא בביקורת כיסוי הקלטות - אין טעם להעביר ארכיון לפני שידוע מה חסר בו. ההבחנה בין הקלטה במרכזייה לבין ניהול הקלטות מוסברת בהשוואה.
הדרכים שקיימות באמת, והשתיים שלא
לפני שמתכננים לוח זמנים כדאי לדעת מה אפשר לחבר. ארבע דרכי קליטה קיימות ונבדקו; שתי דרכים שנשמעות טבעיות למיגרציה - משיכה מדלי S3 ומשיכה מ-SFTP - אינן קיימות. הן מופיעות כערכים במערכת אך אין מאחוריהן תהליך שמושך קבצים, ואין תאריך יעד מפורסם. עדיף לדעת את זה עכשיו מאשר בתחילת הסופשבוע שיועד להעברה.
| הדרך | מתי מתאימה | איך זה עובד | מצב |
|---|---|---|---|
| סוכן התיקייה המקומי | ארכיון שיושב כקבצים על שרת, על NAS או בתיקייה משותפת. זה המצב הנפוץ ביותר. | הסוכן סורק את התיקייה, מפרש את שם הקובץ, ומעלה בבקשה חתומה. הוא רץ בתוך הרשת שלכם ואינו דורש לפתוח דבר החוצה. | קיים ונבדק |
| Webhook חתום | מערכת שיודעת לשלוח רשומת שיחה בעצמה, כולל ייצוא היסטורי שאפשר לשדר מחדש. | בקשת JSON חתומה ב-HMAC-SHA256 לכל שיחה. מתאים כשהמטא-דאטה נמצא במסד נתונים ולא בשם הקובץ. | קיים ונבדק |
| העלאת multipart חתומה | סקריפט חד-פעמי שרץ מול הארכיון ושולח קובץ ומטא-דאטה יחד. | אותה חתימה, בבקשת multipart: שדה מטא-דאטה ושדה אודיו. מגבלת הגודל היא 200MiB לקובץ. | קיים ונבדק |
| שליפה מכתובת הקלטה | מערכת שמחזיקה את הקבצים ומספקת לכל שיחה כתובת שאפשר להוריד ממנה. | שולחים את רשומת השיחה עם recording_url, והשליפה מתבצעת אצלנו ברקע. | קיים ונבדק |
| משיכה מדלי S3 | — | לא קיים. אין מנגנון שמושך קבצים מדלי אחסון, ואין תאריך יעד מפורסם. אם הארכיון בדלי, מורידים אותו לתיקייה ומריצים את הסוכן, או שולחים אותו בהעלאה חתומה. | לא קיים |
| משיכה מ-SFTP | — | לא קיים. אין תהליך שמתחבר לשרת SFTP וסורק אותו. הפתרון המעשי זהה: לסנכרן את התיקייה למקום שהסוכן רואה. | לא קיים |
הפירוט המלא של כל דרך נמצא בעמוד החיבורים. התיעוד הטכני של הסוכן המקומי - התיקייה הנצפית, תבניות השמות, קובץ המצב וההסגר - נמצא במדריך סוכן התיקייה, ותיעוד ה-Webhook החתום נמצא במדריך ה-Webhook.
הנוהל, עשרה שלבים
הסדר אינו מקרי. כל מה שהפיך וזול נעשה לפני כל מה שנוגע במקור, וההחלטה עם זמן ההיערכות הארוך ביותר - על סמך מה מחזיקים את הארכיון ועד מתי - נופלת בשלב השני ולא מתגלה בשלב התשיעי.
מיפוי מקורות
לרשום כל מקום שבו יושבות הקלטות: המרכזייה, שרת ההקלטה, תיקייה משותפת, גיבוי ישן, דיסק חיצוני במשרד ומערכת של ספק קודם שעדיין פעילה. לכל מקור: מי הבעלים, כמה קבצים, כמה נפח, טווח התאריכים ואיזה פורמט. מקור שאיש אינו יודע לומר עליו מי הבעלים הוא הממצא הראשון של המיגרציה, לא תקלה טכנית.
בסיס חוקי והחלטת יעד שמירה
לפני שמעבירים משהו, להחליט על סמך מה הארכיון מוחזק ועד מתי. העברה אינה מאפסת את השעון ואינה מכשירה החזקה שלא הייתה מוצדקת: העברה של הקלטות שאין סיבה להחזיק רק מכפילה אותן. לכל טווח תאריכים לקבוע יעד - להעביר ולשמור עד תאריך מסוים, להעביר ולסמן למחיקה, או לא להעביר כלל. שורה ללא יעד שמירה אינה עוברת.
בדיקת איכות המטא-דאטה
לקחת מאה שמות קבצים אקראיים ולבדוק מה אפשר לחלץ מהם: מספר הצד השני, מועד השיחה, כיוון ושלוחה. הסוכן מזהה ארבע תבניות שמות מוכנות; כל מה שאינו נופל לתוכן צריך תבנית משלכם או מקור מטא-דאטה נפרד. זה השלב שקובע אם המיגרציה תיקח יום או שבועיים, והוא עולה חצי שעה.
גיבוב לפני ואחרי
לחשב SHA-256 לכל קובץ במקור ולשמור את הרשימה בצד. הסוכן מחשב את אותו גיבוב לפני כל העלאה, וגיבוב נוסף מחושב על הזרם בזמן הקליטה ומוחזר בתשובה; שלושתם צריכים להיות זהים. השוואת הרשימות בסוף היא הוכחה שהביטים זהים ולא רק שהמספרים מסתדרים, ורשימת הגיבובים היא גם התיעוד שמאפשר להוכיח בעוד שנה שהקובץ לא השתנה.
זיהוי כפילויות במקור
למיין את רשימת הגיבובים ולחפש ערכים שחוזרים. ארכיון ישן כמעט תמיד מכיל את אותה שיחה תחת שני שמות - עותק גיבוי, תיקייה שהועתקה, ייצוא שרץ פעמיים. הסוכן חוסם את זה בעצמו: קובץ שתוכנו כבר נקלט תחת שם אחר נרשם כ-duplicate ואינו נשלח. עדיין כדאי לספור את הכפילויות מראש, כי הפער בין מספר הקבצים למספר הגיבובים הייחודיים הוא בדיוק מספר הרשומות שלא ייווצרו - ובלי הספירה הזו הספירה הסופית תיראה כאילו חסרים קבצים.
קיבוע אזור הזמן
חותמת זמן בשם קובץ אינה נושאת אזור זמן, ולכן צריך לומר לסוכן לפי איזה שעון לקרוא אותה. ברירת המחדל היא אזור הזמן של המכונה המריצה - ואם היא שרת שמוגדר UTC והמרכזייה כתבה שעון ישראלי, כל שיחה תזוז בשעתיים או שלוש, מספיק כדי להעביר שיחה ליום אחר ולכן גם למועד שמירה אחר. במיגרציה מגדירים אותו במפורש: timeZone בקובץ ההגדרות או --timezone=Asia/Jerusalem. הערך נכתב ביומן, נשמר בקובץ המצב ונשלח עם כל שיחה, כך שאפשר לדעת בדיעבד לפי איזה שעון נקראה. לרשום את אותו ערך בגיליון.
מיפוי כיוון ותוצאה
שם קובץ שאין בו סימן לכיוון מקבל את ברירת המחדל שהוגדרה, ובברירת המחדל של הסוכן זה "יוצאת". אם חלק מהארכיון הוא שיחות נכנסות ללא סימון, עדיף להעביר אותו בהרצה נפרדת עם ברירת מחדל אחרת מאשר לתקן אלפי שורות אחר כך. אותו דבר לגבי תוצאת השיחה: מה שלא ידוע צריך להישאר לא ידוע ולא להיות מנוחש.
הרצה יבשה על מדגם
להעתיק מאתיים עד חמש מאות קבצים מייצגים לתיקייה נפרדת - העתקה, לא העברה - ולהריץ עליה. לבדוק בתוצאה: כמה נקלטו, כמה נדחו בגלל שם שאינו מזוהה, כמה עברו להסגר, ומה המועד והכיוון שנקבעו לעשר שיחות שנבחרו ידנית. המדגם הוא המקום היחיד שבו טעות עולה חמש דקות.
הרצה מלאה בגלים
להעביר לפי טווחי תאריכים, מהישן לחדש או להפך, גל אחד בכל פעם, ולבדוק את הספירה אחרי כל גל. חלון הסריקה מוגבל כברירת מחדל לשבעה ימים אחורה - הגנה מפני העלאת עשור בטעות - ולכן מיגרציה דורשת פתיחה מכוונת שלו: --max-age-days=0 לארכיון שלם, או --since ו---until לגל בודד. שימו לב שהחלון נמדד לפי זמן השינוי של הקובץ ולא לפי התאריך שבשם, ולכן בארכיון שהועתק כל הקבצים עשויים להיראות באותו גיל; במקרה כזה מגדירים את הגלים לפי תיקיות ולא לפי תאריכים. אחרי הגל האחרון מחזירים את החלון לשבעה ימים.
ספירת התאמה סופית
להשוות ארבעה מספרים: קבצי אודיו במקור, גיבובים ייחודיים, רשומות שנוצרו, וקבצים שנדחו או עברו להסגר. הם חייבים להיסגר לאפס עם הסבר לכל פער. רק אחרי שהספירה נסגרה, ורק אחרי שעברה תקופת בדיקה שנקבעה מראש, אפשר לדון במה עושים עם המקור - וגם אז ההחלטה היא החלטה בפני עצמה ולא שלב טכני.
גיליון העבודה להורדה
שורה אחת לכל מקור וטווח תאריכים, עם שלוש שורות דוגמה ושורות ריקות למילוי. אין טופס, אין הרשמה ואין העלאה של דבר לאתר - הקובץ נועד להישאר אצלכם ולעבור בין האנשים שמריצים את ההעברה.
מקודד UTF-8 עם סימן BOM, כדי שעברית תיפתח נכון גם ב-Excel בעברית.
בגיליון יש ספירות בלבד. אין בו טור למספר טלפון, לשם עובד או לרשימת קבצים, ואין בהם צורך כדי לסגור ספירה. גיליון מיגרציה עובר בין תפעול, מערכות מידע ומי שמאשר, ולעיתים גם בדוא״ל - ואין סיבה שיהיה בו עותק של יומן השיחות.
מה יש בכל טור
- מקור
- שם פנימי של המקור - שרת, תיקייה, גיבוי או ספק קודם. שורה אחת לכל מקור וטווח תאריכים.
- בעלים
- מי אחראי למקור הזה. מקור בלי בעלים הוא סיכון, לא משימה.
- טווח_מתאריך, טווח_עד_תאריך
- גבולות הגל. גל אחד לכל שורה, כדי שאפשר יהיה לספור אותו.
- קבצי_אודיו_במקור
- ספירה של קבצים בסיומות אודיו בלבד, לא כלל הקבצים בתיקייה.
- גיבובים_ייחודיים
- כמה ערכי SHA-256 שונים יש בקבצים האלה. הפער מול הטור הקודם הוא הכפילויות, וזה גם מספר הקבצים שהסוכן ידלג עליהם כ-duplicate. זה הטור שמסביר למה נוצרו פחות רשומות מקבצים.
- אזור_זמן_מקור
- איזה שעון כתבה המרכזייה. זה הערך שמועבר ל---timezone, והטור שמונע הזזה של כל הארכיון בשעתיים.
- תבנית_שם_מזוהה
- איזו תבנית התאימה, או "נדרשת תבנית". ממולא אחרי בדיקת המטא-דאטה.
- כיוון_ברירת_מחדל
- מה נקבע לשיחות שאין בשמן סימן כיוון, לגל הזה.
- נקלטו, נדחו, בהסגר
- תוצאות ההרצה. שלושתם יחד חייבים להסתדר מול הספירה במקור.
- יעד_שמירה, תאריך_יעד
- מה מחליטים לגבי החומר שהועבר ועד מתי. שורה בלי יעד שמירה אינה מוכנה להעברה.
- הערה
- מה הוסבר בפער. גל שנסגר בלי הערה ייבדק שוב מאפס בעוד חצי שנה.
דוגמה מסונתזת שהורצה בפועל
כדי לכתוב את העמוד הזה בנינו עץ קבצים מסונתז - שנים-עשר קבצים, בלי אודיו אמיתי ובלי מספרים אמיתיים - והרצנו עליו את הסוכן שלוש פעמים מול נקודת קליטה מקומית. המספרים שלהלן הם מה שחזר, והממצאים שאחריהם הם התנהגויות שנצפו ולא הסברים מהתיעוד. העץ נמחק בתום הבדיקה. אלה מספרי המחשה בקנה מידה זעיר; הם מדגימים צורה של ספירה, לא ביצועים.
- קבצים בעץ
- 12
- מהם 11 בסיומת אודיו ואחד קובץ טקסט של הערות.
- גיבובים ייחודיים
- 10
- קובץ אחד היה עותק מדויק של אחר תחת שם אחר.
- בהרצה יבשה, כל הארכיון
- ↑8 ✗2 ⧉1
- שמונה היו נקלטים, שניים נדחו, אחד זוהה ככפילות תוכן. לא הועלה דבר ולא נכתב קובץ מצב.
- בהרצה הראשונה, ברירות מחדל
- ↑8 ✗1 ⧉1
- חלון שבעה ימים. מתוך השמונה אחד עבר להסגר כשקט לחלוטין.
- כפילות שנחסמה
- 1
- אותו אודיו תחת שם שני. נרשם כ-duplicate עם הפניה למקור, בלי העלאה.
- בהרצה השנייה
- 0
- אותה תיקייה, אותו חלון. קובץ המצב מנע העלאה כפולה.
- בגל הבקפיל
- 1
- הקובץ בן ארבעים היום נקלט אחרי פתיחת החלון ב---max-age-days=0.
- רשומות שנוצרו בצד השני
- 9
- שמונה מההרצה הראשונה ואחת מהבקפיל. אף מיזוג, ואף רשומה כפולה.
איך הספירה הזו נסגרת
אחד-עשר קבצי אודיו במקור. עשרה נכנסו לחלון ברירת המחדל: שמונה נקלטו, אחד נדחה בגלל שם שאינו מזוהה, ואחד נחסם ככפילות תוכן - וזה סוגר את העשרה. הקובץ האחד-עשר נקלט בגל נפרד עם חלון פתוח. בצד הקולט נוצרו תשע רשומות, אף לא אחת מהן מיזוג, ותשע הן בדיוק מספר השיחות השונות שהיו שם.
הפער בין 11 קבצים ל-9 רשומות הוא הממצא, לא התקלה: קובץ אחד נדחה וקובץ אחד היה עותק. ספירה שלא ידעה לצפות לשני אלה הייתה נראית כאילו אבדו קבצים בדרך, ולכן הטורים "גיבובים ייחודיים" ו"נדחו" בגיליון אינם קישוט.
כדי לוודא שהשכבות אינן נלחמות זו בזו מחקנו את קובץ המצב והרצנו שוב את אותו ארכיון: תשע העלאות יצאו, ותשעתן חזרו כמיזוג עם השיחה הקיימת ולא כרשומה חדשה. הזיהוי לפי תוכן פועל מעל הזיהוי לפי שם, לא במקומו.
הבדיקה הידנית שאחרי הספירה חשובה לא פחות ממנה. פתחנו את השיחות שנוצרו ובדקנו מועד, כיוון ומספר הצד השני - ושם התגלו הממצאים שלהלן, ששום ספירה לא הייתה מגלה.
ארבעה ממצאים, ומה השתנה בעקבותיהם
שלושת הראשונים היו תקלות אמיתיות שהתגלו בהרצה הזו, והם תוקנו בסוכן ומכוסים בבדיקות. הם כתובים כאן עם ההתנהגות שנצפתה לפני ואחרי, כי מי שמריץ גרסה ישנה יותר עדיין ייתקל בהתנהגות הקודמת. הרביעי אינו תקלה ולא ניתן לתקן אותו בקוד: תאריך של קובץ הוא תאריך של קובץ.
כפילות מזוהה לפי תוכן, לא לפי שם
מה נצפה: שני קבצים עם אודיו זהה בייט-בייט, תחת שני שמות, נקלטו בהרצה הראשונה כשתי רשומות נפרדות. אחרי התיקון השני נרשם כ-duplicate ולא נשלח, ובצד הקולט נוצרה רשומה אחת.
למה: המזהה החיצוני בקליטה הוא שם הקובץ בלי הסיומת - התנהגות נכונה לקליטה שוטפת, שמאפשרת לשדר קובץ מחדש בלי לייצר כפילות, אך עיוורת לשני עותקים בשני שמות. הסוכן מחשב עכשיו SHA-256 לפני ההעלאה ומחזיק אינדקס תוכן, מעל אותו מנגנון ולא במקומו.
מה עושים: שום דבר מיוחד בהרצה - זו התנהגות ברירת המחדל. כן להמשיך ולספור גיבובים ייחודיים מראש, כי הפער בין מספר הקבצים למספר הרשומות הוא הכפילויות, וספירה שלא ציפתה לו נראית כמו קבצים שאבדו.
תאריך קובץ אינו מועד שיחה, ומסומן ככזה
מה נצפה: קובץ בתבנית שלוחה-מספר, בלי תאריך בשם, קיבל כמועד שיחה את מועד השינוי האחרון של הקובץ - כלומר את יום ההעתקה. עכשיו המועד מסומן כ-file-mtime, נרשמת אזהרה עם שם הקובץ, ובהרצה עם mtimeFallback=reject הקובץ נדחה במקום להיקלט עם תאריך שגוי.
למה: בקליטה שוטפת זמן הקובץ הוא קירוב סביר לזמן השיחה, ולכן הוא נשאר ברירת המחדל. בארכיון שהועתק הוא תאריך ההעתקה, וזה גם מועד שמירה שגוי - ולכן ההבחנה נשמרת ונשלחת עם השיחה במקום להיעלם.
מה עושים: להריץ מיגרציה עם mtimeFallback=reject או --mtime-fallback=reject, ולטפל בנפרד בטווחים שנדחו: לשמר את זמני הקבצים בהעתקה, למצוא מקור זמן אחר, או להחליט שהטווח אינו עובר. קובץ שאין לו מועד כלל אינו נשלח בשום מצב.
אזור הזמן מוגדר במפורש ונרשם
מה נצפה: שם שכלל 09:15 נקלט כ-06:15 לפי UTC כשהמכונה הייתה בשעון ישראל, וכ-09:15 כשהיא הייתה ב-UTC - אותו קובץ, פער של שלוש שעות. אותה בדיקה אחרי התיקון: --timezone=Asia/Jerusalem נותן 06:15Z, --timezone=UTC נותן 09:15Z, והערך שנבחר מודפס ביומן ונשמר עם השיחה.
למה: חותמת בשם קובץ אינה נושאת אזור זמן. ברירת המחדל נשארה השעון של המכונה, כדי שהתקנות קיימות לא יזוזו, אבל היא כבר אינה שקופה: היא נבחרת פעם אחת, נרשמת ונשלחת. מעברי שעון קיץ מטופלים במפורש - שעה שנדלגה או שחזרה פעמיים מסומנת ולא נבלעת.
מה עושים: להעביר --timezone עם אזור הזמן של המרכזייה, לא של השרת, ולרשום אותו בגיליון. אם הארכיון חוצה מעבר שעון, לבדוק מדגם משני צידי המעבר.
חלון שבעת הימים נפתח בכוונה, ונסגר אחר כך
מה נצפה: בהרצה רגילה נסרקו עשרה מתוך אחד-עשר הקבצים; הקובץ בן ארבעים היום נכנס רק עם --max-age-days=0. אותה הרצה מדפיסה עכשיו את החלון שנבחר ואת העובדה שהוא נמדד לפי תאריך הקובץ.
למה: ברירת המחדל של שבעה ימים מגנה על התקנה חדשה מפני העלאת עשור בטעות, וזו התנהגות נכונה לתפעול שוטף. היא פשוט אינה מתאימה למיגרציה, ולכן היא ניתנת לשינוי - 0 מבטל את הגבול, ו---since/--until מגדירים גל.
מה עושים: לפתוח את החלון להרצה מוגדרת ולהחזיר אותו לשבעה ימים בסוף. לזכור שהחלון נמדד לפי זמן השינוי של הקובץ: בארכיון שהועתק כל הקבצים באותו גיל, ואז מחלקים לגלים לפי תיקיות ולא לפי תאריכים.
במה הרצת מיגרציה שונה מהרצה רגילה
הסוכן מותקן בדרך כלל לקליטה שוטפת, וברירות המחדל שלו נכונות לזה. מיגרציה משנה כמה מהן במפורש - ומחזירה אותן בסוף. הטבלה היא ההפרש, לא רשימת כל ההגדרות; התיעוד המלא נמצא במדריך הסוכן.
| הגדרה | ברירת מחדל | במיגרציה | למה |
|---|---|---|---|
--timezone= / timeZone | אזור הזמן של המכונה | אזור הזמן של המרכזייה, במפורש | שם קובץ אינו נושא אזור זמן. שרת שהוגדר UTC יזיז כל שיחה בשעתיים-שלוש. הערך נכתב ביומן ונשמר עם השיחה. |
--mtime-fallback= / mtimeFallback | allow | reject | בארכיון שהועתק, זמן הקובץ הוא יום ההעתקה. עדיף לדחות ולטפל בטווח מאשר לקלוט אלפי שיחות עם תאריך שגוי. |
--max-age-days= | 7 | 0 לארכיון שלם | ברירת המחדל מגנה על התקנה חדשה מפני העלאת עשור בטעות. במיגרציה זה בדיוק מה שרוצים, פעם אחת ובכוונה. |
--since= / --until= | — | גבולות הגל | מגדירים גל אחד לפי זמן השינוי של הקובץ. בארכיון שהועתק זמני הקבצים זהים, ואז מחלקים לגלים לפי תיקיות. |
--dry-run | — | בכל גל, לפני ההרצה | אותה סריקה ואותן הכרעות, בלי העלאה ובלי כתיבה לקובץ המצב. אפשר להריץ שוב ושוב עד שהמספרים מסתדרים. |
maxDepth | 4 | לפי עומק העץ | נסרקות עד ארבע רמות של תת-תיקיות. ארכיון בחלוקה שנה/חודש/יום/שלוחה עמוק יותר, ותיקייה שמעבר לעומק אינה נסרקת - היא כן נרשמת ביומן כשורת depth limit, וזו שורה שכדאי לחפש אחרי הגל הראשון. |
defaultDirection | outbound | לפי הגל | שם ללא סימן כיוון מקבל את ברירת המחדל. גל של שיחות נכנסות עדיף להריץ בנפרד מאשר לתקן אלפי שורות אחר כך. |
חלון שנפתח צריך להיסגר. אם הסוכן ימשיך לרוץ כשירות עם חלון פתוח, כל מעבר יסרוק מחדש את כל הארכיון. הרצות המיגרציה נעשות עם --once ובנפרד מהשירות השוטף, ובסוף הגל האחרון חוזרים לברירות המחדל.
# What the binary itself says it accepts. The authority for everything below.
voicebox-agent --help
# 1. Rehearse a wave. Same scan, same verdicts, nothing uploaded, no state file.
voicebox-agent --once --dry-run \
--config=/etc/voicebox/agent.json \
--timezone=Asia/Jerusalem \
--mtime-fallback=reject \
--max-age-days=0
# 2. Read the summary line: uploaded / failed / duplicates / skipped.
# Then run it for real - the same command without --dry-run.
# 3. Or one wave at a time, bounded by file modification date:
voicebox-agent --once --config=/etc/voicebox/agent.json \
--timezone=Asia/Jerusalem --mtime-fallback=reject \
--max-age-days=0 --since=2026-01-01 --until=2026-06-30
# 4. When the last wave is reconciled, the service goes back to its defaults:
# seven days, mtime fallback allowed. Nothing to pass - just stop overriding.
שתי הערות שלא כדאי לגלות באמצע גל. --since ו---until נקראים לפי שעון המכונה שמריצה את הסוכן ולא לפי --timezone, כי הם מסננים חותמת של מערכת הקבצים; לגל שנגמר בדיוק בחצות כדאי להשאיר יום מרווח ולסמוך על הספירה. ורשימת הדגלים המוסמכת היא voicebox-agent --help - אם משהו כאן ייראה שונה ממנה, הפלט של הבינארי הוא הנכון.
צ׳ק-ליסט להרצה יבשה
כל שורה כאן ניתנת לענייה לפני שמשהו זז. אם שורה אחת נשארת פתוחה, הגל אינו מוכן - וזה זול הרבה יותר מאשר לגלות אותה בגל השלישי.
- המדגם הועתק, לא הועבר. תיקיית המקור לא נגעה בה שום פקודה שכותבת.
- רשימת גיבובים של המדגם נשמרה מחוץ לתיקייה שמועברת.
- ההרצה בוצעה קודם עם --dry-run: אותה סריקה בדיוק, בלי העלאה ובלי כתיבה לקובץ המצב.
- אזור הזמן הועבר במפורש ב---timezone, נבדק בשורת היומן, ונרשם בגיליון.
- ההרצה בוצעה עם --mtime-fallback=reject, וידוע כמה קבצים נדחו בגלל היעדר מועד בשם.
- חלון הסריקה שנפתח מוגדר לגל הזה בלבד, וידוע מי מחזיר אותו לשבעה ימים בסוף.
- התבנית שמזהה את שמות הקבצים נבדקה על עשרה שמות אמיתיים, כולל אחד חריג.
- ברירת המחדל לכיוון מתאימה לגל הזה, ולא לגל אחר.
- עשר שיחות נפתחו ידנית ונבדקו: מועד, כיוון, מספר הצד השני והאודיו עצמו.
- הספירה נסגרה: נקלטו + נדחו + בהסגר = קבצי אודיו במדגם.
- קובץ המצב של הסוכן נמצא בנתיב ידוע, וגובה.
- יעד השמירה לחומר שהועבר נקבע ונרשם.
- מי מאשר שהגל הצליח, ותוך כמה זמן - נקבע מראש.
תוכנית חזרה לאחור
נכתבת מראש, מתוך הנחה שגל אחד ייכשל. תוכנית חזרה שנכתבת אחרי הכישלון היא כבר לא תוכנית.
- המקור נשאר במקומו
- המיגרציה היא העתקה. אין בשום שלב פקודה שמוחקת, מזיזה או משנה קובץ בארכיון המקורי, ולכן חזרה לאחור פירושה פשוט להפסיק להשתמש בתוצאה. אם המקור כבר נמחק - אין חזרה לאחור, וזו הסיבה שהמחיקה אינה חלק מהנוהל הזה.
- גל שנכשל מבוטל כיחידה
- כל גל מוגדר לפי טווח תאריכים ומקור, ולכן אפשר לזהות את מה שנוצר ממנו ולבטל אותו בלי לגעת בגלים אחרים. זו הסיבה להעביר בגלים ולא בהרצה אחת גדולה.
- קובץ המצב הוא נקודת השחזור
- הסוכן זוכר בקובץ מצב מה כבר טופל, כולל הגיבוב של כל קובץ. גיבוי של הקובץ הזה לפני כל גל מאפשר לחזור למצב שלפניו; מחיקה שלו גורמת לסריקה חוזרת של כל מה שבחלון, וזה בטוח - קובץ שכבר נקלט מתמזג עם השיחה הקיימת לפי שמו. מה שכן אובד עם קובץ המצב הוא אינדקס התוכן, ולכן עותק כפול שכבר נחסם עלול להיקלט אחרי מחיקה אם המקור שלו יצא בינתיים מהחלון. גיבוי, ולא מחיקה.
- ההרשאות מבוטלות לפני שמסיימים
- המפתח שנוצר להעברה משמש להעברה בלבד. בסוף הגל האחרון מבטלים אותו, וכך גם אם התיעוד יישכח במגירה, אי אפשר להשתמש בו.
מה המדריך הזה לא עושה
הגבולות כתובים במפורש, כי מדריך מיגרציה שמשאיר אותם מרומזים הוא מדריך שמישהו יקרא בשתיים בלילה.
- אין כאן שלב שמוחק
- שום שלב בנוהל אינו מוחק, מזיז או משנה קובץ במקור, וגם לא בסוף. מה עושים עם הארכיון המקורי אחרי שהספירה נסגרה היא החלטה נפרדת שלכם, שנשענת על בסיס ההחזקה ועל יעד השמירה שנקבע בשלב השני.
- לא להעלות אלינו ארכיון בלי חיבור מוגדר
- אין באתר הזה טופס העלאה, ואין לשלוח לנו הקלטות בדוא״ל, בקישור שיתוף או בכל דרך אחרת. העברה מתבצעת דרך חיבור מוגדר עם מפתח משלו, ואחרת אין לה תיעוד ואין לה בקרה.
- לא כל פורמט ישן נתמך
- הסוכן מזהה קבצים בסיומות wav, mp3, ogg, m4a, gsm, wma, aac ו-flac. פורמטים קנייניים ישנים, קבצים מוצפנים בכלי של ספק, או הקלטות שנשמרו בתוך מסד נתונים - אינם נכנסים בדרך הזו, ולא נבטיח אחרת. במקרים כאלה השאלה הראשונה היא אם המערכת הישנה יודעת לייצא, ולא איך אנחנו קוראים אותה.
- שמירה לנצח אינה תוצאה
- ארכיון שמועבר בלי יעד שמירה מייצר חשיפה חדשה במקום לצמצם אותה. לכל טווח תאריכים צריכה להיות החלטה: עד מתי מחזיקים ומה קורה אחר כך. זו הסיבה שיש טור כזה בגיליון והוא אינו רשות.
- אין כאן מחיר ואין שירות מיגרציה
- לא הגדרנו גבולות של שירות העברה, ולכן העמוד הזה אינו מציע כזה ואינו נוקב במחיר. מה שיש כאן הוא הנוהל עצמו, בצורה שמאפשרת לצוות פנימי או לאיש מקצוע שכבר עובד אתכם להריץ אותו.
שאלות שחוזרות
- אפשר פשוט לתת לכם גישה לדלי S3 או לשרת SFTP?
- לא. אלה שני חיבורים שמופיעים כערכים במערכת אבל אין מאחוריהם תהליך שמושך קבצים, ולכן אין מה לחבר. הדרך המעשית היא להוריד או לסנכרן את הקבצים לתיקייה שהסוכן המקומי רואה, או לשלוח אותם בהעלאה חתומה מסקריפט שרץ אצלכם.
- כמה זמן לוקחת העברה של ארכיון?
- החלק שקובע אינו הנפח אלא איכות שמות הקבצים. ארכיון עם תבנית שמות אחת ועקבית עובר בגלים תוך ימים; ארכיון עם חמש תבניות ותיקיות שהועתקו ידנית לאורך שנים דורש קודם עבודת סדר, ואת זה אי אפשר לדחוס. בדיקת המטא-דאטה בשלב השלישי היא שנותנת את התשובה, והיא עולה חצי שעה.
- אם אותה שיחה קיימת פעמיים תחת שני שמות, ניצור שתי רשומות?
- לא. לפני כל העלאה מחושב SHA-256 של הקובץ, וקובץ שתוכנו כבר נקלט - גם תחת שם אחר לגמרי - נרשם ככפילות ואינו נשלח. זה נבדק בהרצה שמתוארת כאן: עותק מדויק תחת שם שני נחסם, ובצד הקולט נוצרה רשומה אחת. שווה בכל זאת לספור גיבובים ייחודיים במקור, כדי שהספירה הסופית תדע לצפות לפער בין מספר הקבצים למספר הרשומות. שליחה חוזרת של אותו שם קובץ ממוזגת ממילא עם השיחה הקיימת.
- מה קורה לקובץ שאי אפשר לפרש את שמו?
- הוא נדחה ומדווח בשם, ולא מועלה עם ניחוש. זו בחירה מכוונת: שיחה שנקלטה עם מספר או מועד שגוי מתגלה בדרך כלל רק כשמישהו מבקש אותה, ואז כבר מאוחר. הטיפול הוא להוסיף תבנית שם מתאימה ולהריץ שוב את אותו טווח.
- ומה עם קובץ שקט או פגום?
- קובץ שנקלט אך אי אפשר להשמיע אותו, וכן קובץ WAV מסוג PCM שכל הדגימות בו אפס, מסומן ואינו נספר ככיסוי תקין. בהרצה שמתוארת כאן קובץ אחד כזה סומן מתוך תשעה. בארכיון ישן זה שיעור נורמלי לחלוטין, והוא ממצא על המערכת הישנה - לא על ההעברה.
- האם צריך למחוק את הארכיון הישן אחרי ההעברה?
- זו החלטה שלכם ואיננו קובעים אותה. הנוהל כאן אינו מוחק דבר, ובכוונה: מחיקה מוקדמת מבטלת את האפשרות לחזור לאחור. מה שכן נדרש הוא להחליט - להחזיק שני עותקים לנצח בלי החלטה הוא המצב הגרוע מבין השניים.
- ההעברה עצמה מחייבת לפתוח את הרשת החוצה?
- לא. הסוכן המקומי יוזם את החיבור החוצה בלבד ואינו מאזין לפורט. אין צורך ואין המלצה לחשוף תיקיית הקלטות לאינטרנט, לא לצורך העברה ולא אחריה.
ההקשר המשפטי, בקצרה
הסיבה שארכיונים ישנים עלו לסדר היום היא תיקון לחוק הגנת הצרכן שהתקבל בכנסת ב-17 ביולי 2026 ופורסם ברשומות ב-22 ביולי 2026 - חוק הגנת הצרכן (תיקון מס׳ 74), התשפ״ו-2026, המוסיף את סעיף 16ד. מועד התחילה הצפוי הוא 22 במרץ 2027. פירוט התחולה, תקופות השמירה ומועד המסירה נמצא בהסבר על החוק.
שתי נקודות שחשובות דווקא במיגרציה. הראשונה: החוק אינו מחייב להעביר ארכיון היסטורי לשום מקום, ואין בו נוהל מיגרציה - מה שהוא כן יוצר הוא חובות לגבי שיחות שבתחולה מכאן והלאה. השנייה, והחשובה יותר כאן: סעיף 16ד(ח)(1) קובע במפורש שאין בהוראות הסעיף כדי לגרוע מחוק הגנת הפרטיות, ובכלל זה מסעיף 11 לאותו חוק. כלומר העובדה שמותר או צריך להקליט שיחה אינה מכשירה כשלעצמה החזקה של הקלטות ישנות ללא בסיס - וזו הסיבה שהחלטת יעד השמירה נמצאת בשלב השני של הנוהל ולא בסופו.
שתי שאלות שנוגעות ישירות למי שמעביר ארכיון אינן מוכרעות בנוסח, ואיננו מכריעים בהן. הראשונה היא האם חובת השמירה שבהוראת המעבר ניתנת לאכיפה כבר היום, לפני מועד התחילה - מה שברור הוא שהוראת המעבר מודדת את חובת השמירה מיום הפרסום, ולכן מחיקה שנעשית עכשיו אינה הפיכה. השנייה היא איך איסור המחיקה ”אף לא לבקשת הצרכן“ מתיישב עם דרישת מחיקה לפי חוק הגנת הפרטיות. עד שתהיה תשובה, ההשלכה המעשית על הנוהל הזה אחת: הוא מעתיק ואינו מוחק, ומחיקה יזומה של ארכיון היא החלטה נפרדת שכדאי להיוועץ לפניה. לוח הזמנים למעבר מסביר את הוראת המעבר במלואה.
החומר כאן נכתב מתוך נוסח החוק שפורסם ברשומות, והוא הסבר תפעולי בלבד. הוא אינו ייעוץ משפטי, לא נבדק בידי עורך דין מטעמנו, ואינו מחליף בדיקה של הנוהל שלכם מול היועץ המשפטי שלכם ומול הרגולטור הענפי שלכם. אין באמור קביעה שהמצב אצלכם עומד בדרישה כלשהי. נוסח החוק המלא באתר הכנסת (PDF).
האמור כאן נבדק מול נוסח תיקון 74 שפורסם ברשומות ב-22 ביולי 2026, ונקרא מולו לאחרונה ב-2 באוגוסט 2026. לא נבדק בידי עורך דין מטעמנו.
אחרי שהספירה נסגרה
ארכיון שהועבר הוא נקודת התחלה, לא סיום. שלוש השורות שכדאי לסגור מיד אחריו: מה קורה להקלטות חדשות מכאן והלאה - זה עניין לחיבור קבוע ולא להעברה חד-פעמית; מה קורה כשלקוח מבקש הקלטה מהתקופה שהועברה, במסירת הקלטה ללקוח; ואיך נראים הבקרות והשמירה על החומר הזה בפועל, בעמוד האבטחה וביומן הביקורת.
ואם התוצאה של שלב המיפוי היא שאין למעשה ארכיון מסודר להעביר - זו גם תשובה, והיא חוסכת פרויקט. אז השאלה הנכונה היא מה מוקלט היום ומה חסר, וזו בדיוק ביקורת הכיסוי.
לפני שמעבירים ארכיון כדאי לדעת כמה מקום הוא תופס ומה זה עולה בשנה.
המחשבון רץ בדפדפן. אין הרשמה ואין מסירת דוא״ל.
להמשך קריאה
- סוכן תיקייה למרכזייה ישנהאיך מעלים הקלטות מתיקייה במרכזייה ותיקה או ב-Asterisk: התקנה, תבניות שמות קבצים, אזור זמן, זיהוי כפילויות לפי תוכן, קובץ מצב, בידוד, חלון הסריקה וניטור.
- ביקורת כיסוי הקלטותנוהל ביקורת בשבעה שלבים: לייצא רשומות שיחה, להצליב מול ההקלטות, לחשב יחס כיסוי ולסווג כל פער. כולל תבנית CSV להורדה ודוגמה מסונתזת מלאה.
- מערכת הקלטת שיחות לעסקיםעמוד הקטגוריה של VoiceBox: מה מערכת לניהול הקלטות עושה מעל קובץ ההקלטה - קליטה מהמרכזייה, שמירה ומחיקה מבוקרת, איתור שיחות שלא נקלטו ומסירה ללקוח.