חיבור ימות המשיח
למערכות מתקדמות

המדריך השלם למתחילים - מאיסוף נתונים פשוט ועד שיח חכם עם בינה מלאכותית (AI) דרך הטלפון.

מילון מונחים למתחילים

Deploy: הפעלה של המערכת לאוויר.
Repository: תיקיית הפרויקט בגיטאהב.
Settings: הגדרות.
Create: יצירה של משהו חדש.
Keys: מפתחות אבטחה.
Value: הערך שצריך להכניס.
01

הכנת גיליון גוגל (Sheets)

  1. פתחו גיליון Google Sheets חדש.
  2. בשורה 1 כתבו: ID במשבצת הראשונה, ו-Content בשנייה.
  3. העתיקו מהכתובת למעלה את ה-ID של הגיליון (זהו רצף האותיות הארוך שבין ה-/d/ לבין ה-/edit). שמרו אותו בצד.
02

הגדרות Google Cloud (חיבור הרובוט)

כאן אנחנו יוצרים "חשבון שירות" (רובוט) שיוכל לכתוב בגיליון שלכם.
  1. היכנסו ל-Google Cloud Console וצרו פרויקט חדש.
  2. חפשו Google Sheets API ולחצו על Enable.
  3. תחת IAM & Admin עברו ל-Service Accounts וצרו חשבון חדש.
  4. בלשונית Keys לחצו על Add Key ואז Create New Key בפורמט JSON.
  5. חשוב: קובץ יירד למחשב. פתחו אותו בכתבן (Notepad) - נצטרך את כל מה שכתוב בו ל-Vercel.
  6. העתיקו את כתובת המייל של החשבון שיצרתם, לכו לגיליון שלכם ולחצו על "שיתוף" (Share) והוסיפו את המייל הזה כ-Editor.
03

העלאת הקוד ל-GitHub

צרו Repository חדש בגיטאהב והעלו לתוכו את הקבצים הבאים (שימו לב לשמות המדויקים):

server.js
const express = require('express');
const cors = require('cors');
const { GoogleSpreadsheet } = require('google-spreadsheet');
const { JWT } = require('google-auth-library');
const path = require('path');

const app = express();
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, 'public')));

const SHEET_ID = process.env.SHEET_ID;
const GOOGLE_SERVICE_ACCOUNT = process.env.GOOGLE_SERVICE_ACCOUNT;

async function getDoc() {
    if (!GOOGLE_SERVICE_ACCOUNT || !SHEET_ID) {
        throw new Error("חסרים נתוני התחברות לגוגל");
    }
    const credentials = JSON.parse(GOOGLE_SERVICE_ACCOUNT);
    const serviceAccountAuth = new JWT({
        email: credentials.client_email,
        key: credentials.private_key,
        scopes: ['https://www.googleapis.com/auth/spreadsheets'],
    });
    const doc = new GoogleSpreadsheet(SHEET_ID, serviceAccountAuth);
    await doc.loadInfo();
    return doc;
}

app.all('/api/ymotAddText', async (req, res) => {
    try {
        const id = req.query.new_id;
        const content = req.query.new_content;
        if (!id || !content) return res.send("id_list_message=t-שגיאה, חסרים נתונים");
        const doc = await getDoc();
        const sheet = doc.sheetsByIndex[0];
        await sheet.addRow({ ID: id, Content: content });
        res.send("id_list_message=t-הנתונים נשמרו בהצלחה למערכת");
    } catch (error) { res.send("id_list_message=t-חלה שגיאה בשמירת הנתונים"); }
});

