• דף הבית
    • אינדקס קישורים
    • פוסטים אחרונים
    • משתמשים
    • חיפוש בהגדרות המתקדמות
    • חיפוש גוגל בפורום
    • ניהול המערכת
    • ניהול המערכת - שרת private
    • הרשמה
    • התחברות

    מדריך מלא: חיבור Google Chat ל-Apps Script ומשם לימות — עוקף את החסימה, גם בלי חשבון עסקי

    מתוזמן נעוץ נעול הועבר עזרה הדדית למשתמשים מתקדמים
    3 פוסטים 2 כותבים 26 צפיות 1 עוקבים
    טוען פוסטים נוספים
    • מהישן לחדש
    • מהחדש לישן
    • הכי הרבה הצבעות
    תגובה
    • תגובה כנושא
    התחברו כדי לפרסם תגובה
    נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
    • ד מנותק
      דורש 3
      נערך לאחרונה על ידי דורש 3


      ב"ה

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

      הרעיון

      רוצים בוט שיושב בקבוצת גוגל צ'אט, קורא מה שנכתב, ומגיב. שתי הדרכים הרשמיות של גוגל, Webhook או רישום אפליקציית Chat, שתיהן דורשות חשבון עסקי Workspace עם הרשאות מנהל, ולכן חסומות בחשבון פרטי. כאן נופלים רוב האנשים.

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

      אם אתם רוצים רק בוט בקבוצה, עצרו אחרי שלב 8. החלקים של השיחות הפרטיות ושל ימות בסוף הם תוספות נפרדות.

      שלב 1: חשבון בוט

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

      שלב 2: פרויקט Apps Script

      נכנסים ל-script.google.com, מחוברים לחשבון הבוט ולא לשלכם. הכי בטוח בחלון גלישה פרטית עם חשבון הבוט בלבד, כדי לא ליצור את הסקריפט בטעות תחת החשבון הלא נכון. לוחצים פרויקט חדש.

      שלב 3: הפעלת שירות Chat

      בצד שמאל בעורך יש Services עם סימן פלוס. לוחצים פלוס, בוחרים Google Chat API, Add. זה מה שנותן לקוד לקרוא ולכתוב הודעות. בלי זה תקבלו שגיאה שהמשתנה Chat לא מוגדר, וזאת הטעות הכי נפוצה.

      שלב 4: מזהה הקבוצה

      פותחים את הקבוצה בדפדפן ומסתכלים בשורת הכתובת. יש שם קטע כמו space/AAAA. מעתיקים את החלק הזה, אבל שימו לב, בקוד צריך לכתוב אותו עם s, כלומר spaces/AAAA. זו נקודת מעידה קלאסית, אז תוודאו שיש s.

      שלב 5: הקוד

      אם רוצים תשובות חכמות, צריך מפתח Gemini. משיגים אותו חינם ב-Google AI Studio, בכפתור Get API key. אם לא בא לכם, אפשר לדלג, והבוט יחזיר תשובת בדיקה במקום.

      מדביקים את הקוד במקום מה שהיה. משנים רק את מזהה הקבוצה למעלה, ואת מפתח ה-Gemini אם יש.

      const SPACE = 'spaces/PASTE_SPACE_ID';
      const GEMINI_API_KEY = 'PASTE_GEMINI_KEY';
      const GEMINI_MODEL = 'gemini-flash-lite-latest';
      const TRIGGER = /בוט/i;
      
      function checkMessages() {
        const props = PropertiesService.getScriptProperties();
        const last = props.getProperty('last');
        if (!last) { props.setProperty('last', new Date().toISOString()); return; }
      
        const res = Chat.Spaces.Messages.list(SPACE, { pageSize: 15, orderBy: 'createTime desc' });
        const fresh = (res.messages || []).filter(m => m.createTime > last);
        if (!fresh.length) return;
        props.setProperty('last', fresh[0].createTime);
        fresh.reverse();
      
        for (const m of fresh) {
          if (isSelf(m)) continue;
          const t = (m.text || '').trim();
          if (!t || !TRIGGER.test(t)) continue;
          const answer = ask(t);
          if (answer) post(SPACE, answer);
        }
      }
      
      function isSelf(m) {
        const me = Session.getActiveUser().getEmail();
        return m.sender && m.sender.email && m.sender.email === me;
      }
      
      function ask(question) {
        if (!GEMINI_API_KEY || GEMINI_API_KEY.indexOf('PASTE') === 0) return 'קיבלתי: ' + question;
        const url = 'https://generativelanguage.googleapis.com/v1beta/models/' + GEMINI_MODEL + ':generateContent?key=' + GEMINI_API_KEY;
        const body = { contents: [{ role: 'user', parts: [{ text: question }] }] };
        const r = UrlFetchApp.fetch(url, { method: 'post', contentType: 'application/json', payload: JSON.stringify(body), muteHttpExceptions: true });
        if (r.getResponseCode() !== 200) return null;
        try { return JSON.parse(r.getContentText()).candidates[0].content.parts.map(p => p.text).join('').trim(); }
        catch (e) { return null; }
      }
      
      function post(space, text) {
        UrlFetchApp.fetch('https://chat.googleapis.com/v1/' + space + '/messages', {
          method: 'post', contentType: 'application/json',
          headers: { Authorization: 'Bearer ' + ScriptApp.getOAuthToken() },
          payload: JSON.stringify({ text: text }), muteHttpExceptions: true
        });
      }
      

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

      שלב 6: הרצה ראשונה והרשאות

      בוחרים למעלה את checkMessages ולוחצים Run. גוגל תבקש הרשאות, מאשרים. אם קופצת אזהרה שהאפליקציה לא מאומתת, זה תקין כי זו אפליקציה פרטית שלכם, לוחצים Advanced ואז Go to project וממשיכים. ההרצה הראשונה לא תעשה כלום חוץ מלרשום נקודת התחלה, וזה בכוונה, כדי שהבוט לא יגיב לכל ההיסטוריה הישנה בבת אחת.

      שלב 7: טריגר כל דקה

      בצד שמאל יש אייקון שעון, Triggers. Add Trigger, בוחרים את checkMessages, מקור Time-driven, סוג Minutes timer, כל דקה. שומרים. מעכשיו זה רץ לבד בענן של גוגל, גם כשהמחשב כבוי.

      שלב 8: בדיקה

      מהחשבון האישי שלכם כותבים בקבוצה: בוט מה שלומך. תוך דקה הבוט עונה.

      אם משהו לא עובד

      אין תגובה בכלל, תבדקו ב-Executions אם הפונקציה בכלל רצה. שגיאה על Chat פירושה שדילגתם על שלב 3. רץ בלי שגיאה ובלי תגובה פירושו שהבוט לא חבר בקבוצה או שהמזהה שגוי. אם הבוט מגיב לעצמו בלולאה, אתם לא מריצים מחשבון הבוט. אם הבוט הגיב פתאום להמון הודעות ישנות, דילגתם על ההרצה הראשונה, אז כבו את הטריגר, הריצו ידנית פעם אחת, והפעילו מחדש.

      מה עם משתמש בודד ולא קבוצה

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

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

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

      // מחזיר את מזהה השיחה הפרטית עם משתמש מסוים (users/1234...)
      function getDmSpace(userId) {
        const token = ScriptApp.getOAuthToken();
      
        // קודם מנסים למצוא שיחה קיימת
        const find = UrlFetchApp.fetch(
          'https://chat.googleapis.com/v1/spaces:findDirectMessage?name=' + encodeURIComponent(userId),
          { headers: { Authorization: 'Bearer ' + token }, muteHttpExceptions: true });
        if (find.getResponseCode() === 200) {
          return JSON.parse(find.getContentText()).name; // spaces/XXXX
        }
      
        // אם אין - פותחים שיחה חדשה עם המשתמש
        const setup = UrlFetchApp.fetch('https://chat.googleapis.com/v1/spaces:setup', {
          method: 'post', contentType: 'application/json',
          headers: { Authorization: 'Bearer ' + token },
          payload: JSON.stringify({
            space: { spaceType: 'DIRECT_MESSAGE' },
            memberships: [{ member: { name: userId, type: 'HUMAN' } }]
          }),
          muteHttpExceptions: true
        });
        if (setup.getResponseCode() === 200) {
          return JSON.parse(setup.getContentText()).name;
        }
        console.log('לא הצלחתי לפתוח שיחה', setup.getContentText());
        return null;
      }
      

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

      כדי להאזין לכמה שיחות במקביל, קבוצות ושיחות פרטיות מעורבב, ההבדל היחיד הוא שצריך חותמת זמן נפרדת לכל שיחה, אחרת הן דורסות אחת את השנייה. מחליפים את checkMessages בשתי הפונקציות האלה, ומפנים את הטריגר ל-checkAll. שאר הפונקציות, isSelf ו-ask ו-post, נשארות כמו שהן.

      const SPACES = ['spaces/GROUP_ID', 'spaces/DM_ID']; // קבוצות ושיחות פרטיות מעורבב
      
      function checkAll() {
        for (const space of SPACES) checkOne(space);
      }
      
      function checkOne(space) {
        const props = PropertiesService.getScriptProperties();
        const key = 'last_' + space; // חותמת נפרדת לכל שיחה
        const last = props.getProperty(key);
        if (!last) { props.setProperty(key, new Date().toISOString()); return; }
      
        const res = Chat.Spaces.Messages.list(space, { pageSize: 15, orderBy: 'createTime desc' });
        const fresh = (res.messages || []).filter(m => m.createTime > last);
        if (!fresh.length) return;
        props.setProperty(key, fresh[0].createTime);
        fresh.reverse();
      
        for (const m of fresh) {
          if (isSelf(m)) continue;
          const t = (m.text || '').trim();
          if (!t) continue; // בשיחה פרטית כל הודעה ממילא מכוונת לבוט, אז בלי מילת הפעלה
          const answer = ask(t);
          if (answer) post(space, answer);
        }
      }
      

      אם רוצים למצוא שיחה פרטית דרך getDmSpace ולהוסיף אותה להאזנה, פשוט קוראים לפונקציה עם מזהה המשתמש ושמים את התוצאה בתוך רשימת ה-SPACES.

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

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

      הפתרון הוא רכיב מגשר קטן באמצע, במקום שכן מורשה לדבר עם ימות. אני עשיתי את זה עם Cloudflare Worker, שזה סקריפט קטן שרץ אצלם בענן ולא עולה כלום בכמויות האלה. הסקריפט מדבר עם הגשר, והגשר מדבר עם ימות.

      יוצרים אותו ככה: נרשמים ב-dash.cloudflare.com, נכנסים ל-Workers, יוצרים Worker חדש, מדביקים את הקוד הבא במקום מה שיש, ולוחצים Deploy.

      export default {
        async fetch(request, env) {
          if (request.method !== 'POST') return new Response('POST only', { status: 405 });
          if (request.headers.get('X-Auth') !== env.SHARED_SECRET) return new Response('forbidden', { status: 403 });
      
          const data = await request.json();
          const form = new URLSearchParams();
          form.set('token', env.YEMOT_TOKEN);
          form.set('what', 'ivr2:' + data.ext + '/' + data.file);
          form.set('contents', data.contents);
      
          const r = await fetch('https://www.call2all.co.il/ym/api/UploadTextFile', {
            method: 'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            body: form
          });
          return new Response(await r.text(), { status: r.status });
        }
      };
      

      אחרי שיצרתם אותו, נכנסים ב-Cloudflare ל-Settings ואז Variables, ומוסיפים שני משתני סוד. הראשון YEMOT_TOKEN, שהערך שלו הוא מספר המערכת שלכם, נקודתיים, ואז הסיסמה. השני SHARED_SECRET, שהוא סתם מחרוזת אקראית שאתם ממציאים, ומשמשת מפתח בין הסקריפט לגשר. בראש עמוד ה-Worker תראו את הכתובת שלו, משהו שמסתיים ב-workers.dev, תעתיקו אותה.

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

      const BRIDGE_URL = 'https://your-worker.workers.dev'; // הכתובת שהעתקתם
      const BRIDGE_SECRET = 'PASTE_SHARED_SECRET';           // אותו SHARED_SECRET
      const YEMOT_EXT = '5';        // מספר השלוחה בקו שבחרתם
      const YEMOT_FILE = '000.tts'; // שם הקובץ שיוקרא
      
      function syncToYemot() {
        const msgs = Chat.Spaces.Messages.list(SPACE, { pageSize: 10, orderBy: 'createTime desc' }).messages || [];
        const withText = msgs.filter(m => m.text && m.text.trim()).reverse();
        if (!withText.length) return;
      
        const lines = withText.map(m => {
          const who = m.sender && m.sender.displayName ? m.sender.displayName : 'מישהו';
          return who + ' כתב: ' + m.text.trim();
        });
        const digest = 'ההודעות האחרונות בקבוצה. ' + lines.join('. ');
      
        UrlFetchApp.fetch(BRIDGE_URL, {
          method: 'post', contentType: 'application/json',
          headers: { 'X-Auth': BRIDGE_SECRET },
          payload: JSON.stringify({ ext: YEMOT_EXT, file: YEMOT_FILE, contents: digest }),
          muteHttpExceptions: true
        });
      }
      

      נותנים גם לפונקציה הזאת טריגר משלה, בדיוק כמו בשלב 7, כל דקה או שתיים. אם עברתם למסלול ריבוי-השיחות, פשוט תנו ל-syncToYemot את מזהה הקבוצה שאתם רוצים לשדר לטלפון במקום SPACE.

      בצד ימות צריך שלוחה אחת פשוטה שמקריאה את הקובץ. יוצרים שלוחה, נניח 5, ובקובץ ההגדרות שלה שמים:

      type=playfile
      enter_id=no
      

      זהו. מי שמחייג לשלוחה שומע את הקובץ 000.tts שהבוט מעדכן. שימו לב שהשלוחה חייבת להיות קיימת לפני שהבוט מעלה אליה, כי ה-API של ימות לא יוצר שלוחות לבד.

      איך זה נראה בסוף

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

      אם נתקעתם באחד מהשלבים, תכתבו כאן ואשתדל לענות.

      מ תגובה 1 תגובה אחרונה תגובה ציטוט 2
      • מ מנותק
        מ.ל.ל @דורש 3
        נערך לאחרונה על ידי

        @דורש-3 לא הבנתי אם זה על קבוצה בלבד או על כל שיחה שיש לי עם משתמש ?

        ד תגובה 1 תגובה אחרונה תגובה ציטוט 0
        • ד מנותק
          דורש 3 @מ.ל.ל
          נערך לאחרונה על ידי

          @מ.ל.ל כתב:

          @דורש-3 לא הבנתי אם זה על קבוצה בלבד או על כל שיחה שיש לי עם משתמש ?

          שאלה מצוינת. התשובה הקצרה: זה עובד בדיוק אותו דבר, כי בגוגל צ'אט גם שיחה פרטית עם משתמש בודד היא בעצם חלל (Space), רק מסוג אחר. קבוצה היא חלל מסוג SPACE, ושיחה פרטית אחד על אחד היא חלל מסוג DIRECT_MESSAGE. מרגע שיש לכם את המזהה של החלל הפרטי, כל שאר המנגנון זהה, אותה בדיקה מחזורית ואותה תגובה.

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

          איך משיגים את מזהה השיחה הפרטית עם משתמש מסוים

          יש שתי דרכים.

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

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

          // מחזירה את מזהה השיחה הפרטית עם משתמש מסוים (users/1234...)
          function getDmSpace(userId) {
            const token = ScriptApp.getOAuthToken();
          
            // קודם מנסים למצוא שיחה קיימת
            const find = UrlFetchApp.fetch(
              'https://chat.googleapis.com/v1/spaces:findDirectMessage?name=' + encodeURIComponent(userId),
              { headers: { Authorization: 'Bearer ' + token }, muteHttpExceptions: true });
            if (find.getResponseCode() === 200) {
              return JSON.parse(find.getContentText()).name; // spaces/XXXX
            }
          
            // אם אין - פותחים שיחה חדשה עם המשתמש
            const setup = UrlFetchApp.fetch('https://chat.googleapis.com/v1/spaces:setup', {
              method: 'post', contentType: 'application/json',
              headers: { Authorization: 'Bearer ' + token },
              payload: JSON.stringify({
                space: { spaceType: 'DIRECT_MESSAGE' },
                memberships: [{ member: { name: userId, type: 'HUMAN' } }]
              }),
              muteHttpExceptions: true
            });
            if (setup.getResponseCode() === 200) {
              return JSON.parse(setup.getContentText()).name;
            }
            console.log('לא הצלחתי לפתוח שיחה', setup.getContentText());
            return null;
          }
          

          איך גורמים לבוט לענות לכמה שיחות פרטיות במקביל

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

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

          // רשימת החללים שהבוט מאזין להם - אפשר לערבב קבוצות ושיחות פרטיות
          const SPACES = [
            'spaces/PASTE_GROUP_ID',   // קבוצה
            'spaces/PASTE_DM_ID'       // שיחה פרטית עם משתמש מסוים
          ];
          
          function checkAll() {
            for (const space of SPACES) {
              checkOneSpace(space);
            }
          }
          
          function checkOneSpace(space) {
            const props = PropertiesService.getScriptProperties();
            const key = 'last_' + space;           // חותמת זמן נפרדת לכל חלל
            const last = props.getProperty(key);
          
            if (!last) { props.setProperty(key, new Date().toISOString()); return; }
          
            const res = Chat.Spaces.Messages.list(space, { pageSize: 15, orderBy: 'createTime desc' });
            const fresh = (res.messages || []).filter(m => m.createTime > last);
            if (!fresh.length) return;
            props.setProperty(key, fresh[0].createTime);
            fresh.reverse();
          
            for (const m of fresh) {
              if (isSelf(m)) continue;
              const t = (m.text || '').trim();
              if (!t) continue;
              // בשיחה פרטית לרוב לא צריך מילת הפעלה, כי כל הודעה מכוונת לבוט
              const answer = ask(t);
              if (answer) postTo(space, answer);
            }
          }
          
          // כמו post מהמדריך, רק שמקבל לאיזה חלל לכתוב
          function postTo(space, text) {
            UrlFetchApp.fetch('https://chat.googleapis.com/v1/' + space + '/messages', {
              method: 'post', contentType: 'application/json',
              headers: { Authorization: 'Bearer ' + ScriptApp.getOAuthToken() },
              payload: JSON.stringify({ text: text }), muteHttpExceptions: true
            });
          }
          

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

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

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

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

          תגובה 1 תגובה אחרונה תגובה ציטוט 1

          שלום! נראה שהשיחה הזו מעניינת אותך, אבל עדיין אין לך חשבון.

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

          בעזרת התרומה שלך, הפוסט הזה יכול להיות אפילו טוב יותר 💗

          הרשמה התחברות
          • פוסט ראשון
            פוסט אחרון