sending mail with image using sendgrid - javascript

"code for sending email above is the code .iam tired of scratching my head but still not able to see the image in the mail. I am converting the image into base 64 encoded string and also following the sendgrid syntax still not able to send the image .i dunno wats going wrong here.:"
var app = require("../../../server/server");
var base64Img = require("base64-img");
let status = null;
let textBody,
htmBody = null;
var DataSource = require("loopback-datasource-juggler").DataSource;
var dsSendGrid = new DataSource("loopback-connector-sendgrid", {
api_key: app.customConfig.mail.sendgrid.api_key
});
var fs = require("fs");
function base64_encode(file) {
var bitmap = fs.readFileSync(file);
return new Buffer(bitmap).toString("base64");
}
function base64_decode(base64str, file) {
var bitmap = new Buffer(base64str, "base64");
fs.writeFileSync(file, bitmap);
console.log(
"******** File created from base64 encoded string ********",
base64str
);
}
var base64str = base64_encode("../../../images/Campaign-images/Christmas.png");
let message = {
to: "somebody#gmail.com",
from: "noreply#gmail.com",
subject: "test",
text: "hi",
html: '<img src="cid:myimagecid"/>',
attachment: [
{
filename: "Christmas2.png",
content: base64str,
ContentId: "myimagecid"
}
]
};
console.log(message);
app.models.Email.send(message)
.then(result => {
return "sent";
})
.catch(err => {
console.log(err);
return "failed";
});

This code will work for sure
//imageData= "data:image/png;base64,ine793nfdsf......."
imageb64 = imageData.replace('data:image/png;base64,' , '');
//remove data:image/png;base64,
const msg = {
to: 'example#gmail.com',
from: 'test#gmail.com',
subject: "image attached",
html :'<img src="cid:myimagecid"/>',
attachments: [
{
filename: "imageattachment.png",
content: imageb64,
content_id: "myimagecid",
}
]
};
sgMail.send(msg);

If I look to the https://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/index.html
I see it is attachments not attachment
Also there is content_id instead of ContentId
Also make sure, you are using right version (I am pointing to v3 but I think you can choose to use v2)

May be it is because of your mail client doesn't support for base 64 encoded images see this question

Related

How to login to wikipedia using mediawiki API through?