app.get('/api/ymotGetText', async (req, res) => {
    try {
        const id = req.query.id_to_search;
        if (!id) return res.send("id_list_message=t-לא התקבל מזהה לחיפוש");
        const doc = await getDoc();
        const sheet = doc.sheetsByIndex[0];
        const rows = await sheet.getRows();
        const row = rows.find(r => r.get('ID') === String(id));
        if (row) res.send(`id_list_message=t-${row.get('Content')}`);
        else res.send("id_list_message=t-המזהה לא נמצא באקסל");
    } catch (error) { res.send("id_list_message=t-חלה שגיאת מערכת בחיפוש"); }
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
module.exports = app;
package.json
{
  "name": "ymot-texts-api",
  "version": "1.0.0",
  "main": "server.js",
  "scripts": { "start": "node server.js" },
  "dependencies": {
    "express": "^4.18.2",
    "cors": "^2.8.5",
    "google-auth-library": "^9.0.0",
    "google-spreadsheet": "^4.1.1"
  }
}
vercel.json
{
  "version": 2,
  "builds": [{ "src": "server.js", "use": "@vercel/node" }],
  "rewrites": [{ "source": "/(.*)", "destination": "/server.js" }]
}
04

הפצה ב-Vercel (דיפלוי)

  1. התחברו ל-Vercel עם חשבון ה-GitHub שלכם.
  2. לחצו על Add New Project וייבאו את המאגר שיצרתם.
  3. לפני הלחיצה על Deploy, היכנסו ל-Environment Variables והוסיפו 2 סודות:
    • SHEET_ID : המזהה מהשלב הראשון.
    • GOOGLE_SERVICE_ACCOUNT : כל הטקסט שמופיע בקובץ ה-JSON (המפתח).
  4. לחצו Deploy. בסיום תקבלו כתובת אתר (למשל: my-api.vercel.app).
05

הגדרת השלוחה בימות המשיח

עברו לניהול הקו שלכם והגדירו בקובץ ext.ini:

שלוחה להכנסת נתונים (API)

type=api
api_link=https://YOUR-APP.vercel.app/api/ymotAddText
api_000=new_id,yes,10,1,10,HebrewKeyboard,no,no,no,no,no,no,no,no,yes
api_001=new_content,yes,100,1,10,HebrewKeyboard,no,no,no,no,no,no,no,no,yes

שלוחה לשמיעת נתונים

type=api
api_link=https://YOUR-APP.vercel.app/api/ymotGetText
api_000=id_to_search,yes,10,1,10,HebrewKeyboard,no,no,no,no,no,no,no,no,yes
חשוב: החליפו את הקישור YOUR-APP.vercel.app בכתובת שקיבלתם מ-Vercel!

איך זה עובד?

במערכת הזו, המאזין יכנס לשלוחה אחת ויקליד שאלה (למשל: "מי היה הרמבם?"). השאלה נשלחת לגיליון גוגל שלכם. ברגע שהשאלה נוחתת בגיליון, מופעל קוד סודי ששולח את השאלה למוח של הבינה המלאכותית (Gemini). הבינה המלאכותית כותבת תשובה בגיליון, והמאזין עובר לשלוחה השנייה כדי לשמוע את התשובה שמקריא לו הרובוט של ימות המשיח!

AI (בינה מלאכותית): מחשב חכם שיודע לקרוא טקסט ולענות תשובות כמו בן אדם. אנו נשתמש במערכת בשם Gemini של חברת גוגל.
API Key: מפתח סודי. כמו סיסמה מיוחדת שמאפשרת לקוד שלנו "לדבר" עם הבינה המלאכותית.
Apps Script: המקום מאחורי הקלעים של גוגל שיטס שבו אנחנו שמים קוד שעושה פעולות אוטומטיות.
Trigger (טריגר): "הדק". הגדרה שאומרת לגוגל: "ברגע שקורה משהו (למשל התווספה שאלה), תפעיל את הקוד מיד!".
01

הכנת גיליון גוגל והטמעת קוד הבינה

בשלב זה נכניס את ה"מוח" לתוך גיליון האקסל שלנו כדי שיענה על שאלות שמגיעות.
  1. פתחו גיליון Google Sheets חדש, ושנו את השם של הגיליון למטה ל: מענה AI.
  2. הכינו עמודות בשורה הראשונה: בעמודה A כתבו "זמן", ב-B "מספר שורה", ב-C "טקסט השאלה", ב-D "תשובת AI מלאה", וב-E "טקסט מסונן".
  3. בתפריט העליון לחצו על Extensions (תוספים) ואז על Apps Script.
  4. יפתח לכם חלון קוד. תמחקו את כל מה שכתוב שם, והדביקו את הקוד הבא:
// הכניסו כאן את מפתח ה-API שלכם מ-Google AI Studio
const GEMINI_API_KEY = "הכניסו_כאן_את_המפתח_שלכם"; 

function processNewQuestions(e) {
  // פונקציה זו תופעל בכל פעם ש-Vercel מכניס שאלה חדשה
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("מענה AI");
  if (!sheet) return;
  
  const lastRow = sheet.getLastRow();
  // אם אין שאלות, לא לעשות כלום
  if (lastRow <= 1) return; 
  
  // נקרא את השאלה האחרונה שנכנסה
  const questionRange = sheet.getRange(lastRow, 3); // עמודה C היא השאלה
  const answerRange = sheet.getRange(lastRow, 4); // עמודה D היא התשובה המלאה
  const cleanedAnswerRange = sheet.getRange(lastRow, 5); // עמודה E היא התשובה הנקייה
  
  const question = questionRange.getValue();
  const currentAnswer = answerRange.getValue();
  
  // אם יש שאלה ועדיין אין תשובה - נפעיל את ה-AI
  if (question && !currentAnswer) {
    try {
      const prompt = "אתה עוזר חכם. ענה בקצרה ובשפה ברורה על השאלה הבאה: " + question;
      const aiResponseText = callGemini(prompt);
      
      const cleanedText = cleanText(aiResponseText); // ניקוי טקסט לימות המשיח
      
      // כתיבת התשובות חזרה לגיליון
      answerRange.setValue(aiResponseText);
      cleanedAnswerRange.setValue(cleanedText);
      
      logEntry(lastRow, prompt, "הצלחה", "תשובה התקבלה", aiResponseText);
      
    } catch (error) {
      answerRange.setValue("שגיאה בקבלת תשובה.");
      cleanedAnswerRange.setValue("שגיאה.");
      logEntry(lastRow, question, "שגיאה", error.toString(), "");
    }
  }
}

// התחברות למוח של גוגל - Gemini
function callGemini(prompt) {
  const url = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=${GEMINI_API_KEY}`;
  const payload = { "contents": [{ "parts": [{ "text": prompt }] }] };
  
  const options = {
    method: "post",
    contentType: "application/json",
    payload: JSON.stringify(payload)
  };
  
  const response = UrlFetchApp.fetch(url, options);
  const json = JSON.parse(response.getContentText());
  return json.candidates[0].content.parts[0].text;
}

// מנקה כוכביות וסימנים כדי שהרובוט הטלפוני יקריא ברור
function cleanText(text) {
  return text.replace(/[*#_`]/g, "").trim();
}

