cannot have a variable as phpmailer to address - phpmailer

I'm trying to use phpmailer to send emails to addresses stored in the variable $to like this
$mail->AddAddress($to);
but I keep getting an error message saying this
You must provide at least one recipient email address.
I have tried printing $to and it prints out the correct email address where I want the message to be sent. The mail gets sent if I put in an email address (e.g. test1#gmail.com) instead of $to. Could anyone help? Thanks!
This is the context:
// if the email seller form is submitted
if ($_SERVER["REQUEST_METHOD"] == "POST")
{
// retreive the seller's email using his id
$seller_id = $_GET["sellerid"];
// query for the seller's email
$user_query = query("SELECT username FROM users WHERE id = ?", $seller_id);
$to = $user_query[0]["username"];
// send an email to the seller
require_once("PHPMailer/class.phpmailer.php");
// instantiate mailer
$mail = new PHPMailer();
// use your ISP's SMTP server
$mail->IsSMTP();
$mail->Host = "smtp.fas.harvard.edu";
// set From:
$mail->SetFrom($_POST['buyer_email']);
// set To:
$mail->AddAddress($to);
// set Subject:
$mail->Subject = $_POST['subject'];
// set body
$mail->Body = $_POST['message'];
// set alternative body, in case user's mail client doesn't support HTML
$mail->AltBody = "Please view this message in an HTML-enabled browser.";
// send mail
if ($mail->Send() === false)
die($mail->ErrorInfo . "\n");
This is the query function
/**
* Executes SQL statement, possibly with parameters, returning
* an array of all rows in result set or false on (non-fatal) error.
*/
function query(/* $sql [, ... ] */)
{
// SQL statement
$sql = func_get_arg(0);
// parameters, if any
$parameters = array_slice(func_get_args(), 1);
// try to connect to database
static $handle;
if (!isset($handle))
{
try
{
// connect to database
$handle = new PDO("mysql:dbname=" . DATABASE . ";host=" . SERVER, USERNAME, PASSWORD);
// ensure that PDO::prepare returns false when passed invalid SQL
$handle->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
catch (Exception $e)
{
// trigger (big, orange) error
trigger_error($e->getMessage(), E_USER_ERROR);
exit;
}
}
// prepare SQL statement
$statement = $handle->prepare($sql);
if ($statement === false)
{
// trigger (big, orange) error
trigger_error($handle->errorInfo()[2], E_USER_ERROR);
exit;
}
// execute SQL statement
$results = $statement->execute($parameters);
// return result set's rows, if any
if ($results !== false)
{
return $statement->fetchAll(PDO::FETCH_ASSOC);
}
else
{
return false;
}
}

Your problem is...
// if the email seller form is submitted
if ($_SERVER["REQUEST_METHOD"] == "POST") //<-- POST HERE
{
// retreive the seller's email using his id
$seller_id = $_GET["sellerid"]; //<-- GET HERE

Related

how to send a mail in a particular format by using send grid

I am able to send a mail by using send grid API how to send a mail in particular format by using send grid
Mail-Format
please find the Mail-format image
Pass in the body as HTML and set the IsBodyHtml = true. I do this using SendGrid.
public Task SendEmailAsync(string email, string subject, string htmlMessage)
{
var client = new SmtpClient(host, port)
{
Credentials = new NetworkCredential(userName, password),
EnableSsl = false
};
return client.SendMailAsync(
new MailMessage(from, email, subject, htmlMessage) { IsBodyHtml = true }
);
}

How to get email of user who send message to bot in Circuit JavaScript SDK?

I'm creating a bot that will receive a messages in Circuit and then send it somewhere else with email of user that printed this message.
As example I use xlator-bot https://github.com/circuit/xlator-bot
this.receiveItem = function receiveItem(item) {
logger.info('[APP]: receiveItem');
if (item.type !== 'TEXT' || self.sentByMe(item)) {
logger.debug('[APP]: skip it is not text or I sent it');
return;
}
if (!item.text || !item.text.content) {
logger.info('[APP]: skip it does not have text');
return;
}
self.receiveText(htmlToText.fromString(item.text.content))
.then (function addResponseItem(responseItem){
logger.info('[APP]: addResponseItem');
var comment = {
convId: item.convId,
parentId: (item.parentItemId) ? item.parentItemId : item.itemId,
content: responseItem
};
return client.addTextItem(item.convId, comment);
})
.catch(function(e){
logger.error('[APP]:', e);
});
};
I want to get email of user who send item in this function as string variable. Can anyone suggest how can I do it?
The item has an attribute creatorId which is the userId of the sender. The API getUserById will return the user object that contains the emailAddress attribute.
See
https://circuitsandbox.net/sdk/classes/Item.html#property_creatorId and https://circuitsandbox.net/sdk/classes/Client.html#method_getUserById and
https://circuitsandbox.net/sdk/classes/User.html#property_emailAddress

AddStringAttachment giving unusual results

I am sending attachments (CSV) which I have been sending for years using mail() but decided to migrate to SMTP for better reliability.
Code 1 (CSV attachment)
$attachment = $this->CSVData; // "Date","Name","Dept" ... \n"2019-03-13","Dave" ...
$encoding = 'base64';
$contentType = 'text/csv';
$filename = $this->createFileName(); //Get FileDate and Name
$recipient = $delivery_email; // xxxxxxx#gmail.com
$subject = $this->emailHeader['subject'] . " CSV Data";
$message = 'Daily Data File';
$mail = new PHPMailer\PHPMailer\PHPMailer(true); // Passing `true` enables exceptions
try {
//Server settings
$mail->SMTPDebug = 0; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = SMTP_HOST; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = SMTP_USER; // SMTP username
$mail->Password = SMTP_PASS; // SMTP password
$mail->SMTPSecure = SMTP_AUTH; // Enable TLS encryption, `ssl` also accepted
$mail->Port = SMTP_PORT; // TCP port to connect to
//Recipients
$mail->setFrom($this->fromEmail, $this->fromEmailName); // Add a FROM
$addresses = explode(',', $recipient);
foreach ($addresses as $address) {
$mail->AddAddress(trim($address)); // Add a recipient(s)
}
if ( !empty($this->emailCC) ) $mail->addCC($this->emailCC); // Add a CC
//13-03-2019: Add the attachment to the email
$mail->AddStringAttachment($attachment, $filename, $encoding, $contentType);
//Content
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $subject;
$mail->Body = $message;
$mail->AltBody = 'This email is formatted in HTML';
$mail->send();
$this->fo->printStatus('Email successfully sent to: '. $recipient );
return true;
} catch (Exception $e) {
$this->fo->printStatus( basename(__FILE__) .' '. __LINE__ . ': Message could not be sent. Mailer Error: '. $mail->ErrorInfo );
return false;
}
The email gets delivered to me BUT ...
Problems:
When viewing in Gmail browser - I get message: "
Gmail virus scanners are temporarily unavailable – The attached files haven't been scanned for viruses. Download these files at your own risk."
When viewing in Gmail browser - I cant save/download the file? (clicking the download button does nothing)
When clicking attachment to view in browser, I now get error: "Whoops. There was a problem while previewing this document"
I try "Show Original" and it takes 30+ seconds for the email to load which just shows the base64 encoded data
I tried to open in inbox in Outlook and after 5 minutes of the emails not loading I gave up (thinking the emails are not encoded properly or something causing outlook to get stuck)
It looks like it is working (i.e. the file looks legit based on the gmail icon preview) but I cant do anything else with it and I don't know if it is a Gmail issue or File Issue.
Any advice?
Turns out that Gmail was having issues all yesterday afternoon with attachments. It was a Gmail issue - The timing is unbelievable
https://www.theguardian.com/technology/2019/mar/13/googles-gmail-and-drive-suffer-global-outages

Prefill docusign template fields

Using the Docusign node.js sample I'm able to send a template, however I'm having trouble pre-setting the field values.
I've looked around on stack overflow and found 3 different versions of the setTemplateRoles JSON format. I've tried them all and none worked.
When I run this code, the email comes to foo#email.com and my template comes through fine, but the fields are not pre-filled.
Q1. When they say tab what are they talking about? What is a tab?
Q2. Does tabLabel mean Data Label, or are they different things?
Screenshot:
when editing the template in the GUI.
Q3. How can I add a "custom field" to my docusign template? I've tried to do it by clicking Custom Fields, and adding one. But it seems to be more of a field template than a specific custom field.
When I run the API call listCustomFields, it comes back empty.
var docusign = require('docusign-esign');
// Note: Following values are class members for readability and easy testing
// TODO: Enter your DocuSign credentials
var UserName = 'foo#email.com';
var Password = 'SECRET1';
// TODO: Enter your Integrator Key (aka API key), created through your developer sandbox preferences
var IntegratorKey = 'SECRET2';
// for production environment update to 'www.docusign.net/restapi'
var BaseUrl = 'https://demo.docusign.net/restapi';
var RequestSignatureFromTemplate = function () {
// TODO: Enter signer information and template info from a template in your account
var signerName = 'Bob';
var signerEmail = 'foo#email.com';
var subject = "testing 123";
var templateId = 'XXX';
var templateRoleName = 'Seller';
// initialize the api client
var apiClient = new docusign.ApiClient();
apiClient.setBasePath(BaseUrl);
// create JSON formatted auth header
var creds = '{"Username":"' + UserName + '","Password":"' + Password + '","IntegratorKey":"' + IntegratorKey + '"}';
apiClient.addDefaultHeader('X-DocuSign-Authentication', creds);
// assign api client to the Configuration object
docusign.Configuration.default.setDefaultApiClient(apiClient);
// ===============================================================================
// Step 1: Login() API
// ===============================================================================
// login call available off the AuthenticationApi
var authApi = new docusign.AuthenticationApi();
// login has some optional parameters we can set
var loginOps = new authApi.LoginOptions();
loginOps.setApiPassword('true');
loginOps.setIncludeAccountIdGuid('true');
authApi.login(loginOps, function (error, loginInfo, response) {
if (error) {
console.log('Error: ' + error);
return;
}
if (loginInfo) {
// list of user account(s)
// note that a given user may be a member of multiple accounts
var loginAccounts = loginInfo.getLoginAccounts();
console.log('LoginInformation: ' + JSON.stringify(loginAccounts));
// ===============================================================================
// Step 2: Create Envelope API (AKA Signature Request) from a Template
// ===============================================================================
// create a new envelope object that we will manage the signature request through
var envDef = new docusign.EnvelopeDefinition();
envDef.setEmailSubject(subject);
envDef.setTemplateId(templateId);
envDef.setTemplateRoles([
{email:'foo#email.com',
name:'bob',
roleName:'Seller',
// tabStatuses:[
// {tabStatus:[{
// tabLabel:'sellerName',
// tabValue:'test123'
// }]}
// ]
tabs:
{textTabs:[{
tabLabel:'sellerName',
tabName:'sellerName',
tabValue:'test123'
}]},
// tabStatuses:
// {textTabs:[{
// tabLabel:'sellerName',
// tabName:'sellerName',
// tabValue:'test123'
// }]}
}
]);
// console.log("eid", envDef.getEnvelopeId()); //undefined
//I commented out the following example code. I looked through the docusign-esign source and it didn't seem to have a way to add tabStatuses (whatever that means) so I used the above code instead. Which works as far as sending the email, but doesn't work for pre-filling the fields.
// create a template role with a valid templateId and roleName and assign signer info
// var tRole = new docusign.TemplateRole();
// tRole.setRoleName(templateRoleName);
// tRole.setName(signerName);
// tRole.setEmail(signerEmail);
//
// // create a list of template roles and add our newly created role
// var templateRolesList = [];
// templateRolesList.push(tRole);
//
// // assign template role(s) to the envelope
// envDef.setTemplateRoles(templateRolesList);
// send the envelope by setting |status| to "sent". To save as a draft set to "created"
envDef.setStatus('sent');
// use the |accountId| we retrieved through the Login API to create the Envelope
var loginAccount = new docusign.LoginAccount();
loginAccount = loginAccounts[0];
var accountId = loginAccount.accountId;
//it gets a little messy with junk experimental code. But what's not commented out is the same as the example, except I've added an additional callback in the deepest function.
// instantiate a new EnvelopesApi object
var envelopesApi = new docusign.EnvelopesApi();
// envelopesApi.getDocuments(loginAccount.accountId)
// call the createEnvelope() API
envelopesApi.createEnvelope(accountId, envDef, null, function (error, envelopeSummary, response) {
if (error) {
console.log('Error: ' + error);
return;
}
if (envelopeSummary) {
console.log('EnvelopeSummary: ' + JSON.stringify(envelopeSummary));
var envelopeId = envelopeSummary.envelopeId;
console.log("envelopeId", envelopeId);
// envelopesApi.listDocuments(accountId, envelopeId, function (error, data, response) {
// if (error) {console.log("error", error);return;}
// console.log("data", data);
// console.log("response", response);
// });
//envelopesApi.getDocument downloads the PDF binary 2.5MiB.
var documentId = '1';
var chunks=[];
envelopesApi.listCustomFields(accountId, envelopeId, function (error, data, response) {
if (error) {console.log("error", error);return;}
console.log("typeof data", typeof data);
// console.log("data.length", data.length);
// // console.log("response", response);
// response.on('data',chunk => chunks.push(chunk));
// response.on('end',()=>{
// var allChunks = chunks.join('');
// console.log("allChunks", allChunks);
// });
console.log("data", data);
// console.log("data.toJson()", data.toJson());
console.log("data.getTextCustomFields()", data.getTextCustomFields());
});
}
});
}
});
}; // end RequestSignatureFromTemplate()
When they say tab what are they talking about? What is a tab?
Tabs - aka fields or tags- can be added to documents and templates and are used several ways.
First they are used to indicate to a recipient where a signature or initials are required.
Second, they can be used to show data or information to recipients, such as dates, names, addresses, and other data.
Third, tabs can be used as editable information fields so you can retrieve data or information from your recipients
More information here
Does tabLabel mean Data Label, or are they different things?
Yes they are the same.
If you give tabs of the same type the same tabLabel when a recipient updates one tab it will update all the others with the same data in real-time.
More information here (see "Shared Tab Labels" section)
How can I add a "custom field" to my docusign template? I've tried to do it by clicking Custom Fields, and adding one. But it seems to be more of a field template than a specific custom field. When I run the API call listCustomFields, it comes back empty.
A "custom field" could mean several things.
See this answer for more information.
If you are looking for the Tabs on a document then you should explore the listEnvelopeTabs api
My template comes through fine, but the fields are not pre-filled.
If you are looking for pre-filled Fields (aka Tabs), you should set the "value" property in your request. More info here
Here is the raw Json request.
"tabs": {
"textTabs": [
{
"value": "$100",
"xPosition": "300",
"yPosition": "200",
"documentId": "1",
"pageNumber": "1"
}]
}

Handle XMPP presence with Node

I'm using the node-xmpp module to connect to a XMPP server and join a group chat. Connecting to the server, setting the presence, joining the room and reading out messages works so far. But I want to receive the userlist of the room too.
The XMPP protocol requires to send a presence stanza when the client enters the room (http://xmpp.org/extensions/xep-0045.html#enter-pres). But how can I now parse it in node?
My code currently looks like this:
var xmpp = require('node-xmpp');
// Create the XMPP Client
var cl = new xmpp.Client({
jid: jid,
password: password,
reconnect: true
});
// Do things when online
cl.on('online', function() {
util.log("We're online!");
// Set client's presence
cl.send(new xmpp.Element('presence', { type: 'available' }).c('show').t('chat'));
cl.send(new xmpp.Element('presence', { to: room_jid+'/'+room_nick }).c('x', { xmlns: 'http://jabber.org/protocol/muc' }).c('history', {seconds: 1}));
// Send keepalive
setInterval(function() {
cl.send(' ');
}, 30000);
cl.on('stanza', function(stanza) {
// always log error stanzas
if (stanza.attrs.type == 'error') {
util.log('[error] ' + stanza);
return;
}
// ignore everything that isn't a room message
if (!stanza.is('message') || !stanza.attrs.type == 'chat') {
return;
}
var body = stanza.getChild('body');
// message without body is probably a topic change
if (!body) {
return;
}
// Extract username
var from, room, _ref;
_ref = stanza.attrs.from.split('/'), room = _ref[0], from = _ref[1];
var message = body.getText();
// Log topics and messages to the console
if(!from) {
util.log('Topic: ' + message);
} else {
util.log('[' + from + ']: ' + message);
}
});
});
I already tried triggering presence by using
if(stanza.is('presence')) {}
within the cl.on('stanza') part but it doesn't work.
UPDATE: I'm describing a new method now which doesn't require the client to send requests.
Background: When the client joins a group chat, the server returns presence stanzas which contain information about the connected users to the group chat.
cl.on('stanza', function(stanza) {
// always log error stanzas
if (stanza.attrs.type == 'error') {
util.log('[error] ' + stanza);
return;
}
if(stanza.is('presence')){
// We are only interested in stanzas with <x> in the payload or it will throw some errors
if(stanza.getChild('x') !== undefined) {
// Deciding what to do based on the xmlns attribute
var _presXmlns = stanza.getChild('x').attrs.xmlns;
switch(_presXmlns) {
// If someone is joining or leaving
case 'http://jabber.org/protocol/muc#user':
// Get the role of joiner/leaver
_presRole = stanza.getChild('x').getChild('item').attrs.role;
// Get the JID of joiner/leaver
_presJID = stanza.getChild('x').getChild('item').attrs.jid;
// Get the nick of joiner/leaver
_presNick = stanza.attrs.from.split('/')[1];
// If it's not none, this user must be joining or changing his nick
if(_presRole !== 'none') {
// We are now handling the data of joinging / nick changing users. I recommend to use an in-memory store like 'dirty' [https://github.com/felixge/node-dirty] to store information of the users currentliy in the group chat.
} else {
// We are now handling the data of leaving users
}
break;
}
return;
}
return;
}
OLD METHOD
I previously described a method how to query the server for current users in the group chat. By maintaining a store where all user traffic (joining, leaving, nick changing) is stored, this is no longer required. However you could still use it to make sure the data is consistent by issues like a presence stanza was not delivered to the client correctly. That's the reason it's still described below:
To request a list with users connected to the room, you need to perform the following actions:
First send a request to the server and ask for the user list:
cl.send(new xmpp.Element('iq', {from: jid, to: room_jid, type: 'get' }).c('query', { xmlns: 'http://jabber.org/protocol/disco#items' }));
then listen for iq-stanzas, parse them and populate an array with the data:
// Catching the requested user list
if(stanza.is('iq')){
// Fetching usernames from return data (data structure: http://xmpp.org/extensions/xep-0045.html#example-12)
var _items = stanza.getChild('query').getChildren('item');
var users = new Array();
for(var i = 0; i<_items.length; i++) {
// We are building an object here to add more data later
users[i] = new Object();
users[i]['name'] = _items[i].attrs.name;
}
console.log(util.inspect(users, {depth: null, colors: true}));
return;
}
This will provide you with a user list. To request unique JIDs you have to probe every user. To keep the list up to date, you should remove users when they leave and add + probe when they join.

Resources