I am using the latest Java API to set dynamic template data into my SendGrid Email Templates.
However though i am passing the values correctly ( i am able to see the sent dynamic values in the web dashboard), yet the value is not getting 'expressed' when the mail is being generated.
I tried with both HTML editor as well as Code editor , following the steps in the documentation . Java code is as below.
personalization0.addTo(new Email("ron#xxxxx", "Ron Abraham"));
personalization0.addDynamicTemplateData("otpvalue", "123456");
mail.addPersonalization(personalization0);
mail.setTemplateId("<templateid>");
HTML Code in SendGrid web editor
<span style="color: #000; font-size: 18px">OTP Value : {{ otpvalue }} </span></div>
In the web dashboard , when i check the sent mail i see otpvalue is being passed to the template.
I guess there is somethign missing in the way the value gets written into the HTML Dynamic Template . Any pointers ?
EDIT - Pasting the full method code below
#PostMapping("/sendDynamicMail")
#PreAuthorize("#oauth2.hasScope('signup')")
public Response sendDynamicMailviaSendGridApi() throws IOException{
String API_KEY = "SG.**********";
Email from = new Email("*****#*****.com");
String subject = "Test Dynamic Mail from Development team";
Email to = new Email("ron#*****.com");
Content content = new Content("text/html","Replace Body Content with Dynamic Template");
Mail mail = new Mail(from,subject,to,content);
mail.setReplyTo(from);
Personalization personalization0 = new Personalization();
personalization0.addTo(new Email("ron+1#*****", "Ron Abraham"));
personalization0.addDynamicTemplateData("otpvalue", "666666");
mail.addPersonalization(personalization0);
//design first one template
mail.setTemplateId("d-6dc6223eebfc49b7b887cac1c0f34fa2");
SendGrid sg = new SendGrid(API_KEY);
Request request = new Request();
Response response;
try {
request.setMethod(Method.POST);
request.setEndpoint("mail/send");
request.setBody(mail.build());
response = sg.api(request);
System.out.println(response.getStatusCode());
System.out.println(response.getBody());
System.out.println(response.getHeaders());
return response;
}
catch(IOException io) {
throw io;
}
finally {
//do nothing
}
}
Here is how the HTML Dynamic Template Looks . I have tried using the otp value in several places.
<div style="font-family: inherit; text-align: center"> <span style="color: #000; font-size: 18px">OTP Value1 : {{ otpvalue }} </span></div>
the issue was how the personalization data was being passed.
personalization0.addDynamicTemplateData("dynamic_template_data", "{otpvalue:454545}" );
earlier i was passing the otp value directly as as key value pair.
On analyzing the format which was being sent via curl , i made the change in java and it has worked.
Related
I'm absolutely new to the field of frontend and backend. I sent a request from React to Django using "POST" and I have extracted data from the request I can print it in the terminal, but how to show the result in web browser from Django (i.e.8000/result/) it seems to use "GET" method but it fails because my data is extracted from POST request. So basicacly, I input a text and submitted to localhost:8000/result, so I want to show the result on this url or redirect to another and send it back to React.
I don't know how to achieve this I used a pretty dumb method I save the data of request in tempory json and read the json in another function to render a browser through "GET". I tried to render or redirect to some url pages directly after process the "POST" request, but it apprently fails.
views.py
#api_view(["GET","POST"])
#class SubmitTextView(View):
def post(request):
if request.method =="POST":
#print(True)
text = request.body
#print(type(text))
result = json.loads(text)["text"]
json_data = json.dumps({"text":result})
#return HttpResponse(json_data, content_type='application/json')
#return JsonResponse({"text":result})
#context = {'result':result,'headline':'Result Searched from Wikipedia'}
#return render(request, 'my_template.html', context)
with open("sample.json", "w") as outfile:
outfile.write(json_data)
return JsonResponse({"status":"success"})
def upload(request):
with open('sample.json', 'r') as openfile:
# Reading from json file
json_object = json.load(openfile)
text = json_object["text"]
#print(text)
context = {'result':text,'headline':'Result Searched from Wikipedia'}
return render(request, 'my_template.html', context)
url.py
from django.contrib import admin
from django.urls import path,include
from app.views import *
urlpatterns = [
path('admin/', admin.site.urls),
path('new/',post,name = 'new'),
path('response/', upload, name='response'),
]
html
<h1>{{ headline }}</h1>
<div
style="border: 1px solid black; overflow: auto; max-height: 200px;">
<p>{{result}}</p>
</div>
Please help me with this... Appreciate it!!
I'm using CakePHP 3.8 to create a CMS for a website. I need a simple WYSIWYG editor with image upload. I'd previously used CKEditor, but was having problems getting the image upload working, so thought I'd try TinyMCE instead.
So, I downloaded TinyMCE 5 (with all standard plugins), linked it in in the head section of my page, and created a form with a TinyMCE textarea like this:
<fieldset>
<legend>New Page</legend>
<?php
echo $this->Flash->render();
echo $this->Form->create($newpage);
echo $this->Form->control('title');
echo $this->Form->control('content',
array('label' => 'Page Content',
'type' => 'textarea',
'id' => 'editor_area'));
echo $this->Form->button('Save');
echo $this->Form->end();
?>
</fieldset>
<script>
tinymce.init({
selector:'#editor_area',
height: 500,
menubar: false,
images_upload_url: '<?php echo IMG_UPLOAD_URL ?>',
toolbar: [
'undo redo | cut copy paste | styleselect | bold italic underline removeformat | alignleft aligncenter alignright | charmap | bullist numlist | link image'
],
plugins: ['advlist lists link autolink image charmap imagetools code']
});
</script>
This works fine, text area appears with the editor etc. The upload url in images_upload_url points to the following UploadsController.php (I've left out the details for brevity; can add them in if needed):
<?php
namespace App\Controller\Admin;
use App\Controller\AppController;
class UploadsController extends AppController
{
public function uploadImage() {
$result = array();
$result['success'] = 'success';
// Process file upload
return $this->response->withType('application/json')
->withStringBody(json_encode($result));
}
}
When I upload an image, I get the following error in the console:
Failed to load resource: the server responded with a status of 403 (Forbidden)
The output from CakePHP shows the error:
Error: CSRF token mismatch.
The debugger shows that the POST includes the following:
Cookie: CAKEPHP=dvsktjv7vp8la5nv7dv19634d1; csrfToken=53e5718e13a1e963d51f9c93c48471a478b35c02b565d6f0699cd2a335775c2b17986cfc2cc587ff7343a6573e3eb2e498a9cb962397599c023417d1dfa9506c; ckCsrfToken=7l2PEC0g06819qQcLwdX5ul7E7jNRa3r61jENt2x
I'm not sure where to go from here.
(Or if there's a more straightforward way to include a free/inexpensive WYSIWYG editor with a decent image/file uploader, I'm open to suggestions! It's a website for a school, so budget is very small and can't be a monthly cost.)
The cookie data is only one part of the CSRF protection mechanism, the client needs to send the CSRF token in either the request data or the X-CSRF-Token header too.
I'm not overly familiar with TinyMCE image uploads, but looking at the docs, you'll probably need a custom upload handler, where you can add additional data, the CSRF token that is.
Taking the example from the TinyMCE docs, the handler could look something like this, where the CSRF token is appended to the form data:
images_upload_handler: function (blobInfo, success, failure) {
var xhr, formData;
xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.open('POST', <?= json_encode(IMG_UPLOAD_URL) ?>);
xhr.onload = function() {
var json;
if (xhr.status != 200) {
failure('HTTP Error: ' + xhr.status);
return;
}
json = JSON.parse(xhr.responseText);
if (!json || typeof json.location != 'string') {
failure('Invalid JSON: ' + xhr.responseText);
return;
}
success(json.location);
};
formData = new FormData();
formData.append('file', blobInfo.blob(), blobInfo.filename());
// append CSRF token in the form data
formData.append('_csrfToken', <?= json_encode($this->request->getParam('_csrfToken')) ?>);
xhr.send(formData);
}
Also according to the docs the response JSON must contain a property named location that contains the web path to the uploaded file, that might be in the code that you've left out, mentioning it just in case.
See also
TinyMCE Docs > Introduction & getting started > Uploading images and files
TinyMCE Docs > Configuration reference > Image & file upload options > images_upload_handler
Cookbook > Security > Cross Site Request Forgery (CSRF) Middleware
I'd like to know how could I make a report downloadable from my AngularJS Application?
The report is a .xlsx I can post the data, but the response is:
What I'd like is a downloadable file, or to open the .xlsx on Excel Online in other tab as in the preview.
How could I do that?
I usually recommend to create a hidden form and do plain http submit to jsreport /api/report. This is the most stable way and works across all browsers.
<form method='POST' target='_blank' action='/api/report' id='jsrForm'>
<input hidden='true' name='template[shortid]' value="41ucBgXKe"/>
<input hidden='true' name='data[foo]' value="Hello world"/>
<input hidden='true' name='options[Content-Disposition]' value="attachment; filename=myreport.pdf"/>
</form>
<script>
document.getElementById("jsrForm").submit();
</script>
Do you have control over the response? If so, add the content-disposition header and MediaType header to the response:
For System.Net.Http.HttpResponseMessage
var response = new HttpResponseMessage{Content = ...........}
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") {
FileName = "mydoc.xlsx"
};
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
For System.Net.WebClient
var client = new WebClient();
client.Headers.Add("Content-disposition", "attachment");
client.Headers.Add("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
After reseaches and tests, I still can't show an image form ReST API on my Angular App. I have images available on my ReST web service, why do I use a ReST service? Because in order to access you need to be authenticated (I use oAuth 2 protocol). When I use POSTMan (ReST client very usefull) everything works great, the image is displayed without doing nothing. But when I try to display it with Angular after a $http it doesn't work.
Here are the headers received form the service :
Content-Length → 51756
Content-Type → image/jpeg; charset=binary
Server → Apache/2.4.9 (Win64) PHP/5.5.12
X-Powered-By → PHP/5.5.12
Here is my Angular code :
var data64 = $base64.encode(unescape(encodeURIComponent(data)));
scope.src = 'data:image/jpeg;charset=binary;base64,' + data64;
and my HTML :
<img ng-src="{{src}}" border="0" />
For information I use angular-base64 (https://github.com/ninjatronic/angular-base64) for the encodage. Without "unescape" and "encodeURIComponent" I have an error, I've tried to remove white spaces but it still doesn't work.
Thank you :)
Seems that this will not work since you tell the browser that the image data is base64 encoded, but you also transformed it with unescape and encodeURIComponent.
Why don't you fetch your image data into a binary data structure (requires a modern browser), instead of into a string:
$http.get(req, {responseType: "arraybuffer"}).
success(function(data) {
$scope.src = 'data:image/jpeg;base64,' + _arrayBufferToBase64(data);
});
_arrayBufferToBase64 is defined here.
A different approach would be to install a request interceptor, recognize the image url and add the oauth headers for this case.
I tryed this way in angular 8+ and works fine:
imageToShow: any;
createImageFromBlob(image: Blob) {
let reader = new FileReader();
reader.addEventListener("load", () => {
this.imageToShow = reader.result;
}, false);
if (image) {
reader.readAsDataURL(image);
}
}
and also call it like this:
getImageFromService() {
this.api.getImage(key).subscribe(data => {
this.createImageFromBlob(data);
}, error => {
console.log(error);
});
}
Well, I'm working on a mobile application with ionic framework. In one of my views, the user can edit your name, password and also its image. For this I am using the CordovaFileTransfer plugin and it works great for me. I'm managing to change the image and all the data I need. But not even like getting to change the data in my database, update the application. Let me explain.
When the user changes their image or their data, the web service response returns a "status 1" if achievement make the change successfully and also the URL of the image and the new name change. This we have in localStorage variables and $ rootScope within my application which update once it receives a status one from my server but to return to my dashboard application that is not updated, I close and open the application again and reflected the changes. As a way to do it, maybe my question is very basic but that works for more than one person.
JSON WEBSERVICE RESPONSE :
Object {status: 1, photo: "www.google.cl/de5a0cc049d0f3c394befb83d2cb44e3.jpg", name: "Test"}
Code controller angularjs
$cordovaFileTransfer.upload(encodeURI(server),image,ftOptions,true)
.then(function(result) {
var respuestaJSON = jQuery.parseJSON(result.response);
if(respuestaJSON.status == 1){
sessionService.set("user",respuestaJSON.name);
sessionService.set("photo", respuestaJSON.photo);
$rootScope.username = sessionService.get("user");
$rootScope.photo = sessionService.get("photo");
sessionService :
.factory('sessionService',['$http',function($http){
return {
set:function(key,value){
return localStorage.setItem(key,JSON.stringify(value));
},
get:function(key){
return JSON.parse(localStorage.getItem(key));
},
destroy:function(key){
return localStorage.removeItem(key);
},
};
}])
HTML CODE :
<div id="dashboard-header">
<center>
<div id="home-avatar" style="background-image:url('{{photo}}')"></div>
</center>
</div>