function logEntry(rowNumber, prompt, status, response, aiText) {
  let logSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Logs");
  if (!logSheet) { logSheet = SpreadsheetApp.getActiveSpreadsheet().insertSheet("Logs"); }
  logSheet.appendRow([new Date(), rowNumber, prompt, status, response, aiText]);
}
                    
מאיפה מביאים API Key? חפשו בגוגל "Google AI Studio API Key", התחברו עם חשבון הגוגל שלכם, לחצו על "Create API Key" והעתיקו את הרצף הארוך. את הרצף הזה הדביקו בתוך המרכאות בשורה הראשונה של הקוד למעלה במקום הטקסט "הכניסו_כאן_את_המפתח_שלכם".

הגדרת טריגר (הדק אוטומטי) - קריטי מאוד!

  1. בצד שמאל של מסך ה-Apps Script, חפשו סמל של שעון מעורר (Triggers / מפעילים).
  2. לחצו על הכפתור הכחול למטה למטה: Add Trigger (הוספת מפעיל).
  3. בחלון שיפתח, הגדירו כך:
    • בחר פונקציה: processNewQuestions
    • בחר מקור אירוע: מגיליון אלקטרוני (From spreadsheet)
    • בחר סוג אירוע: בעת שינוי (On change)
  4. לחצו שמור. גוגל יבקש מכם אישור אבטחה (לחצו Advanced -> Go to script -> Allow).
02

העלאת קוד השרת ל-GitHub

עכשיו נכין את קוד השרת (server.js) שיקבל את ההקשה מימות המשיח ויעביר אותה לגיליון. שימו לב שקוד זה שונה מהמדריך הבסיסי ומותאם למערכת הבינה המלאכותית שלנו.

server.js
const express = require('express');
const cors = require('cors');
const { GoogleSpreadsheet } = require('google-spreadsheet');
const { JWT } = require('google-auth-library');
const path = require('path');

const app = express();
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

const SHEET_ID = process.env.SHEET_ID;
const GOOGLE_SERVICE_ACCOUNT = process.env.GOOGLE_SERVICE_ACCOUNT;