I already have two working bots in Wikipedia, but they use different method.
Currently, I am trying to create a bot using C#. On the API documentation page, they have provided some sample codes in java, PHP, and python. But unfortunately, they haven't provided any sample code in C#. It is the only language I am familiar with.
This is the Wikimedia API:Edit documentation page. Would someone kindly convert the few words from java (or any other language) to C#?
If I could get only this code converted to C#, I can build the rest of the bot by myself.
I asked help on the relevant noticeboard(s) on the wikimedia site(s), but nobody there is familiar with C#. That's why I am now asking this outside of wikipedia.
Thanks a lot in advance
This is the java source-code:
```
/*
edit.js
MediaWiki API Demos
Demo of `Login` module: Sending post request to login
MIT license
*/
var request = require( 'request' ).defaults( { jar: true } ),
url = 'https://test.wikipedia.org/w/api.php';
// Step 1: GET request to fetch login token
function getLoginToken() {
var params = {
action: 'query',
meta: 'tokens',
type: 'login',
format: 'json'
};
request.get( { url: url, qs: params }, function ( error, res, body ) {
var data;
if ( error ) {
return;
}
data = JSON.parse( body );
loginRequest( data.query.tokens.logintoken );
} );
}
// Step 2: POST request to log in.
// Use of main account for login is not
// supported. Obtain credentials via Special:BotPasswords
// (https://www.mediawiki.org/wiki/Special:BotPasswords) for lgname & lgpassword
function loginRequest( loginToken ) {
var params = {
action: 'login',
lgname: 'bot_username',
lgpassword: 'bot_password',
lgtoken: loginToken,
format: 'json'
};
request.post( { url: url, form: params }, function ( error, res, body ) {
if ( error ) {
return;
}
console.log( body );
} );
}
// Start From Step 1
getLoginToken();
I can't go so deeply but I hope you can take a look at this page and find out how to do it
https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=net-6.0
You can try something like this
private static async Task LoginRequest(string loginToken)
{
var data = new
{
action = "login",
lgname = "bot_username",
lgpassword = "bot_password",
lgtoken = loginToken,
format = "json"
};
using (var client = new HttpClient())
using (var response = await client.PostAsJsonAsync(LOGIN_URL, data))
{
var responseString = await response.Content.ReadAsStringAsync();
var responseObject = JsonConvert.DeserializeObject<JObject>(responseString);
Console.WriteLine(responseObject);
}
}
private static async Task<string?> GetLoginToken()
{
var url = $"{LOGIN_URL}?action=query&meta=tokens&type=login&format=json";
using (var client = new HttpClient())
using (var response = await client.GetAsync(url))
{
var responseString = await response.Content.ReadAsStringAsync();
var responseObject = JsonConvert.DeserializeObject<JObject>(responseString);
return responseObject?["query"]?["tokens"]?["logintoken"]?.ToString();
}
}
For converting the response you need
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
You can call these methods from your Main method like this:
const string LOGIN_URL = "https://test.wikipedia.org/w/api.php";
public static async Task Main()
{
var loginToken = await GetLoginToken();
await LoginRequest(loginToken ?? throw new Exception("No login token."));
}

React | Facebook JS API : Error code 100 when trying to upload multiple images to my page feed

In a first function, I upload multiple images to page-id/photos and receive a positive response with all the ids of these images.
The next part however is where I'm stuck; I am now trying to create a post with multiple images to my Facebook page timeline. However, I'm getting a weird error response claiming that I already have uploaded my images.
I've even followed Facebook's own example from their documentation using Open Graph Explorer, but that just returns another error
Function to send image:
(works without a problem)
sendFacebookImagePost(page) {
const attached_media = []
for(let i = 0; i < this.state.upload_imgsrc.length; i++) {
let reader = new FileReader();
reader.onload = (e) => {
let arrayBuffer = e.target.result;
let blob = new Blob([arrayBuffer], { type: this.state.upload_imgsrc[i].type });
let data = new FormData()
data.append("source", blob)
data.append("message", this.state.fb_message)
data.append("no_story", true)
data.append("published", true)
axios({
method: "post",
url: "https://graph.facebook.com/" + page.id + "/photos?access_token=" + page.accessToken,
data: data
})
.then(response => {
attached_media.push({media_fbid: response.data.id})
if (attached_media.length === this.state.upload_imgsrc.length) {
this.sendFacebookPost(page, attached_media)
}
})
.catch(error => {
console.log(error);
})
}
reader.readAsArrayBuffer(this.state.upload_imgsrc[i]);
}
}
Function to send post:
(Here is where the error happens)
sendFacebookPost(page, attached_media) {
let data = {
message: this.state.fb_message,
link: this.state.fb_link,
attached_media: attached_media
// this is what attached_media returns:
// [
// {media_fbid: response.data.id},
// {media_fbid: response.data.id}
// ]
}
axios({
method: "post",
url: "https://graph.facebook.com/" + page.id + "/feed?access_token=" + page.accessToken,
data: data
})
.then( () => this.setState({fb_successMessage: "Post successful!", fb_errorMessage: ""}) )
.catch(error => {
console.log(error);
})
}
Error code
error: {
code: 100
error_subcode: 1366051
error_user_msg: "These photos were already posted."
error_user_title: "Already Posted"
fbtrace_id: "Cl9TUTntOZK"
is_transient: false
message: "Invalid parameter"
type: "OAuthException"
}
My try on Open Graph Explorer
Problem solved.
The part that went wrong is where I add the following to my image post:
data.append("published", true). Apparently, images you want to use in a multi photo post have to be set to published: false before they can be used in a post. Otherwise, Facebook sees this as already uploaded.

Google drive API - ulpoad an audio blob converted in base64 string- drive.files.create method - File id not found

I'm trying to sent an audio blob on some Google drive folder. To succeed I translate blob in file before sending it.
I received since the starting an error :
Error: File not found.
code: 404, errors: [ { domain: 'global',
reason: 'notFound',
message: 'File not found: 1aazd544z3FOCAsdOA5E7XcOaS3297sU.',
locationType: 'parameter',
location: 'fileId' } ] }
progressive edit : So far I have converted my audio blob in base64 string in order to ease the processing of my blob.
But, I fail always to write a file with my base 64 audio blob :
Here my driveApi.js :
// request data from req.body
var data = req.body.data ; // data variable is presented in form of base64 string
var name = req.body.word ;
(...)
// WRITE FILE AND STORE IT IN BODY HEADER PROPERTY
body: fs.writeFile((name + ".mp3"), data.substr(data.indexOf(',')+1), {encoding: 'base64'}, function(err) {
console.log('File created')
})
Three steps: create a temporary file with your base64 data out of the drive.files.create function, then give this file a specific name -e.g. tempFile, also you can customize this name with a time value. After that, pass this file on a "fs.createReadStream" method to upload it on Google drive.
Some hints:
Firstly - use path.join(__dirname, name + "-" + Date.now() +".ext" ) to create to file name
Secondly - make this process asynchronously to avoid data flow conflict (trying to create file before file is created), so call the drive.files.create after having setting a fs.writeFile function.
Thirdly - Destroy the tempFile after the operation has been done. It allows you to automatize the process.
I let you dive in the methods you need. But basically fs should do the job.
Again, be careful on the data flow and use callback to control it. Your code can crash just because the function gone up in a no-operational way.
Some links :
https://nodejs.org/api/path.html
https://nodejs.org/api/fs.html#fs_fs_writefile_file_data_options_callback
here an instance :
// datavalue = some time value
fs.writeFile(
path.join(__dirname, name + "-" + datevalues +".mp3" ),
data.substr(data.indexOf(',')+1),
{encoding: 'base64'},
// callback
function(err) {
if(err){ console.log("error writting file : " + err)}
console.log('File created')
console.log("WRITTING") // control data flow
fileCreate(name)
})
function fileCreate (name){
// upload file in specific folder
var folderId = "someID";
var fileMetadata = {
'name': name + ".mp3" ,
parents: [folderId]
}; console.log("MEDIA") // control data flow
var media = {
mimeType: 'audio/mp3',
body: fs.createReadStream(path.join(__dirname, name + "-" + datevalues +".mp3" ))
};
drive.files.create({
auth: jwToken,
resource: fileMetadata,
media: media,
fields: 'id'
}, function (err, file) {
if (err) {
// Handle error
console.error(err);
} else {
console.log('File Id: ', file.data.id);
}
// make a callback to a deleteFile() function // I let you search for it
});
}
How about this modification? I'm not sure the condition of blob from reactApp.js. So could you please try to use this modification? In this modification, file or blob from reactApp.js are used.
Modified script :
var stream = require('stream'); // Added
module.exports.uploadFile = function(req){
var file ;
console.log("driveApi upload reached")
function blobToFile(req){
file = req.body.blob
//A Blob() is almost a File() - it's just missing the two properties below which we will add
file.lastModifiedDate = new Date();
file.name = req.body.word;
return file;
}
var bufStream = new stream.PassThrough(); // Added
bufStream.end(file); // Or bufStream.end(### blob from reactApp.js ###) Added
console.log(typeof 42);
// upload file in specific folder
var folderId = "1aa1DD993FOCADXUDNJKLfzfXcOaS3297sU";
var fileMetadata = {
"name": req.body.word,
parents: [folderId]
}
var media = {
mimeType: "audio/mp3",
body: bufStream // Modified
}
drive.files.create({
auth: jwToken,
resource: fileMetadata,
media: media,
fields: "id"
}, function (err, file) {
if (err) {
// Handle error
console.error(err);
} else {
console.log("File Id: ", file.id);
}
console.log("driveApi upload accomplished")
});
}
If this didn't work, I'm sorry.

Uploading file to PouchDB/CouchDB

I'm building a mobile app with Cordova. I am using PouchDB for local storage so the app works without internet. PouchDB syncs with a CouchDB server so you can access your data everywere.
Now, i've got to the point where I need to add a function to upload (multiple) files to a document. (files like .png .jpg .mp3 .mp4 all the possible file types).
My original code without the file upload:
locallp = new PouchDB('hbdblplocal-'+loggedHex);
function addItem() {
//get info
var itemTitle = document.getElementById('itemTitle').value;
var itemDesc = document.getElementById('itemDesc').value;
var itemDate = document.getElementById('itemDate').value;
var itemTime = document.getElementById('itemTime').value;
//get correct database
console.log(loggedHex);
console.log(loggedInUsername);
//add item to database
var additem = {
_id: new Date().toISOString(),
title: itemTitle,
description: itemDesc,
date: itemDate,
time: itemTime
};
locallp.put(additem).then(function (result){
console.log("Added to the database");
location.href = "listfunction.html";
}).catch(function (err){
console.log("someting bad happened!");
console.log(err);
});
}
I'll add a link to a JSfiddle where I show my attempt to add the file upload. i've also included the html part.
link to jsfiddle: click here
I've noticed an error in the console about there not being a content-type.
Is there someone who can help me?
I think you're not setting the content_type of your attachment right. Try changing type to content_type like so:
var additem = {
_id: new Date().toISOString(),
title: itemTitle,
description: itemDesc,
date: itemDate,
time: itemTime,
_attachments: {
"file": {
content_type: getFile.type,
data: getFile
}
}
};
Also see the docs for working with attachments.

Written File from Node Scrape Incorrect

I am trying to pull the name, address, and url from the madeinnyc tech map for a personal project in learning how to use mapbox. In the process I wanted to scrape the listings and export them in a json file that I could use for the project. The issue I am running into is that the information is not being correctly written to the json file. When I log the scrapped data in the console, I am receiving the correct format and all of the data, but the written file from the scrapped data is incorrect and only received one random piece of data. I think the current setup is scraping individual pieces and overwriting it multiple times, because I am getting multiple File Success logs in my console. Is my writeFile method incorrect?
Here is the info logged to the console console.log(metadata) (correct data, condensed since you get the idea of the rest of the listings):
{ name: 'Todayships',
address: '4447 Seton Ave 2',
url: 'http://todayships.com/' }
{ name: 'Togather',
address: '45 Main St Suite 404',
url: 'http://www.togather.com' }
{ name: 'Tomorrow Networks, LLC',
address: '1270 Avenue of the Americas 2920',
url: 'http://www.tomorrownetworks.com' }
{ name: 'Topi',
address: '20 W 20 Street 2nd Floor',
url: 'http://topi.com' }
output.json
{
"name": "Berlinica Publishing LLC",
"address": "255 West 43rd Street Suite 1012",
"url": "http://www.berlinica.com"
}s.com"
}ackground.html"
}drianyc.com/ersp.html"
}
scrape.js
var request = require('request');
var cheerio = require('cheerio');
var fs = require('fs');
request('http://mappedinny.com/', function (error, response, html) {
if (!error && response.statusCode == 200) {
var $ = cheerio.load(html);
$('li').each(function(i, element){
var li = $(this)
var name = li.attr('data-name');
var address = li.attr('data-address');
var url = li.attr('data-url');
var metadata = {
name : name,
address : address,
url : url
};
console.log(metadata);
fs.writeFile('output.json', JSON.stringify(metadata, null, 4), function(err){
console.log('File Success');
});
});
}
});
The problem is that you're asynchronously writing to the same file in a synchronous loop (your each()).
If your intention is to write all results to the same file, you might try:
var results = [];
$('li').each(function(i, element){
var li = $(this)
var name = li.attr('data-name');
var address = li.attr('data-address');
var url = li.attr('data-url');
var metadata = {
name : name,
address : address,
url : url
};
console.log(metadata);
results.push(metadata);
});
fs.writeFile('output.json', JSON.stringify(results, null, 4), function(err){
if (err)
console.log('File Error: ' + err);
else
console.log('File Success');
});

Categories

Resources