אני עובד על שירות לבניית קווי מכירות
כל קו מכיל שלוחת הודעות, שולחת הרשמה לצינתוק, שלוחת מכירות, שלוחת השארת הודעה להנהלה (למייל), ושלוחת השארת הודעה של ההנהלה (עם רשימה לבנה).
אם יש מישהו שמקים קווי מכירות אשמח להתנסות עליו.
תודה.
אני עובד על שירות לבניית קווי מכירות
כל קו מכיל שלוחת הודעות, שולחת הרשמה לצינתוק, שלוחת מכירות, שלוחת השארת הודעה להנהלה (למייל), ושלוחת השארת הודעה של ההנהלה (עם רשימה לבנה).
אם יש מישהו שמקים קווי מכירות אשמח להתנסות עליו.
תודה.
@THMHE תחפש כאן
יש שם הרבה אופציות תראה אם משהו מתאים לך
לדעתי אפשר גם להחליף את כל הודעות המערכת בהודעה שמתאימה לך,ככה שזה לא אמור להיות בעיה.
@THMHE אם זה סוג של תשלום אפשר להשתמש במכירות לפי מק"ט להגדיר מוצר בשקל ואז שיבחר כמות זה בעצם יבחר את הסכום וישמיע כסכום (למרות שיכול להיות שישמיע לא טוב) להגדיר תשלום מזומן ולאחר הקניה שיעבור לשלוחה מסוימת, לדעתי זה אפשרי אבל אני לא יכול עכשיו לבדוק את זה
@א-תורת-מרן רשימת תפוצה חינמית שנרשמים אליה לצינתוקים (כמו של הבתי ספר) או רשימת תפוצה בתשלום?
תפרט קצת יותר מה אתה מתכוון
@soris1989 כתב בבקשת POST בC# יוצרת שגיאה:
@עידו מה שדיברנו עד עכשיו זה שגיאה בשליחת בקשת POST ב-C#, ב-PHP אין את הבעיה הזו.
תשתמש בפונקציה הבאה:
<?php function sendPostRequest($url, $data, $headers = []) { $ch = curl_init($url); // Convert data to JSON $jsonData = json_encode($data); // Set headers $defaultHeaders = [ 'Content-Type: application/json', 'Content-Length: ' . strlen($jsonData) ]; $headers = array_merge($defaultHeaders, $headers); // cURL options curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // צריך להגדיר כדי שתוכל לשלוח בקשות ללא SSL curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // צריך להגדיר כדי שתוכל לשלוח בקשות ללא SSL curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // Execute request $response = curl_exec($ch); // Handle errors if ($response === false) { return "cURL Error: " . curl_error($ch); } curl_close($ch); return $response; }
גם עכשיו שלחתי בC# רק שבשביל להיות בטוח במה שהhttpclient שולח (ההדר והתוכן) עשיתי עמוד PHP שיחזיר בדיוק את הבקשה שנשלחה, ומהערך שחוזר רואים שהתוכן שנשלח הוא תקין, גם מבחינת ההדר שלו, שהוא של ג'סון ולא משהו אחר
@soris1989 כתב בבקשת POST בC# יוצרת שגיאה:
@עידו כתב בבקשת POST בC# יוצרת שגיאה:
@soris1989 כתב בבקשת POST בC# יוצרת שגיאה:
@עידו אז בסופו של דבר הצלחת לקבל את פרטי ה-request בשליחת בקשה מהמחשב לשרת?
כן, הקוד שלמעלה זה תחילת הבקשה שנשלחת לשרת. לכאורה הכל נראה תקין... לא יודע למה מות המשיח עושים בעיות...
מה הבעיות שהם עושים?
מה שדיברנו עד עכשיו, הם לא מזהים את תוכן הבקשה, מבחינתם הbody לא קיים
@soris1989 כתב בבקשת POST בC# יוצרת שגיאה:
@עידו אז בסופו של דבר הצלחת לקבל את פרטי ה-request בשליחת בקשה מהמחשב לשרת?
כן, הקוד שלמעלה זה תחילת הבקשה שנשלחת לשרת. לכאורה הכל נראה תקין... לא יודע למה מות המשיח עושים בעיות...
@soris1989 @צדיק-תמים
מבדיקה שלי הוא כן שולח עם הדר של ג'סון.
זה הקוד שמחזיר את הבקשה כמו שהיא
<?php
header('Content-Type: application/json');
// פונקציה לקבלת גוף הבקשה הגולמי (raw body)
function getRawBody() {
return file_get_contents('php://input');
}
// יצירת מערך עם כל פרטי הבקשה
$requestData = [
'method' => $_SERVER['REQUEST_METHOD'],
'headers' => getallheaders(),
'GET' => $_GET,
'POST' => $_POST,
'FILES' => $_FILES,
'COOKIE' => $_COOKIE,
'raw_body' => getRawBody(),
'server' => $_SERVER,
];
// פלט JSON יפה לקריאה
echo json_encode($requestData, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
זה הקוד שחזר (חתכתי את הסוף)
"method": "POST",
"headers": {
"Content-Type": "application/json; charset=utf-8",
"Host": "www.stamandsefer.co.il",
"Content-Length": "26555",
"Expect": "100-continue",
"Connection": "Keep-Alive"
},
"GET": [],
"POST": [],
"FILES": [],
"COOKIE": [],
"raw_body": "{\"what\":\"ivr2:SaleProducts/sale_products_name.ini\",\"contents\":\"001=\\u05D6\\u05D5\\u05E8\\u05E2 \\u05D5\\u05E7\\u05D5\\u05E6\\u05E8 \\u05D0 \\u05D1\\u05E8\\u05D0\\u05E9\\u05D9\\u05EA \\u05D7\\u05DC\\u05E7 \\u05D0\\r\\n002=\\u05D3\\u05D1\\u05E8 \\u05D1\\u05E2\\u05D9\\u05EA\\u05D5 - \\u05DE\\u05E7\\u05E8\\u05D0\\u05D4 \\u05D0 \\u05DB\\u05D9\\u05EA\\u05D4 \\u05D0\\r\\n003=\\u05E7\\u05DC \\u05DC\\u05DB\\u05EA\\u05D5\\u05D1 \\u05D1\\u05DB\\u05EA\\u05D1 \\u05D0 \\u05D7\\u05DC\\u05E7 1\\r\\n004=\\u05D9\\u05E9 \\u05E4\\u05EA\\u05E8\\u05D5\\u05DF \\u05D7\\u05DC\\u05E7 1\\r\\n005=\\u05D9\\u05E9 \\u05E4\\u05EA\\u05E8\\u05D5\\u05DF \\u05D7\\u05DC\\u05E7 2\\r\\n006=\\u05D9\\u05E9 \\u05E4\\u05EA\\u05E8\\u05D5\\u05DF \\u05D4\\u05E0\\u05D3\\u05E1\\u05D4 \\u05D7\\u05DC\\u05E7 1\\r\\n007=\\u05E1\\u05D9\\u05D3\\u05D5\\u05E8 \\u0022\\u05E2\\u0022\\u0022\\u05DE\\u0022\\r\\n008=\\u05D6\\u05D5\\u05E8\\u05E2 \\u05D5\\u05E7\\u05D5\\u05E6\\u05E8 2\\r\\n009=\\u05D6\\u05D5\\u05E8\\u05E2 \\u05D5\\u05E7\\u05D5\\u05E6\\u05E8 3\\r\\n010=\\u05D7\\u05D5\\u05DE\\u05E9 \\u05E9\\u05DE\\u05D5\\u05EA \\r\\n011=\\u05D7\\u05D5\\u05DE\\u05E9 \\u05D1\\u05E8\\u05D0\\u05E9\\u05D9\\u05EA \\r\\n012=\\u05D3\\u05D1\\u05E8 \\u05D1\\u05E2\\u05D9\\u05EA\\u05D5 - \\u05DE\\u05E7\\u05E8\\u05D0\\u05D4 \\u05DB\\u05D9\\u05EA\\u05D4 \\u05D1\\r\\n013=\\u05E1\\u05D5\\u05D3\\u05D5\\u05EA \\u05D4\\u05DB\\u05EA\\u05D9\\u05D1 \\u05DB\\u05D9\\u05EA\\u05D4 \\u05D1\\r\\n014=\\u05D7\\u05D5\\u05D1\\u05E8\\u05EA \\u05DB\\u05EA\\u05D9\\u05D1\\u05D4 \\u05EA\\u05DE\\u05D4 \\r\\n015=\\u05D1\\u05D9\\u05DF \\u05D4\\u05E9\\u05D5\\u05E8\\u05D5\\u05EA \\u05DB\\u05D9\\u05EA\\u05D4 \\u05D1\\r\\n016=\\u05D9\\u05E9 \\u05E4\\u05EA\\u05E8\\u05D5\\u05DF \\u05D7\\u05DC\\u05E7 1\\r\\n017=\\u05D9\\u05E9 \\u05E4\\u05EA\\u05E8\
@soris1989 כתב בבקשת POST בC# יוצרת שגיאה:
@עידו כי זה בקשות ששלחת מהקוד שלך וזה לא אמור לנטר את הבקשות ששלחת מהשרת שלך לשרת של ימות המשיח, אלא להאזין לבקשות שמתקבלות בשרת שלך. במידה ותרצה לנטר גם בקשות שאתה שולח מהקוד שלך, עליך להשתמש ב-logs, יש ספריות מוכנות ב-C# שעושות לך את כל הקטע של logging. תבדוק ב-chatgpt איך לממש את זה בקוד ממש פשוט.
using System; using System.Net.Http; using System.Threading; using System.Threading.Tasks; public class LoggingHandler : DelegatingHandler { public LoggingHandler(HttpMessageHandler innerHandler) : base(innerHandler) { } protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { Console.WriteLine($"[Request] {request.Method} {request.RequestUri}"); // Log Headers foreach (var header in request.Headers) { Console.WriteLine($" {header.Key}: {string.Join(", ", header.Value)}"); } // If there's content, log its headers too if (request.Content != null) { foreach (var header in request.Content.Headers) { Console.WriteLine($" Content-{header.Key}: {string.Join(", ", header.Value)}"); } } var response = await base.SendAsync(request, cancellationToken); Console.WriteLine($"[Response] {response.StatusCode}"); return response; } } class Program { static async Task Main() { var client = new HttpClient(new LoggingHandler(new HttpClientHandler())); var request = new HttpRequestMessage(HttpMethod.Get, "https://jsonplaceholder.typicode.com/posts/1"); request.Headers.Add("Custom-Header", "MyValue"); var response = await client.SendAsync(request); } }
את ה- Console.WriteLine תחליף בספריית LOG
אני שולח מהמחשב לשרת, לא מהשרת לשרת, לא יודע למה הוא לא מנטר את זה.
אבדוק יותר מאוחר איך לממש את זה, תודה
@soris1989 כתב בבקשת POST בC# יוצרת שגיאה:
@עידו באיזו שפה אתה כותב?
אם זה אתה משתמש באחסון VPS, אז תוכל ללכת לתיקית ה-apache או ngnix ושם יש לוגים של כל הבקשות שנכנסות לשרת.
באחסון שיתופי (shared), אתה יכול להנפיק את קובץ ה-LOG דרך הקוד של השפה שבה אתה כותב, מן הסתם ה-entry point של האפליקציה שלך מקבלת את ה-request שמכיל מידע על הבקשה וה-headers שלה.
אני כותב בעיקר C# ואם צריך משתמש בchatgpt לphp או לשאר השפות - כמו שאמרתי, אני לא מתכנת.
בדקתי את הלוגים של השרת ומשום מה הבקשות ששלחתי לא מופיעות שם לא ברור לי למה...
@soris1989 כתב בבקשת POST בC# יוצרת שגיאה:
@עידו זה משהו שאתה מטמיע בקוד אצלך, ודרך הקוד נתוני ה-request מוכנסים לתוך קובץ log.
אתה כותב ב-asp.net?
אני לא כותב בASP ולדעתי השרת לא יודע להריץ ASP
תודה
@soris1989 כתב בבקשת POST בC# יוצרת שגיאה:
@עידו אתה יכול בקוד להשתמש בסיפריות מוכנות של Logging לתוך קובץ.
הקוד הבא מאפשר את קבלת המחרוזת של ה-curl:
static async Task UploadTextFileWithPost2() { var url = "https://www.call2all.co.il/ym/api/UploadTextFile"; try { var client = new HttpClient(); var obj = new { token = $"{Username}:{Password}", what = "ivr2:14/text_file.ini", contents = "Some test message" }; var json = JsonConvert.SerializeObject(obj); var content = new StringContent(json, Encoding.UTF8, "application/json"); // Generate cURL command string curlCommand = GenerateCurlCommand("POST", url, client, content); Console.WriteLine("Generated cURL:"); Console.WriteLine(curlCommand); var responseJ2 = await client.PostAsync(url, content); // בדיקת מצב התגובה if (responseJ2.IsSuccessStatusCode) { // קריאת התוכן של התגובה var responseContent2 = await responseJ2.Content.ReadAsStringAsync(); Console.WriteLine($"Response: {responseContent2}"); } else { Console.WriteLine($"Error: {responseJ2.StatusCode}"); return; } } catch (Exception ex) { Console.WriteLine($"Exception: {ex.Message}"); } await Task.Delay(1000); Console.WriteLine("Async work done!"); } static string GenerateCurlCommand(string method, string url, HttpClient client, HttpContent content) { StringBuilder sb = new StringBuilder(); sb.Append($"curl -X {method} "); // Add headers foreach (var header in client.DefaultRequestHeaders) { sb.Append($"-H \"{header.Key}: {string.Join("; ", header.Value)}\" "); } // Add content body if (content != null) { string body = content.ReadAsStringAsync().Result; sb.Append($"-d '{body}' "); } // Add URL sb.Append(url); return sb.ToString(); }
המתודה GenerateCurlCommand, פולטת לך string עם ה- curl, את ה-string הזה תדפיס בתוך קובץ log או משהו בסגנון. וזה לגבי בקשות שאתה מריץ מהקוד שלך.
לגבי בדיקת בקשות שנכנסות למערכת שלך, במידה ואתה כותב ב asp.net core, אז תיצור middleware באופן הבא:
using Microsoft.AspNetCore.Http; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using Microsoft.Extensions.Logging; public class RequestLoggingMiddleware { private readonly RequestDelegate _next; private readonly ILogger<RequestLoggingMiddleware> _logger; public RequestLoggingMiddleware(RequestDelegate next, ILogger<RequestLoggingMiddleware> logger) { _next = next; _logger = logger; } public async Task InvokeAsync(HttpContext httpContext) { // Log request method, URL, and headers _logger.LogInformation("Request Method: {Method}, Request URL: {Url}", httpContext.Request.Method, httpContext.Request.Path); // Log all headers foreach (var header in httpContext.Request.Headers) { _logger.LogInformation("Header: {Header}: {Value}", header.Key, header.Value); } // Call the next middleware in the pipeline await _next(httpContext); } }
בקוד של asp.net (לא CORE), תשים ב-global.asax:
using System; using System.Web; public class Global : HttpApplication { protected void Application_BeginRequest(object sender, EventArgs e) { HttpContext context = HttpContext.Current; // Log request method and URL var method = context.Request.HttpMethod; var url = context.Request.Url.ToString(); // Log all headers foreach (var header in context.Request.Headers.AllKeys) { var headerValue = context.Request.Headers[header]; System.Diagnostics.Debug.WriteLine($"Header: {header}: {headerValue}"); } // Log method and URL System.Diagnostics.Debug.WriteLine($"Request Method: {method}, Request URL: {url}"); } }
בשרת שלי אין net (סייבר פאנל מבוסס לינוקס)
@soris1989 יש לי שרת, איך אני יכול לראות בו בדיוק מה מגיע אליו? כולל ההדר?
@soris1989 אבל בקוד רגיל בC# לא מוסיפים את זה, אני לא הוספתי בכל אופן...
@soris1989 כתב בבקשת POST בC# יוצרת שגיאה:
POSTMAN: curl --location --request POST 'https://www.call2all.co.il/ym/api/UploadTextFile' \ --header 'Content-Type: application/json' \ --data-raw '{ "token": "<username>:<password>", "what": "ivr2:14/text_file.ini", "contents": "Some text message" }' c#: curl -X POST -d '{"token":"<username>:<password>","what":"ivr2:14/text_file.ini","contents":"Some test message"}' https://www.call2all.co.il/ym/api/UploadTextFile
תגוובה ב-POSTMAN:
{ "responseStatus": "OK", "message": "ok", "yemotAPIVersion": 6 }
תגובה ב-C#:
Response: {"yemotAPIVersion":6,"responseStatus":"EXCEPTION","message":"IllegalStateException(session token is required)"
אז ככה, ב-C# ברגע שאתה משייך flag של -d ל-curl, זה אוטומטית יוצר בקשה עם:
Content-Type: application/x-www-form-urlencoded
וזה לא נשלח עם:
Content-Type: application/json
ה-body שנשלח לשרת של ימות הוא בפורמט json בעוד שה-content-type בפורמט של:
x-url-encoded.לאחר מכן, ניסיתי לכפות על ה-httpClient לשים header של Content-Type: application/json, אך הוא מתעלם מזה....
ומכאן נובעת השגיאה, הבעיה היא לא בימות המשיח, אלא באופן בניית ה-CURL ב-C#, שה-body שנשלח לא תואם ל-content-type ב-header.
לא ממש הבנתי על איזה flag או d דיברת, אבל זה מעניין, למה אתרים אחרים כן מקבלים את זה?
ולכאורה בקוד פשוט שלחת JSON אז למה בכל זאת הוא לא שולח את זה כסוג JSON?
@צדיק-תמים
אני יודע 3 דברים:
מה רץ מאחורי הקלעים ואיזה עוד אינפורמציה מועברת בדרך, אני לא יודע.
מה שבטוח ימות המשיח מסרבים להתייחס לתוכן הג'סון.
@צדיק-תמים אני יודע איך הבקשה נראית בפועל, אני כבר אחרי כל זה...
@צדיק-תמים כתב בבקשת POST בC# יוצרת שגיאה:
אתה מכיר את mitmproxy? יש לו ממשק וובי שמאפשר לראות את התוכן בפועל של בקשות
לא מכיר, אבל גם jsonplaceholder נותן אפשרות
@צדיק-תמים כתב בבקשת POST בC# יוצרת שגיאה:
@עידו כתב בבקשת POST בC# יוצרת שגיאה:
והם לא מוכנים לקבל אותו כשהוא נשלח ע"י ספריה מסוימת (שבה משתמשים היום) בשפה מסוימת, אולי אני טועה אבל לפי הבנתי יש להם בשרת בעיה עם איך שC# מממשים את הפרוטוקול הזה.
במילים אחרות, אם אני - מתכנת C# (אני לא, למעשה אני רחוק מזה, אבל זה לא הנקודה) - רוצה לכתוב קוד שיתקשר עם השרת שלהם, והולך לפי התיעוד הרשמי שלהם, אני בבעיה, מה שאין כן אם אני מתכנת בPHP או שפות אחרות, שאז הכל חלק.
על זה בדיוק אני אומר שאין כזה דבר (כלומר הכל יכול להיות תיאורטית, הכוונה שיש לזה סבירות אפסית), ובוא ננסה להבין איפה שורש הבעיה. כי היא ב100% לא במימוש של C#
נכון, היא במימוש של ימות המשיח, כי שם זה לא עובד... באתרים אחרים כן...