async function getDoc() {
    if (!GOOGLE_SERVICE_ACCOUNT || !SHEET_ID) {
        throw new Error("שגיאת קונפיגורציה: חסרים סודות במשתני הסביבה");
    }
    const credentials = JSON.parse(GOOGLE_SERVICE_ACCOUNT);
    const serviceAccountAuth = new JWT({
        email: credentials.client_email,
        key: credentials.private_key,
        scopes: ['https://www.googleapis.com/auth/spreadsheets'],
    });
    const doc = new GoogleSpreadsheet(SHEET_ID, serviceAccountAuth);
    await doc.loadInfo();
    return doc;
}

// שלוחה 1: קבלת השאלה מימות המשיח והכנסתה לגיליון
app.all('/api/ymotAskAI', async (req, res) => {
    try {
        const question = req.query.question_text;
        const phone = req.query.ApiPhone || "לא ידוע";
        
        if (!question) return res.send("id_list_message=t-לא זוהתה הקשה");
        
        const doc = await getDoc();
        const sheet = doc.sheetsByTitle["מענה AI"]; // חובה שהגיליון יקרא כך
        
        // מכניסים את השאלה לעמודה C (הגיליון מסדר את העמודות לפי הכותרות)
        await sheet.addRow({ "זמן": new Date().toLocaleString(), "מספר שורה": phone, "טקסט השאלה": question });
        
        res.send("id_list_message=t-שאלתך התקבלה המתן מספר שניות לתשובה");
    } catch (error) { res.send("id_list_message=t-חלה שגיאה במערכת"); }
});

// שלוחה 2: חיפוש התשובה הנקייה בגיליון והקראתה
app.all('/api/ymotReadAI', async (req, res) => {
    try {
        const phone = req.query.ApiPhone; // נחפש לפי מספר הטלפון
        const doc = await getDoc();
        const sheet = doc.sheetsByTitle["מענה AI"];
        
        const rows = await sheet.getRows();
        // מחפשים מהסוף להתחלה כדי למצוא את השאלה האחרונה של המשתמש הזה
        let userRow = null;
        for (let i = rows.length - 1; i >= 0; i--) {
            if (rows[i].get("מספר שורה") === String(phone)) {
                userRow = rows[i];
                break;
            }
        }
        
        if (userRow && userRow.get("טקסט מסונן")) {
            const answer = userRow.get("טקסט מסונן");
            res.send(`id_list_message=t-${answer}`);
        } else {
            res.send("id_list_message=t-התשובה עדיין לא מוכנה נסה שוב");
        }
    } catch (error) { res.send("id_list_message=t-חלה שגיאה במשיכת התשובה"); }
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
module.exports = app;

קובץ ה- package.json וקובץ ה- vercel.json נשארים בדיוק אותו דבר כמו במדריך הבסיסי (לשונית קודמת).

03

הפצה ב-Vercel (דיפלוי)

התהליך זהה לחלוטין למה שלמדנו: מייבאים את המאגר ל-Vercel, שמים את ה-SHEET_ID ואת ה-GOOGLE_SERVICE_ACCOUNT, ומריצים Deploy.

04

הגדרת השלוחות בימות המשיח

שלוחה 1 - לשאול את השאלה

שימו לב: הערך העשירי הושאר ריק כדי לאפשר הקשת טקסט חופשית כבקשתכם, והוספנו המתנה ותיבת סימון כדי להרוויח זמן עד שהבינה המלאכותית תסיים לכתוב בגיליון.

type=api
api_link=https://YOUR-APP.vercel.app/api/ymotAskAI

; קבלת הטקסט מהמשתמש - שינוי הערך העשירי לריק כדי לאפשר הקשה
api_000=question_text,yes,100,1,10,HebrewKeyboard,no,no,no,,no,no,no,no,yes

; קבלת החלטה לגבי תיבת הסימון
; שינוי זמן המתנה ל-7 שניות, סוג השמעה ל-Digits, וריק בערך העשירי
api_001=checkbox_choice,yes,1,1,7,Digits,no,no,no,,no,no,no,no,no

api_timeout=20
api_hangup_send=no

שלוחה 2 - לשמוע את תשובת ה-AI

אחרי שהמאזין חיכה קצת בשלוחה 1, הלקוח יעבור לשלוחה זו (יש להגדיר מעבר אוטומטי בימות המשיח) וישמע את התשובה.

type=api
api_link=https://YOUR-APP.vercel.app/api/ymotReadAI
תזכורת חמה: אל תשכחו לשנות את YOUR-APP.vercel.app לכתובת האמיתית שוורסל נתן לכם!