case 4670 multiple changes by Claude to break out message sending from the individual forms and support the trial server request
This commit is contained in:
@@ -1,228 +1,165 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Net.Mail;
|
||||
using System.Net;
|
||||
//for captcha:
|
||||
using System.Net.Http;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
|
||||
namespace contact.Pages
|
||||
{
|
||||
[BindProperties(SupportsGet = true)]
|
||||
public class RequestFormModel
|
||||
{
|
||||
public RequestFormModel()
|
||||
{
|
||||
DataCenter = "SF";
|
||||
}
|
||||
[Required]
|
||||
public string Name { get; set; }
|
||||
[Required]
|
||||
public string Company { get; set; }
|
||||
|
||||
[Required, EmailAddress]
|
||||
public string Email { get; set; }
|
||||
[Required]
|
||||
public string DataCenter { get; set; }
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class RequestModel : PageModel
|
||||
{
|
||||
// public string DataCenter { get; set; }
|
||||
[BindProperty(SupportsGet = true)]
|
||||
public RequestFormModel SubRequest { get; set; }
|
||||
|
||||
public List<SelectListItem> DataCenters { get; } = new List<SelectListItem>
|
||||
{
|
||||
new SelectListItem { Value = "SF", Text = "San Francisco" },
|
||||
new SelectListItem { Value = "NY", Text = "New York" },
|
||||
new SelectListItem { Value = "TOR", Text = "Toronto" },
|
||||
new SelectListItem { Value = "AMS", Text = "Amsterdam" },
|
||||
new SelectListItem { Value = "LON", Text = "London" },
|
||||
new SelectListItem { Value = "FFT", Text = "Frankfurt" },
|
||||
new SelectListItem { Value = "SNG", Text = "Singapore" },
|
||||
new SelectListItem { Value = "BNG", Text = "Bangalore" },
|
||||
new SelectListItem { Value = "SYD", Text = "Sydney Australia" }
|
||||
|
||||
};
|
||||
|
||||
private readonly IConfiguration _configuration;
|
||||
public RequestModel(IConfiguration configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
public ActionResult OnPost()
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return Page();
|
||||
}
|
||||
|
||||
//2025-11-01 Google dropping support for captcha, just nuking it for now, see how much spam I get
|
||||
// if (!ReCaptchaPassed(
|
||||
// Request.Form["g-recaptcha-response"], // that's how you get it from the Request object
|
||||
// _configuration.GetSection("GoogleReCaptcha:secret").Value
|
||||
// ))
|
||||
// {
|
||||
// //Return a fail code that will hopefully take us off the spammers list
|
||||
// return StatusCode(500);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
//fuck those spammers
|
||||
//2022-05-06 changes to get rid of jumbo lead magnet spammer but still force him to pay someone to manually enter the stuff
|
||||
//ideally it should read from a text file here but this is a quickie fix while Joyce is on important viha phone call
|
||||
var blocks = new List<string>();
|
||||
blocks.Add("google");
|
||||
blocks.Add("jumboleadmagnet");//<--fuck this guy in particular, keeps spamming
|
||||
blocks.Add("boostleadgeneration");
|
||||
//ericjonesmyemail@gmail.com
|
||||
var companyname = SubRequest.Company.ToLowerInvariant();
|
||||
foreach (string s in blocks)
|
||||
{
|
||||
if (companyname.Contains(s))
|
||||
{
|
||||
goto skipspam;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
PostRequestToSockeye();
|
||||
SendMail();
|
||||
|
||||
skipspam:
|
||||
return Redirect("https://ayanova.com/docs/ay-evaluate/");
|
||||
}
|
||||
|
||||
private void PostRequestToSockeye()
|
||||
{
|
||||
|
||||
using var client = new HttpClient();
|
||||
//client.BaseAddress = new System.Uri("https://sockeye.ayanova.com");///api/v8.0/subscription-server/
|
||||
|
||||
var r = new
|
||||
{
|
||||
dataCenter = SubRequest.DataCenter,
|
||||
email = SubRequest.Email,
|
||||
company = SubRequest.Company,
|
||||
name = SubRequest.Name,
|
||||
rValue = "totallylegit"
|
||||
};
|
||||
|
||||
|
||||
HttpContent body = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(r),
|
||||
System.Text.Encoding.UTF8,
|
||||
"application/json");
|
||||
var response = client.PostAsync("https://sockeye.ayanova.com/subscription-server-trial-request", body).Result;
|
||||
//var response = client.PostAsync("http://localhost:7676/subscription-server-trial-request", body).Result;
|
||||
|
||||
// if (response.IsSuccessStatusCode)
|
||||
// {
|
||||
// var content = await response.Content.ReadAsStringAsync();
|
||||
// if (!string.IsNullOrEmpty(content))
|
||||
// {
|
||||
// var objDeserializeObject = JsonConvert.DeserializeObject<SongsModel>(content);
|
||||
|
||||
// Console.WriteLine("Data Saved Successfully.");
|
||||
|
||||
// if (objDeserializeObject != null)
|
||||
// {
|
||||
// Console.WriteLine(objDeserializeObject.Name);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void SendMail()
|
||||
{
|
||||
var MessageBody = $"Name:\r\n{SubRequest.Name}\r\n\r\nCompany:\r\n{SubRequest.Company}\r\n\r\nDataCenter:\r\n{SubRequest.DataCenter}";
|
||||
|
||||
//SEND TO US
|
||||
using (var message = new MailMessage())
|
||||
{
|
||||
message.To.Add(new MailAddress("support@ayanova.com"));
|
||||
message.From = new MailAddress(SubRequest.Email);
|
||||
message.Subject = $"Trial request from {SubRequest.Company}";
|
||||
message.Body = MessageBody;
|
||||
using (var smtpClient = new SmtpClient("smtp.fastmail.com"))
|
||||
{
|
||||
|
||||
smtpClient.Host = "smtp.fastmail.com";
|
||||
smtpClient.Port = 587;
|
||||
smtpClient.UseDefaultCredentials = false;
|
||||
//testing
|
||||
smtpClient.EnableSsl = true;
|
||||
|
||||
// smtpClient.Port=465;
|
||||
// smtpClient.DeliveryMethod= SmtpDeliveryMethod.Network;
|
||||
|
||||
|
||||
|
||||
//NOTE: Do not use the noreply email address to send mail, it crashes the server somehow
|
||||
|
||||
//******************************************************************************************************************
|
||||
//******************************************************************************************************************
|
||||
//TEST CRASH
|
||||
// smtpClient.Credentials = new System.Net.NetworkCredential("noreply@ayanova.com", "91768700489f8edd28aa71e3e0f4073eba54ce83c4c1a6a910700fa94094ddfd");
|
||||
|
||||
|
||||
//FASTMAIL CHANGES
|
||||
//Fastmail server names and ports help page: https://www.fastmail.help/hc/en-us/articles/1500000278342
|
||||
//APP Password created in fastmail for smtp use only labelled 'contact-form': cnea8agl6nlx5j7l
|
||||
|
||||
//try using from as support@onayanova.com
|
||||
//try domain version if this still won't work
|
||||
smtpClient.Credentials = new System.Net.NetworkCredential("support@onayanova.com", "cnea8agl6nlx5j7l");
|
||||
//******************************************************************************************************************
|
||||
//******************************************************************************************************************
|
||||
|
||||
smtpClient.Send(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void OnGet()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//2025-11-01 Google dropping support for captcha, just nuking it for now, see how much spam I get
|
||||
// public static bool ReCaptchaPassed(string gRecaptchaResponse, string secret)
|
||||
// {
|
||||
// HttpClient httpClient = new HttpClient();
|
||||
// var res = httpClient.GetAsync($"https://www.google.com/recaptcha/api/siteverify?secret={secret}&response={gRecaptchaResponse}").Result;
|
||||
// if (res.StatusCode != HttpStatusCode.OK)
|
||||
// {
|
||||
// // logger.LogError("Error while sending request to ReCaptcha");
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// string JSONres = res.Content.ReadAsStringAsync().Result;
|
||||
// dynamic JSONdata = JObject.Parse(JSONres);
|
||||
// if (JSONdata.success != "true")
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// return true;
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Threading.Tasks;
|
||||
using contact.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace contact.Pages
|
||||
{
|
||||
[BindProperties(SupportsGet = true)]
|
||||
public class RequestFormModel
|
||||
{
|
||||
public RequestFormModel()
|
||||
{
|
||||
DataCenter = "SF";
|
||||
}
|
||||
[Required]
|
||||
public string Name { get; set; }
|
||||
[Required]
|
||||
public string Company { get; set; }
|
||||
[Required, EmailAddress]
|
||||
public string Email { get; set; }
|
||||
[Required]
|
||||
public string DataCenter { get; set; }
|
||||
}
|
||||
|
||||
public class RequestModel : PageModel
|
||||
{
|
||||
private const string EvaluateUrl = "https://ayanova.com/docs/ay-evaluate/";
|
||||
|
||||
[BindProperty(SupportsGet = true)]
|
||||
public RequestFormModel SubRequest { get; set; }
|
||||
|
||||
//Set when neither Sockeye nor the email got the request, so the page can say so
|
||||
public bool SendFailed { get; set; }
|
||||
|
||||
public List<SelectListItem> DataCenters { get; } = new List<SelectListItem>
|
||||
{
|
||||
new SelectListItem { Value = "SF", Text = "San Francisco" },
|
||||
new SelectListItem { Value = "ATL", Text = "Atlanta" },
|
||||
new SelectListItem { Value = "NY", Text = "New York" },
|
||||
new SelectListItem { Value = "TOR", Text = "Toronto" },
|
||||
new SelectListItem { Value = "AMS", Text = "Amsterdam" },
|
||||
new SelectListItem { Value = "LON", Text = "London" },
|
||||
new SelectListItem { Value = "FFT", Text = "Frankfurt" },
|
||||
new SelectListItem { Value = "SNG", Text = "Singapore" },
|
||||
new SelectListItem { Value = "BNG", Text = "Bangalore" },
|
||||
new SelectListItem { Value = "SYD", Text = "Sydney Australia" }
|
||||
};
|
||||
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly MailSender _mail;
|
||||
private readonly ILogger<RequestModel> _logger;
|
||||
|
||||
public RequestModel(IConfiguration configuration, IHttpClientFactory httpClientFactory, MailSender mail, ILogger<RequestModel> logger)
|
||||
{
|
||||
_configuration = configuration;
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_mail = mail;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void OnGet()
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnPostAsync()
|
||||
{
|
||||
//The select can be bypassed by a hand-crafted POST; only accept codes from the list
|
||||
if (!DataCenters.Any(d => d.Value == SubRequest.DataCenter))
|
||||
{
|
||||
ModelState.AddModelError("SubRequest.DataCenter", "Please choose a data center from the list.");
|
||||
}
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return Page();
|
||||
}
|
||||
|
||||
if (ContactModel.IsBlocked(SubRequest.Company))
|
||||
{
|
||||
return Redirect(EvaluateUrl);
|
||||
}
|
||||
|
||||
//1. Record the request in Sockeye. A failure here is logged and reported in the email,
|
||||
// so the trial can be set up by hand instead of the request disappearing.
|
||||
string sockeyeResult;
|
||||
bool sockeyeOk;
|
||||
try
|
||||
{
|
||||
await PostRequestToSockeyeAsync();
|
||||
sockeyeOk = true;
|
||||
sockeyeResult = "Recorded in Sockeye.";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
sockeyeOk = false;
|
||||
sockeyeResult = $"NOT RECORDED IN SOCKEYE ({ex.Message}). Set this trial up by hand.";
|
||||
_logger.LogError(ex, "Trial request post to Sockeye failed. {Body}", Describe());
|
||||
}
|
||||
|
||||
//2. Notify support. Email is in the body; From is the form account, so it was never there before either
|
||||
var body = $"{Describe()}\r\n\r\nSockeye:\r\n{sockeyeResult}";
|
||||
var subject = sockeyeOk
|
||||
? $"Trial request from {SubRequest.Company}"
|
||||
: $"Trial request NOT RECORDED from {SubRequest.Company}";
|
||||
bool mailOk;
|
||||
try
|
||||
{
|
||||
await _mail.SendToSupportAsync(subject, body, SubRequest.Name, SubRequest.Email);
|
||||
mailOk = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
mailOk = false;
|
||||
_logger.LogError(ex, "Trial request email failed. Submission:\r\n{Body}", body);
|
||||
}
|
||||
|
||||
//Either path reaching John means the request is not lost; only both failing is a failure for the visitor
|
||||
if (!sockeyeOk && !mailOk)
|
||||
{
|
||||
SendFailed = true;
|
||||
return Page();
|
||||
}
|
||||
|
||||
return Redirect(EvaluateUrl);
|
||||
}
|
||||
|
||||
private string Describe() =>
|
||||
$"Name:\r\n{SubRequest.Name}\r\n\r\nCompany:\r\n{SubRequest.Company}\r\n\r\nEmail:\r\n{SubRequest.Email}\r\n\r\nDataCenter:\r\n{SubRequest.DataCenter}";
|
||||
|
||||
private async Task PostRequestToSockeyeAsync()
|
||||
{
|
||||
//Sockeye:TrialRequestUrl. On the server this is http://127.0.0.1:7575/subscription-server-trial-request,
|
||||
//straight to Kestrel on the same host, so it depends on neither DNS nor the droplet reaching its own reserved IP.
|
||||
var url = _configuration["Sockeye:TrialRequestUrl"];
|
||||
if (string.IsNullOrWhiteSpace(url))
|
||||
{
|
||||
throw new InvalidOperationException("Sockeye:TrialRequestUrl is not configured");
|
||||
}
|
||||
|
||||
var r = new
|
||||
{
|
||||
dataCenter = SubRequest.DataCenter,
|
||||
email = SubRequest.Email,
|
||||
company = SubRequest.Company,
|
||||
name = SubRequest.Name,
|
||||
rValue = "totallylegit"
|
||||
};
|
||||
|
||||
var client = _httpClientFactory.CreateClient("sockeye");
|
||||
var response = await client.PostAsJsonAsync(url, r);
|
||||
//Previously the response was never checked, so a rejected request failed silently
|
||||
response.EnsureSuccessStatusCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user