I want to change my current text email format to HTML format, so that I can send an email in nicely formatted way with headers, font values etc as shown in the screenshot below.
Image showing email body with header font size etc
Currently I have text format for sending email using AWS.ses
exports.sendEmail = function(email, token, event, context) {
var ses = new AWS.SES({
region: process.env.SES_REGION
});
var eParams = {
Destination: {
ToAddresses: [email]
},
Message: {
Body: {
Text: {
//template or environment variable
Data: `Hello ${event.request.userAttributes.given_name},\n\nYour Device Validation Token is ${token}\nSimply copy this token and paste it into the device validation input field.`
}
},
Subject: {
//template or environment variable
Data: "CWDS - CARES Device Validation Token"
}
},
//environment variable
Source: process.env.SOURCE_EMAIL
};
/* eslint-disable no-unused-vars */
ses.sendEmail(eParams, function(err, data){
if(err) {
logWrapper.logExceptOnTest("FAILURE SENDING EMAIL - Device Verify OTP");
logWrapper.logExceptOnTest(event);
logWrapper.logExceptOnTest(context);
context.fail(err);
}
else {
logWrapper.logExceptOnTest("Device Verify OTP sent");
context.succeed(event);
}
});
/* eslint-enable no-unused-vars */
}
It's fairly straight forward, just add the Html section of the Body node, i.e.:
var eParams = {
Destination: {
ToAddresses: [email]
},
Message: {
Body: {
Text: {
Data: `Hello ${event.request.userAttributes.given_name},\n\nYour Device Validation Token is ${token}\nSimply copy this token and paste it into the device validation input field.`
},
Html: {
Data: `<html><head><title>Your Token</title><style>h1{color:#f00;}</style></head><body><h1>Hello ${event.request.userAttributes.given_name},</h1><div>Your Device Validation Token is ${token}<br/>Simply copy this token and paste it into the device validation input field.</div></body></html>`
}
},
Subject: {
//template or environment variable
Data: "CWDS - CARES Device Validation Token"
}
},
//environment variable
Source: process.env.SOURCE_EMAIL
};
However... I generally split out the email template into html and text files, and use handlebars to inject data items. Here is an extract of one of my working solutions:
contact/contact.js
var AWS = require('aws-sdk');
var ses = new AWS.SES();
var fs = require('fs');
var Handlebars = require('handlebars');
module.exports.sendemail = (event, context, callback) =>
var eventData = JSON.parse(event.body);
fs.readFile("./contact/emailtemplate.html", function (err, emailHtmlTemplate) {
if (err) {
console.log("Unable to load HTML Template");
throw err;
}
fs.readFile("./contact/emailtemplate.txt", function (err, emailTextTemplate) {
if (err) {
console.log("Unable to load TEXT Template");
throw err;
}
// Prepare data for template placeholders
var emailData = {
"given_name": event.request.userAttributes.given_name,
"token": token
};
// Inject data into templates
var templateTitle = Handlebars.compile(process.env.EMAIL_TITLE);
var titleText = templateTitle(emailData);
console.log(titleText);
emailData.title = titleText;
var templateText = Handlebars.compile(emailTextTemplate.toString());
var bodyText = templateText(emailData);
console.log(bodyText);
var templateHtml = Handlebars.compile(emailHtmlTemplate.toString());
var bodyHtml = templateHtml(emailData);
console.log(bodyHtml);
// Prepare SES params
var params = {
Destination: {
ToAddresses: [
process.env.EMAIL_TO
]
},
Message: {
Body: {
Text: {
Data: bodyText,
Charset: 'UTF-8'
},
Html: {
Data: bodyHtml
},
},
Subject: {
Data: titleText,
Charset: 'UTF-8'
}
},
Source: process.env.EMAIL_FROM
}
console.log(JSON.stringify(params,null,4));
// Send Email
ses.sendEmail(params, function(err,data){
if(err) {
console.log(err,err.stack); // error
var response = {
statusCode: 500,
headers: {
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Credentials" : true
},
body: JSON.stringify({"message":"Error: Unable to Send Message"})
}
callback(null, response);
}
else {
console.log(data); // success
var response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Credentials" : true
},
body: JSON.stringify({"message":"Message Sent"})
}
callback(null, response);
}
});
}); //end of load text template
}); //end of load html template
};
contact/emailtemplate.html
<!DOCTYPE html>
<html>
<head>
<title>Your New Token</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>
h1 { color:#f00; }
</style>
</head>
<body>
<div class="emailwrapper">
<div class="main">
<div class="content">
<h1>Hi {{given_name}}</h1>
<div style="padding:20px;">
<div>your new token is {{token}}.</div>
</div>
</div>
</div>
</div>
</body>
</html>
contact/emailtemplate.txt
Hi {{given_name}}
your new token is {{token}}.
Related
When i send data from ajax to view in Django I am getting none in data. What seems to be the problem. Here is mycode. Where as if i remove processData: false, contentType: false, then data is printed successfully but on file it gives error.
Ajax code
<script>
function submit_data()
{
var type = $('#type').val();
var subtype = $('#subtype').val();
var name = $('#name').val();
var price = $('#price').val();
var weight = $('#weight').val();
var details = $('#details').val();
var picture1 = $('#image1')[0].files[0];
var picture2 = $('#image2')[0].files[0];
var picture3 = $('#image3')[0].files[0];
var vedio_url = $('#vedio_link').val();
alert(picture1)
$.ajax({
url: '/add_record/',
type: 'POST',
headers: { "X-CSRFToken": '{{csrf_token}}' },
processData: false,
contentType: false,
data: {
type,
subtype,
name,
price,
weight,
details,
picture1,
picture2,
picture3,
vedio_url,
},
success: function (response) {
alert("datauploaded successfully!")
},
error: function(){
alert('error')
}
});
}
</script>
View code
def add_record(request):
print("Yes i am here")
type = request.POST.get('type')
subtype = request.POST.get('subtype')
name = request.POST.get('name')
price = request.POST.get('price')
weight = request.POST.get('weight')
details = request.POST.get('details')
picture1 = request.FILES.get('picture1')
picture2 = request.FILES.get('picture2')
picture3 = request.FILES.get('picture3')
vedi_url = request.POST.get('vedio_url')
print (picture1)
print(type)
print(request.POST)
return JsonResponse({'message':'success'},status=200)
Error:
Yes i am here
None
None
<QueryDict: {}>
its returning none, Why is that?
Ajax without files:
Your JS data element should be a dictionary, also remove processData and contentType parameters.
<!doctype html>
<html lang="en">
<head>
</head>
<body>
<input type="text" id="name"/>
<button type="button" id="send" onclick="submit_data()">Send<button/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js" integrity="sha512-n/4gHW3atM3QqRcbCn6ewmpxcLAHGaDjpEBu4xZd47N0W2oQ+6q7oc3PXstrJYXcbNU1OHdQ1T7pAP+gi5Yu8g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
function submit_data()
{
var name = $('#name').val();
$.ajax({
url: '/add_record/',
type: 'POST',
headers: { "X-CSRFToken": '{{csrf_token}}' },
data: {
'name': name,
},
success: function (response) {
alert(response.data)
},
error: function(){
alert('error')
}
});
}
</script>
</body>
</html>
views:
from django.shortcuts import render
from django.http import JsonResponse
def form_record(request):
return render(request, "mytemplate.html", {})
def add_record(request):
print("Yes i am here")
name = request.POST.get('name')
print(f"Post: {request.POST}")
return JsonResponse({'data': name},status=200)
Ajax with files:
Because you are sending binary data you should to use FormData:
function submit_data()
{
var name = $('#name').val();
var formData = new FormData() // changes here
formData.append('name', name) // and here
$.ajax({
url: '/add_record/',
type: 'POST',
headers: { "X-CSRFToken": '{{csrf_token}}' },
contentType: false, // and here
enctype: 'multipart/form-data', // and here
processData: false, // and here
cache: false,
data: formData, // <-- carefully here
success: function (response) {
alert(response.data)
},
error: function(){
alert('error')
}
});
}
Result:
you can do with a lot of entries please because I have a more complex problem.
in my case I have 6 entries when I enter an entry I have an output in the form of a table and at the end I have to make a final request which will take into account the rows that I have selected.
Excuse my English.
my js :
function submit_data(){
list_fournisseurs = selectcheck();
list_entrepot = selectcheck1();
var numdoc = $('#numdoc').val();
var reference = $('#reference').val();
var reference_doc = $('#reference_doc').val();
var date_debut = $('#date_debut').val();
var date_fin = $('#date_fin').val();
var format_fournisseur = new FormData();
var format_entrepot = new FormData();
var format_numdoc = new FormData();
var format_reference = new FormData();
var format_reference_doc = new FormData();
var format_date_debut = new FormData();
var format_date_fin = new FormData();
const format = [
format_fournisseur.append('list_fournisseurs', list_fournisseurs),
format_entrepot.append('list_entrepot', list_entrepot),
format_numdoc .append('numdoc', numdoc),
format_reference.append('reference', reference),
format_reference_doc.append('reference_doc', reference_doc),
format_date_debut.append('date_debut', date_debut),
format_date_fin.append('date_fin', date_fin),
]
$.ajax({
type : 'POST',
url : 'fournisseur_ajax',
data : {
'csrfmiddlewaretoken': csrf,
'format' : format,
},
//processData: false,
success : (res) =>{
console.log('res.data',res.data)
},
error : (err) =>{
console.log(err)
},
})
}
my view
if request.method == "POST" :
check_list_fournisseurs = request.POST.getlist("format_fournisseur[]")
print("########## voici la liste ###########",check_list_fournisseurs)
check_list_entrepot = request.POST.getlist("format_entrepot[]")
print("########## voici la liste ###########",check_list_entrepot)
print("numdoc ",num_doc)
print("item_ref",item_ref)
print("item_doc",item_doc)
print("date_depart", date_debut)
print("date_fin",date_fin)
context ={'check_list_entrepot':check_list_entrepot,"check_list_fournisseurs":check_list_fournisseurs, 'num_doc':num_doc, 'item_ref':item_ref, 'item_doc':item_doc, 'date_debut':date_debut, 'date_fin':date_fin}
return render(request,"final.html",context)
I'm tyring to get a list of all the site collections that users have permissions to access. My plan is to display these on the home page, to make it easy for them to navigate to each of their sites. I've tried the following code, but nothing form my API call is writing the the console. It's just blank. What am I missing with writing to the console? Is the name siteURL wrong?
'''
$.ajax({
url: "/_api/search/query?querytext='contentclass:sts_site'",
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
var results = data.d.results;
var itemhtml = "";
$.each(results, function (index, dataRec) {
console.log(siteUrl);
});
},
error: function (data) {
(data);
}
})
'''
Here is a code snippet to get all site collection and print using Console.log:
<script src="https://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
<script type="text/javascript">
$( document ).ready(function() {
//print sites info
searchSites(_spPageContextInfo.webAbsoluteUrl,
function(query){
var resultsCount = query.PrimaryQueryResult.RelevantResults.RowCount;
for(var i = 0; i < resultsCount;i++) {
var row = query.PrimaryQueryResult.RelevantResults.Table.Rows.results[i];
var siteUrl = row.Cells.results[6].Value;
console.log(JSON.stringify(siteUrl));
}
},
function(error){
console.log(JSON.stringify(error));
}
);
});
function searchSites(webUrl,success, failure) {
var url = webUrl + "/_api/search/query?querytext='contentclass:sts_site'";
$.ajax({
url: url,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
success(data.d.query);
},
error: function (data) {
failure(data);
}
});
}
</script>
Reference:
What is the REST endpoint URL to get list of site collections?
WHEN I FILL THE FORM IN HTML,I FACE ERROR OF 500. MY WEBSERVICE IS NOT WORKING. WHEN I COPYPASTE URL AND OPEN IN NEW TABLE THEN IT SHOWS BELOW ERROR.
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)]
public void addNewUser(string name,string address,string email, string phoneno, string pin)
{
JavaScriptSerializer ser = new JavaScriptSerializer();
string Message = "";
try
{
using (MySqlConnection connection = new MySqlConnection(DBconnect.ConnectionString))
{
MySqlCommand cmd = new MySqlCommand("INSERT INTO users(name,address,email,phoneno,pin) VALUES(#name,#address,#email,#phoneno,#pin)", connection);
cmd.Parameters.AddWithValue("#name", name);
cmd.Parameters.AddWithValue("#address", address);
cmd.Parameters.AddWithValue("#email", email);
cmd.Parameters.AddWithValue("#phoneno", phoneno);
cmd.Parameters.AddWithValue("#pin", pin);
connection.Open();
cmd.ExecuteNonQuery();
connection.Close();
}
Message = "New User is added Successfully.";
}
catch (Exception ex)
{
Message = "Not Added";
}
var JSonData = new
{
Message = Message
};
HttpContext.Current.Response.Write(ser.Serialize(JSonData));
}
<script type="text/javascript">
$(document).ready(function () {
$("#btnAdduser").on('click', function (e)
{
e.preventDefault();
var All_users = {};
All_users.name = $('#name').val();
All_users.address = $('#address').val();
All_users.email = $('#email').val();
All_users.phoneno = $('#phoneno').val();
All_users.pin = $('#pin').val();
var jsonData = JSON.stringify({
All_users: All_users
});
$.ajax({
type: "POST",
url: "http://localhost/WebApi/WebService.asmx?op=addNewUser",
data: jsonData,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
error: OnErrorCall
});
function OnSuccess(response) {
var result = response.d;
if (result == "success") {
$("#msg").html("New record addded successfully :)").css("color", "green");
}
$("#name").val("");
$("#address").val("");
$("#email").val("");
$("#phoneno").val("");
$("#pin").val("");
}
function OnErrorCall(response) {
$("#msg").html("Error occurs :(").css("color", "red");
}
});
});
</script>
*
System.InvalidOperationException: Missing parameter: name. at
System.Web.Services.Protocols.ValueCollectionParameterReader.Read(NameValueCollection
collection) at
System.Web.Services.Protocols.HttpServerProtocol.ReadParameters()
at
System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()
*
I tried reproducing your case.
The problem is UseHttpGet = true, change to UseHttpGet = false and also check that attribute in class [System.Web.Script.Services.ScriptService]
and update your AJAX call by WebService.asmx/addNewUser like this, it worked
<script
src="https://code.jquery.com/jquery-3.3.1.js"
integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
crossorigin="anonymous"></script>
<button id="btnAdduser">Test</button>
<script type="text/javascript">
$(document).ready(function () {
$("#btnAdduser").on('click', function (e)
{
e.preventDefault();
var All_users = {};
All_users.name = "Hien";
All_users.address = "Test";
All_users.email = "Test";
All_users.phoneno = "Test";
All_users.pin = "123";
var jsonData = JSON.stringify({
data: All_users
});
$.ajax({
type: "POST",
url:
"http://localhost/WebApi/WebService.asmx/addNewUser",
data: JSON.stringify(All_users),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
error: OnErrorCall
});
function OnSuccess(response) {
var result = response.d;
if (result == "success") {
$("#msg").html("New record addded successfully :)").css("color", "green");
}
$("#name").val("");
$("#address").val("");
$("#email").val("");
$("#phoneno").val("");
$("#pin").val("");
}
function OnErrorCall(response) {
$("#msg").html("Error occurs :(").css("color", "red");
}
});
});
</script>
I want to use the AWS S3 JS SDK to upload multiple files from a browser. I can get one file just fine, but can't get multiple. When I select mulitple files, the last file is the only one to get uploaded. Here's the code:
//head
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.213.1.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
//body
<input type="file" id="file-chooser" multiple />
<button id="upload-button">Upload to S3</button>
<div id="results"></div>
<script type="text/javascript">
AWS.config.region = 'us-east-1';
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: '###'
});
AWS.config.credentials.get(function(err) {
if (err) alert(err);
console.log(AWS.config.credentials);
});
var bucketName = 'c2networkingfiles'; // Enter your bucket name
var bucket = new AWS.S3({
params: {
Bucket: bucketName
}
});
var fileChooser = document.getElementById('file-chooser');
var button = document.getElementById('upload-button');
var results = document.getElementById('results');
button.addEventListener('click', function() {
var fileArr = fileChooser.files;
if (fileArr[0]) {
for (k=0; k<fileArr.length; k++) {
var file = fileArr[k];
var fileName = file.name;
// test to see if file already exists
var objKey2 = 'testing/' + file.name;
var objE = new AWS.S3();
var params2 = {
Bucket: bucketName,
Key: objKey2
};
objE.headObject(params2, function(err, data) {
if (data) {
results.innerHTML = 'File is present. Uploaded on ' + data.LastModified;
//console.log(data);
} else {
//results.innerHTML = '';
var objKey = 'testing/' + file.name;
var params = {
Key: objKey,
ContentType: file.type,
Body: file,
ACL: 'public-read'
};
bucket.putObject(params, function(err, data) {
if (err) {
results.innerHTML = 'ERROR: ' + err;
} else {
//listObjs();
results.append('SUCCESS! ' + fileName + ' uploaded. <br />');
}
});
}
});
}
} else {
results.append('Nothing to upload.');
}
}, false);
</script>
The original code example didn't have the loop and I'm wondering if this isn't working right because there isn't a mechanism to wait until the first file has finished before the loop starts the next upload.
If this is the answer, is there a way to check the upload status and wait until the first file is complete before the loop is allowed to continue?
If this isn't the answer, what else could be happening?
In Sharepoint 2013, is it possible to drag and drop a file (.jpg , .pdf, .png) to a custom list as an attachment? If so, can this be achieved by using a script (JS, jquery)? So, if a user is reporting a bug (NewForm.aspx), and he has a screenshot of the error message saved as a .jpg, I would want him to be able to drop this file into a drop zone on the form.
Can this scenario work - I would be very grateful for your suggestions?
Here is my tested code.
<style type="text/css">
.droppable {
background: #08c;
color: #fff;
padding: 100px 0;
text-align: center;
}
.droppable.dragover {
background: #00CC71;
}
</style>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script type="text/javascript">
function makeDroppable(element, callback) {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('id', 'dragdropContent');
input.setAttribute('multiple', true);
input.style.display = 'none';
input.addEventListener('change', triggerCallback);
element.appendChild(input);
element.addEventListener('dragover', function (e) {
e.preventDefault();
e.stopPropagation();
element.classList.add('dragover');
});
element.addEventListener('dragleave', function (e) {
e.preventDefault();
e.stopPropagation();
element.classList.remove('dragover');
});
element.addEventListener('drop', function (e) {
e.preventDefault();
e.stopPropagation();
element.classList.remove('dragover');
triggerCallback(e);
});
element.addEventListener('click', function () {
input.value = null;
input.click();
});
function triggerCallback(e) {
var files;
if (e.dataTransfer) {
files = e.dataTransfer.files;
} else if (e.target) {
files = e.target.files;
}
callback.call(null, files);
}
}
$(function () {
String.prototype.format = function () {
var args = [].slice.call(arguments);
return this.replace(/(\{\d+\})/g, function (a) {
return args[+(a.substr(1, a.length - 2)) || 0];
});
};
var element = document.querySelector('.droppable');
function callback(files) {
// Here, we simply log the Array of files to the console.
//console.log(files);
var fileName = files[0].name;
// Construct the endpoint. mydoc is document library name
var reader = new FileReader();
reader.file = files[0];
reader.onload = function (event) {
var arrayBuffer = event.target.result;
//var fileData = '';
//var byteArray = new Uint8Array(arrayBuffer);
//for (var i = 0; i < byteArray.byteLength; i++) {
// fileData += String.fromCharCode(byteArray[i]);
//}
var fileEndpoint = String.format(
"{0}/_api/web/lists/getByTitle('{1}')/RootFolder/files" +
"/add(overwrite=true, url='{2}')",
_spPageContextInfo.webAbsoluteUrl, 'mydoc', fileName);
//Add the file to the SharePoint folder.
$.ajax({
url: fileEndpoint,
type: "POST",
data: arrayBuffer,//fileData,
processData: false,
headers: {
"X-RequestDigest": jQuery("#__REQUESTDIGEST").val(),
"accept": "application/json;odata=verbose",
"content-length": arrayBuffer.byteLength,
//"IF-MATCH": itemMetadata.etag,
//"X-HTTP-Method": "MERGE"
},
success: function (data, b, c) {
alert('File upload succeeded.');
},
error: function (a, b, err) {
alert('Error: ' + err.responseText);
}
})
};
reader.onerror = function (e) {
alert(e.target.error);
}
var arrayBuffer = reader.readAsArrayBuffer(files[0]);
}
makeDroppable(element, callback);
})
</script>
<div class="droppable">
<p>Drag files here or click to upload</p>
</div>
Update:
This is the control in my test sample:
You could try to debug is any JS error in your page.