@לעזור-לכולם כתב בעזרה בשליחת מיילים דרך AWS SES:
השרת שלך הוא בAWS?
כן,
הם אישרו לי את ההגדלה הראשונה,
אחרי שיצרתי שם כמה שירותים, ולפני שימוש משמעותי בזה
@לעזור-לכולם כתב בעזרה בשליחת מיילים דרך AWS SES:
השרת שלך הוא בAWS?
כן,
הם אישרו לי את ההגדלה הראשונה,
אחרי שיצרתי שם כמה שירותים, ולפני שימוש משמעותי בזה
@ע-ה-דכו-ע כתב בעזרה בשליחת מיילים דרך AWS SES:
למה באמת הם היו מיועדים?
בשבוע הראשון היה לי רק איפוסי סיסמאות וכו',
ואח"כ קמפיינים לפי פילוח של לקוחות, נניח לקוחות שגרים בעיר X - הודעה שיש מכירה בעיר שלהם, וכו'.
פתחו לי את המגבלה בשבוע שפתחתי את החשבון שם.
GPT כתב לי איזה בקשה לכתוב להם, למה מיועדים המיילים וכו',
ואישרו לי מיד 50000 ב24 שעות.
ואחכ ביקשתי עוד הגדלות, ועכשיו יש לי מגבלה של 150000
@meir-lamdan גם אני השתמשתי עם זה כמה פעמים.
וסוף סוף בצעתי פעולות שהיו צריכים נציג ופשוט לא היה לי סבלנות להמתין.
שאלתי את הנציגים אם הם שומעים שזה הגיע ממערכת מסוימת - הם אמרו שהם קיבלו את השיחה כמו כל שיחה נכנסת רגילה.
אתה לא חייב לכתוב את הת.ז. הנכונה - מקסימום כשתעבור לנציג (אם בכלל הם מקבלים את הת.ז. שרשמת) תגיד לו שטעית בת.ז.
ואתה ממש לא צריך לשתף סיסמאות..
יש לי מערכת גדולה שבניתי,
אני מחפש מישהו שיטפל בהעלאה של זה לAWS,
תוך טיפול באבטחה, עומסים וכו'.
העבודה היא גם בשלב הראשוני וגם תמיכה בהמשך.
אשמח להמלצה מהיכרות אישית על מישהו/חברה - שנותנים את השירות הזה.
תודה
@משתמש-מקצוען כתב בapi לא רשמי של ווטסאפ, סיכונים/מותר-אסור:
ומחר החברה שאתה משתמש איתה תיסגר בגלל תביעה, זה בדיוק כמו שיחסמו לך את המספר.
זה לא ממש ככה.
בשימוש בAPI לא רשמי זה כמו שימוש בווטאספ ווב.
וגם אם סוגרים את החברה שאתה משתמש איתה, תוכל לעבור לחברה אחרת, או פשוט לפתוח את זה על סמארטפון או במחשב..
@eido כתב במעבר על תיקיות ותתי תיקיות על כל קבציהן בלי רקורסיה:
אני צריך יותר "תוכנית עבודה"
אולי תעשה משהו בסגנון שמבצע ריצה כדי לקבל את כל הנתיבים של הקבצים.
ותשמור את זה כJSON בגוגל שיטס ששם תיצור נניח שורה לכל תהליך שרץ ובשמירה תפצל את הJSON לפי מספר קבצים או גודל קבצים - לכמה תאים בשורה של התהליך...
ואז תבצע תהליך כשכל תהליך מוריד את הקבצים בJSON של תא מסוים ובסיום קורא לאנדפוינט שמתקדם לתא הבא וכן הלאה..
אם מעניין אותך יש לי את הקוד הזה בnode.
שאני דבר ראשון מקבל את כל הנתיבים של הקבצים - שזה בקשות לא כבדות.
ואח"כ אני עובר על כל הקבצים עם מידע כמה אחוז כבר ירד (ושומר לקובץ ZIP את מה שנוצר)
// ============================================
// ייבוא מודולים
// ============================================
const axios = require('axios');
const fs = require('fs');
const path = require('path');
const archiver = require('archiver');
const TOKEN = "XX"
const API_BASE_URL = 'https://www.call2all.co.il/ym/api/';
const ITEMS_PER_REQUEST = 500;
// ============================================
// פונקציות עזר
// ============================================
/**
* יצירת תיקייה אם לא קיימת
*/
function ensureDir(dirPath) {
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath, { recursive: true });
}
}
/**
* מחיקת תיקייה רקורסיבית
*/
function removeDir(dirPath) {
if (fs.existsSync(dirPath)) {
fs.rmSync(dirPath, { recursive: true, force: true });
}
}
/**
* קבלת פרטי המערכת
*/
async function getSystemInfo() {
try {
const response = await axios.get(`${API_BASE_URL}GetSession`, {
params: {
token: TOKEN
}
});
if (response.data.responseStatus !== 'OK') {
throw new Error(`Error getting system info: ${response.data.message}`);
}
return response.data;
} catch (error) {
console.error('❌ שגיאה בקבלת פרטי מערכת:', error.message);
throw error;
}
}
/**
* קבלת תוכן תיקייה מהשרת
*/
async function getDirectoryContent(dirPath, filesFrom = 0, filesLimit = ITEMS_PER_REQUEST) {
try {
const response = await axios.get(`${API_BASE_URL}GetIVR2Dir`, {
params: {
token: TOKEN,
path: dirPath,
filesFrom,
filesLimit
}
});
if (response.data.responseStatus !== 'OK') {
throw new Error(`Error getting directory: ${response.data.message}`);
}
return response.data;
} catch (error) {
console.error(`❌ שגיאה בקבלת תוכן תיקייה ${dirPath}:`, error.message);
throw error;
}
}
/**
* הורדת קובץ בודד
*/
async function downloadFile(filePath, localPath) {
try {
const response = await axios.get(`${API_BASE_URL}DownloadFile`, {
params: {
token: TOKEN,
path: filePath
},
responseType: 'arraybuffer'
});
ensureDir(path.dirname(localPath));
fs.writeFileSync(localPath, response.data);
return true;
} catch (error) {
console.error(`❌ שגיאה בהורדת קובץ ${filePath}:`, error.message);
return false;
}
}
/**
* איסוף כל הקבצים מתיקייה (עם טיפול בפגינציה) - ללא הורדה
*/
async function collectFilesFromDir(dirPath) {
let filesFrom = 0;
let allFiles = [];
let allIni = [];
let allHtml = [];
// איסוף כל הקבצים (עם פגינציה)
while (true) {
const dirContent = await getDirectoryContent(dirPath, filesFrom, ITEMS_PER_REQUEST);
const currentFiles = dirContent.files || [];
const currentIni = dirContent.ini || [];
const currentHtml = dirContent.html || [];
allFiles.push(...currentFiles);
allIni.push(...currentIni);
allHtml.push(...currentHtml);
// אם קיבלנו פחות מהלימיט, זה אומר שזה הסיבוב האחרון
if (currentFiles.length < ITEMS_PER_REQUEST) {
break;
}
filesFrom += ITEMS_PER_REQUEST;
}
return [
...allFiles,
...allIni,
...allHtml
];
}
/**
* סריקה רקורסיבית של כל התיקיות - רק איסוף נתיבים
*/
async function scanRecursively(dirPath, localDirPath, filesList = []) {
// איסוף הקבצים מהתיקייה הנוכחית
const files = await collectFilesFromDir(dirPath);
// הוספת הקבצים למערך עם הנתיב המקומי
for (const file of files) {
filesList.push({
remotePath: file.what,
localPath: path.join(localDirPath, file.name),
name: file.name,
size: file.size || 0
});
}
// קבלת רשימת התיקיות
const dirContent = await getDirectoryContent(dirPath, 0, ITEMS_PER_REQUEST);
const dirs = dirContent.dirs || [];
// עיבוד כל תיקייה באופן רקורסיבי
for (const dir of dirs) {
const subDirPath = dir.what;
const localSubDirPath = path.join(localDirPath, dir.name);
await scanRecursively(subDirPath, localSubDirPath, filesList);
}
return filesList;
}
/**
* הורדת כל הקבצים עם התקדמות
*/
async function downloadAllFiles(filesList, concurrency = 10) {
let completed = 0;
const total = filesList.length;
const startTime = Date.now();
console.log(`\n⬇️ מתחיל הורדת ${total} קבצים...\n`);
// חלוקה לבאצ'ים להורדה מקבילית מבוקרת
for (let i = 0; i < filesList.length; i += concurrency) {
const batch = filesList.slice(i, i + concurrency);
const downloadPromises = batch.map(async (file) => {
const success = await downloadFile(file.remotePath, file.localPath);
completed++;
const percentage = Math.floor((completed / total) * 100);
const elapsed = ((Date.now() - startTime) / 1000).toFixed(0);
const estimatedTotal = total > 0 ? ((elapsed / completed) * total).toFixed(0) : 0;
const remaining = estimatedTotal - elapsed;
// עדכון progress bar
const barLength = 30;
const filled = Math.floor((completed / total) * barLength);
const bar = '█'.repeat(filled) + '░'.repeat(barLength - filled);
process.stdout.write(`\r[${completed}/${total}] ${bar} ${percentage}% | ${elapsed}s / ~${estimatedTotal}s`);
return success;
});
await Promise.all(downloadPromises);
}
console.log('\n');
return completed;
}
/**
* יצירת קובץ ZIP
*/
async function createZip(sourceDir, outputPath) {
return new Promise((resolve, reject) => {
const output = fs.createWriteStream(outputPath);
const archive = archiver('zip', {
zlib: { level: 9 } // דחיסה מקסימלית
});
output.on('close', () => {
console.log(`\n📦 קובץ ZIP נוצר: ${outputPath}`);
console.log(` גודל: ${(archive.pointer() / 1024 / 1024).toFixed(2)} MB`);
resolve();
});
archive.on('error', (err) => {
reject(err);
});
archive.pipe(output);
archive.directory(sourceDir, false);
archive.finalize();
});
}
/**
* פונקציה ראשית
*/
async function main() {
console.log('🚀 מתחיל תהליך גיבוי...\n');
// בדיקת טוקן
if (TOKEN === 'your-token-here') {
console.error('❌ שגיאה: לא הוגדר טוקן! הדבק את הטוקן שלך בתחילת הקובץ.');
process.exit(1);
}
const startTime = Date.now();
const startDate = new Date();
// יצירת פורמט תאריך מלא
const year = startDate.getFullYear();
const month = String(startDate.getMonth() + 1).padStart(2, '0');
const day = String(startDate.getDate()).padStart(2, '0');
const hours = String(startDate.getHours()).padStart(2, '0');
const minutes = String(startDate.getMinutes()).padStart(2, '0');
const seconds = String(startDate.getSeconds()).padStart(2, '0');
const dateTimeStr = `${year}-${month}-${day}_${hours}-${minutes}-${seconds}`;
try {
// קבלת פרטי מערכת
console.log('📋 מקבל פרטי מערכת...');
const systemInfo = await getSystemInfo();
const systemNumber = systemInfo.username || 'unknown';
console.log(` מערכת: ${systemNumber}`);
console.log(` שם: ${systemInfo.name || 'N/A'}\n`);
// יצירת תיקייה זמנית עם אותו שם כמו הקובץ
const backupName = `backup_${systemNumber}_${dateTimeStr}`;
const TEMP_DIR = path.join(__dirname, `temp_${backupName}`);
console.log('📁 יוצר תיקייה זמנית...');
ensureDir(TEMP_DIR);
// שלב 1: סריקה ואיסוף נתיבים
console.log('🔍 שלב 1: סורק תיקיות ואוסף רשימת קבצים...\n');
const allFiles = await scanRecursively('ivr2:/', TEMP_DIR);
const totalSize = allFiles.reduce((sum, file) => sum + (file.size || 0), 0);
const totalSizeMB = (totalSize / 1024 / 1024).toFixed(2);
console.log(`\n✅ סריקה הושלמה!`);
console.log(` 📊 נמצאו: ${allFiles.length} קבצים`);
console.log(` 💾 גודל כולל: ${totalSizeMB} MB\n`);
// שלב 2: הורדת קבצים
console.log('⬇️ שלב 2: מוריד קבצים...');
const successCount = await downloadAllFiles(allFiles, 10);
console.log(`✅ הורדה הושלמה: ${successCount}/${allFiles.length} קבצים\n`);
// יצירת קובץ ZIP
const zipPath = path.join(__dirname, `${backupName}.zip`);
console.log('\n📦 יוצר קובץ ZIP...');
await createZip(TEMP_DIR, zipPath);
// מחיקת תיקייה זמנית
console.log('🧹 מנקה תיקייה זמנית...');
removeDir(TEMP_DIR);
const duration = ((Date.now() - startTime) / 1000 / 60).toFixed(2);
console.log(`\n✅ הגיבוי הושלם בהצלחה!`);
console.log(`⏱️ זמן כולל: ${duration} דקות`);
console.log(`📁 קובץ הגיבוי: ${zipPath}`);
} catch (error) {
console.error('\n❌ שגיאה בתהליך הגיבוי:', error.message);
// ניקוי במקרה של שגיאה
if (TEMP_DIR) {
console.log('🧹 מנקה תיקייה זמנית...');
removeDir(TEMP_DIR);
}
process.exit(1);
}
}
// הרצת התוכנית
if (require.main === module) {
main();
}
שים לב שצריך להתקין את הספריות ולכתוב טוקן.
@Shmuel754 כתב בסליקת אשראי דרך api:
לפלא קארד, יש API המאפשר לשלוח מספר כרטיס ותוקף או טוקן.
https://gateway21.pelecard.biz/SandboxServices?selectedMethodId=62
אני לא יודע איך הגעת לקישור הזה.
זה לא הוכחה כי יכול להיות שזה רק למי שיש אישור PCI.
עד כמה שידוע לי אם אין לי אישור כזה אסור לי להחזיק (ובכלל זה גם לקבל בקשה מהאתר שלי לשרת שלי ולהעביר לשרת של חברת האשראי) מספר אשראי של לקוח.
@dovid
חברות ישראליות:
טרנזילה.
credit2000
נדרים פלוס
@dovid כתב בסליקת אשראי דרך api:
בטח שיש.
יש לך דוגמא של חברה כזו?
התממשקתי עם הרבה חברות ועדיין לא מצאתי חברה שנותנת לשלוח להם מספר כרטיס.
חיפשתי בעבר גם בלי קשר לנידון כאן..
@eido כתב בסליקת אשראי דרך api:
אני לא רואה מקום לשליחת מספר הכרטיס.
אין כזה דבר לשלוח מספר כרטיס בAPI (בהנחה ואין לך אישור PCI)
כל חברות האשראי עובדות בצורה שאתה מטמיע IFRAME שלהם (בצורה כזו או אחרת).
ושם הלקוח מזין את פרטי התשלום,
ואז אתה מקבל callback לשרת שלך עם הטוקן ופרטי הלקוח.
@eido כתב בלוגי שגיאה בnodejs וyemotrouter מה הגורם לקריסה?:
הtry/catch הארוך הוא כי עשיתי שינוי על שינוי לטובת הלקוח. אז נשאר כזה ארוך, סתם להבין מה רע בזה?
1 - בגדול זה שזה ארוך זה לא ממקד אותך בבעיה
2 - הוא כתב שעדיף בלי, כי אם אתה לא מטפל בשגיאה אז זה נזרק הלאה ויש לו בספריה טיפול בשגיאות.
אז אתה יכול לטפל שם בשגיאות..
@ששא זה לא מדויק.
יש לי לקוחות שיוצרים אתרים עם AI
אבל כשזה משהו שבאמת מנהל מערכת כספית מורכבת הם פשוט לא סומכים על זה
שבמקרה מסוים החישובים וכו' לא יהיו נכונים.
לנדרים פלוס יש אפשרות לשלוח callback על כל עיסקה שקורית..
@יעקב-מ.-פינס
עם iframe יכול להיות לך טוב?
@י.פל. למה שלא תעשה את זה כסאב דומיין שיפנה ישירות להוסטינגר?