Application creates classroom invitation, but no email is being sent to student - google-api-client

After creating a classroom invitation the method classroom.create returns with the return status 200 but the user never receives email with the invitation message.
I have given the the client id associated with the service account that I am using, the scopes classroom.roster and mail.google.com, but nothing seems to work.
Am I missing something?
Thank you very much,
Andres
This is the fragment of code that creates the invitation:
//get authorization client
const auth = await google.auth.getClient({
scopes
});
//impersonate teacher account
if (auth instanceof google.auth.JWT) {
auth.subject = 'teacher_email#dom.edu';
}
const options = { auth,
requestBody: {
courseId: '19220887720',
role: 'STUDENT',
userId: 'student_email#dom.edu'
}
};
//send invitation
try {
const invitation = await classroom.invitations.create(options);
console.log('invitation was sent:', invitation);
} catch (err) {
console.error('error: ' , err);
}
Response: status 200.
The invitation is really created. Response includes an invitation id and If you check on the ClassRoom home page->people you can see the correct student was invited.

Based from this forum, students need to have the same settings on in their account, which they may not by default. They should also choose to be a student first.
Also, notification e-mails of Google Classroom are sent from classroom.google.com domain. See Email notifications - Classroom Help for further details.

Related

Impossible to Send Multiple Emails from Gmail after May 30th Update

I have code which has remained essentially unchanged for months. The code extracted an email address and email password from an .env file and was used for a few difference cases. Whenever a single user signs up, they would receive an email; and whenever an owner signs many employees up, each of them would receive and email.
The email account we used to send these emails was a Gmail, and was created before the May 30th update and allowed less secure apps access. This allowed it to work sending an individual an email when they signed up, and provided there was a 1 second delay between each employee signed up, it was able to handle the en masse emailing as well.
The email account we use has since been changed, this new email was created after the May 30th update. I jumped through all of the extra hoops to enable less secured apps on this new account, so it sends individual sign up emails with no issue. However, as soon as I attempt to execute the en masse emails (even with the one second delay) I get the following error:
Error: Invalid login: 535-5.7.8 Username and Password not accepted.
Now, this really makes no sense because it is a copy and paste job of the email syntax that DOES work meaning this code below works...
try{
// Creates the Transporter
const transporter = nodemailer.createTransport({
service: "Gmail",
auth: {
user: `${process.env.SIGNUP_EMAIL}`,
pass: `${process.env.SIGNUP_PASS}`
}
})
// Creates the Mail Object
const mailOptions = {
from: `${process.env.SIGNUP_EMAIL}`,
to: `${actualEmail}`,
subject: `Thank you for joining the TOM Team!`,
text: `We have recieved your Account Signup and are please to welcome you to the TOM Experience!`
}
// Sends the mail
transporter.sendMail(mailOptions, (error, response) => {
if (error){
throw new Error('Something went wrong, please try again \n' + error)
}
})
} catch(error){
console.log(error)
}
But this code DOES NOT (breaks on the first attempt no matter how many others there are after)
try{
const transporter = nodemailer.createTransport({
service: "Gmail",
auth: {
user: `${process.env.SIGNUP_EMAIL}`,
pass: `${process.env.SIGNUP_PASS}`
}
})
// Creates the Mail Object
const mailOptions = {
from: `${process.env.SIGNUP_EMAIL}`,
to: `${actualEmail}`,
subject: `Thank you for joining the TOM Team!`,
text: `We have recieved your Account Signup and are please to welcome you to the TOM Experience! \nUpon recieving this email, you will have a new TOM Account for the mobile app. Please use this email, and the password "${passwordToUse}" to login and get started!`
}
// Sends the mail
transporter.sendMail(mailOptions, (error, response) => {
if (error){
console.log(error)
throw new Error('Something went wrong, please try again \n' + error)
}
})
}
catch(err){
console.log(err)
throw new Error(`Something went wrong emailing ${actualEmail}. Please check this is the proper address.`)
}
Is it just impossible to send gmails en masse now? Even with a 1 second delay? Even if not, why is the very first email failing? I truly have no idea why I'm facing these errors
I'm not sure why this is, but increasing the wait time from 1000 milliseconds to 1500, and then back to 1000 did the trick.
I'm not sure, maybe the new email just needed to get baby-stepped into sending multiple at a time.

Send Money to Paypal Account ASP.Net Server Side Code

I am having a difficult time finding halfway descent documentation or examples on how to send money to another Paypal account.
I have installed the Nuget package PaypalSDK version 1.0.4. I have read the documentation at https://developer.paypal.com/home. I have browsed and tried to implement the sample code at https://github.com/paypal/Checkout-NET-SDK.
The problem I am having is that I am having is that I am not seeing notifications of payments sent or received in my sandbox account. I can successfully execute a checkout with the Javascript button in my shopping cart view. But eventually I want to add the capability to send money from my Paypal business account to another Paypal business account, without the other Paypal Business Account owner having to be logged in to my website.
Does the money recipient have to authorize the money I send, or should it just get deposited into their account once I send it?
Here is my code:
namespace MyShoppingCart.Helpers.Paypal
{
public class CaptureOrderSample
{
static string PayPalClientID = Startup.StaticConfig.GetValue<string>("Paypal:ClientID");
static string PayPalClientSecret = Startup.StaticConfig.GetValue<string>("Paypal:ClientSecret");
public static HttpClient client()
{
// Creating a sandbox environment
PayPalEnvironment environment = new SandboxEnvironment(PayPalClientID, PayPalClientSecret);
// Creating a client for the environment
PayPalHttpClient client = new PayPalHttpClient(environment);
return client;
}
public async static Task<HttpResponse> createOrder(string Email)
{
HttpResponse response;
// Construct a request object and set desired parameters
// Here, OrdersCreateRequest() creates a POST request to /v2/checkout/orders
var order = new OrderRequest()
{
CheckoutPaymentIntent = "CAPTURE",
PurchaseUnits = new List<PurchaseUnitRequest>()
{
new PurchaseUnitRequest()
{
AmountWithBreakdown = new AmountWithBreakdown()
{
CurrencyCode = "USD",
Value = "100.00"
},
Payee = new Payee
{
Email = Email // "payee#email.com"
}
}
}
//,
//ApplicationContext = new ApplicationContext()
//{
// ReturnUrl = "https://www.example.com",
// CancelUrl = "https://www.example.com"
//}
};
// Call API with your client and get a response for your call
var request = new OrdersCreateRequest();
request.Prefer("return=representation");
request.RequestBody(order);
response = await client().Execute(request);
var statusCode = response.StatusCode;
Order result = response.Result<Order>();
Debug.WriteLine($"Status: {result.Status}");
Debug.WriteLine($"Order Id: {result.Id}");
Debug.WriteLine($"Intent: {result.CheckoutPaymentIntent}");
Debug.WriteLine("Links:");
foreach (LinkDescription link in result.Links)
{
Debug.WriteLine($"\t{link.Rel}: {link.Href}\tCall Type: { link.Method}");
}
return response;
}
}
}
And this is currently called from my Orders controller when an order is completed. This is just for testing purposes.
[Authorize]
public async Task<IActionResult> CompleteOrder()
{
var items = _shoppingCart.GetShoppingCartItems();
Models.Order order = await _ordersService.StoreOrderAsync(items);
PrepareSellerEmail(items, order, "You Have a New Order!");
PrepareBuyerEmail(items, order, "Thank You for Your Order!");
await _shoppingCart.ClearShoppingCartAsync(_serviceProvider);
DeleteCartIDCookie();
//OrderRequest request = Helpers.CreateOrderSample.BuildRequestBody("USD", "100.00", "sb-r43z1e9186231#business.example.com");
//var client = Helpers.Paypal.CaptureOrderSample.client();
var result = Helpers.Paypal.CaptureOrderSample.createOrder("sb-r43z1e9186231#business.example.com");
//var response = await PayPalClient.client().execute.(request);
return View("OrderCompleted");
}
The output of the result is:
Status: CREATED
Order Id: 51577255GE4475222
Intent: CAPTURE
Links:
self: https://api.sandbox.paypal.com/v2/checkout/orders/51577255GE4475222 Call Type: GET
approve: https://www.sandbox.paypal.com/checkoutnow?token=51577255GE4475222 Call Type: GET
update: https://api.sandbox.paypal.com/v2/checkout/orders/51577255GE4475222 Call Type: PATCH
capture: https://api.sandbox.paypal.com/v2/checkout/orders/51577255GE4475222/capture Call Type: POST
This is a screen capture from my sandbox account:
Am I supposed to do something else to actually execute the transfer?
Edit: I figured out how to use the Paypal Payouts API.
First I installed the Nuget Package. It's simply called PayoutsSdk. I'm using version 1.1.1.
For the payout to execute, you need the client() method that is listed above in this post, and this CreatePayout() method listed below.
public async static Task<HttpResponse> CreatePayout()
{
var body = new CreatePayoutRequest()
{
SenderBatchHeader = new SenderBatchHeader()
{
EmailMessage = "Congrats on recieving 1$",
EmailSubject = "You recieved a payout!!"
},
Items = new List<PayoutItem>()
{
new PayoutItem()
{
RecipientType="EMAIL",
Amount=new Currency()
{
CurrencyCode="USD",
Value="1",
},
Receiver="sb-r43z1e9186231#business.example.com",
}
}
};
PayoutsPostRequest request = new PayoutsPostRequest();
request.RequestBody(body);
var response = await client().Execute(request);
var result = response.Result<CreatePayoutResponse>();
Debug.WriteLine($"Status: {result.BatchHeader.BatchStatus}");
Debug.WriteLine($"Batch Id: {result.BatchHeader.PayoutBatchId}");
Debug.WriteLine("Links:");
foreach (PayoutsSdk.Payouts.LinkDescription link in result.Links)
{
Debug.WriteLine($"\t{link.Rel}: {link.Href}\tCall Type: {link.Method}");
}
return response;
}
Of course I'll add parameters to the method for email, amount, currency code, email message, and subject.
Right now, I am calling this method from the controller method like this: var result = Helpers.Paypal.CaptureOrderSample.CreatePayout(); where Helpers.Paypal are folders that contain a class called CaptureOrderSample, which I will probably rename.
To send money from your account to another account, there are several different options:
Automate the sending with the Payouts API or Payouts Web (spreadsheet upload). For live, payouts can only be used if the live account sending the payment is approved for payouts.
Log into the account that is going to send the money in https://www.paypal.com or https://www.sandbox.paypal.com and click on the menu for Pay & Get Paid -> Send Money .
Use a PayPal Checkout integration, with or without the Orders API, and specify a payee that is to receive the money. You must log in with the paying (sending) account to approve the sending, and finally the order must be captured (via API or client side actions.order.capture()) which is what results in a PayPal transaction. If the final capture step is not performed, no money will be sent and the order will merely remain created or approved and eventually expire (72 hours after creation or 3 hours after approval)
In the sandbox, no actual emails are sent with notifications. Instead, the developer.paypal.com dashboard has a "Notifications" tab on the left, and of course activity will also be visible in each sandbox account by logging into the account. Only captured activity is likely to be visible.

How do I just get an email address after authenticating with oAuth2? - google-api-nodejs-client

I am trying to just get an email address after authenticating with oAuth2. After I get a code when I validate with a google account, I go and get the user from Google Plus, like this:
let oAuth2Client = new auth.OAuth2(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_CLIENT_CALLBACK);
const tokens = await getToken(oAuth2Client, code);
oAuth2Client.setCredentials(tokens);
plus('v1').people.get({ userId: 'me', auth: oAuth2Client }, function(err, response) {
.... This repsonse is the full user object from Google Plus
});
How do I just get the email address, or a list of email addresses? I don't want all the other Google Plus info. I have already set my scope to email, but I still get lots of other information. I am assuming that I need to make a request to something other than plus, but I can't find what to do in the documentation.
If you have set email scope (https://www.googleapis.com/auth/userinfo.email), you can use oauth2("v2").userinfo.v2.me.get :
var google = require('googleapis');
....
google.oauth2("v2").userinfo.v2.me.get({
auth: oAuth2Client
}, function(e, profile) {
if ("email" in profile) {
console.log(profile.email);
} else {
console.log("scope email not set");
}
});

how to update an subscription without id in mail chimp rest api

I really like the new Mail Chimp REST API - it is easy to create subscriptions by PUT and those can be updated using the subscription id.
But I would like to update a subscription simply using the email address, because I do not want to save any new Mail Chimp Id in my Middle-ware application, as long as the email should be sufficient as identifier?
To update a List Member the API is:
/lists/{list_id}/members/{id}
but I would prefer a simpler way:
/lists/{list_id}/members/{email}
is something like this possible?
The subscriber's ID is the MD5 hash of their email address. Since you would have to make a function call to URL Encode the email address for your second way, using the first way is just as easy.
See this help document on managing subscribers for more details.
More specifics on updating a subscriber via MailChimp's REST API.
// node/javascript specific, but pretty basic PUT request to MailChimp API endpoint
// dependencies (npm)
var request = require('request'),
url = require('url'),
crypto = require('crypto');
// variables
var datacenter = "yourMailChimpDatacenter", // something like 'us11' (after '-' in api key)
listId = "yourMailChimpListId",
email = "subscriberEmailAddress",
apiKey = "yourMailChimpApiKey";
// mailchimp options
var options = {
url: url.parse('https://'+datacenter+'.api.mailchimp.com/3.0/lists/'+listId+'/members/'+crypto.createHash('md5').update(email).digest('hex')),
headers: {
'Authorization': 'authId '+apiKey // any string works for auth id
},
json: true,
body: {
email_address: email,
status_if_new: 'pending', // pending if new subscriber -> sends 'confirm your subscription' email
status: 'subscribed',
merge_fields: {
FNAME: "subscriberFirstName",
LNAME: "subscriberLastName"
},
interests: {
MailChimpListGroupId: true // if you're using groups within your list
}
}
};
// perform update
request.put(options, function(err, response, body) {
if (err) {
// handle error
} else {
console.log('subscriber added to mailchimp list');
}
});

verify email using accounts.ui package

I want to send a verification email when some user is created. I use the accounts-password package, so any Accounts methods are called in my code.
I read in documentation that I need to call:
Accounts.sendVerificationEmail(userId, [email])
but the problem is that I don't know when to call it.
I tried to call in the callback function of Accounts.onCreateUser(func) but the user had not been created yet in the database.
Any ideas?
on the serverside:
Accounts.config({sendVerificationEmail: true, forbidClientAccountCreation: false});
got the answer from the comments above.
sendVerificationEmail is only available server-side. What I usually do is to use a setInterval inside onCreateUser to wait for Meteor to create the user before sending an email.
Read More: Verify an Email with Meteor Accounts.
// (server-side)
Accounts.onCreateUser(function(options, user) {
user.profile = {};
// we wait for Meteor to create the user before sending an email
Meteor.setTimeout(function() {
Accounts.sendVerificationEmail(user._id);
}, 2 * 1000);
return user;
});
You need specify mail in enviroment variables.
Then use Accounts.sendVerificationEmail(userId, [email]) in callback of Account.onCreateUser sorry for mistake and delay.
Like this (below is full example js file):
Template.register.events({
'submit #register-form' : function(e, t) {
e.preventDefault();
var email = t.find('#account-email').value
, password = t.find('#account-password').value;
// Trim and validate the input
Accounts.onCreateUser({email: email, password : password}, function(err){
if (err) {
// Inform the user that account creation failed
} else {
// Success. Account has been created and the user
// has logged in successfully.
Accounts.sendVerificationEmail(this.userId, email);
}
});
return false;
} });
if(Meteor.isServer){
Meteor.startup(function(){
process.env.MAIL_URL='smtp://your_mail:your_password#host:port'
}
}
I refered to this pages :
http://blog.benmcmahen.com/post/41741539120/building-a-customized-accounts-ui-for-meteor
http://sendgrid.com/blog/send-email-meteor-sendgrid/
How come my Meteor app with accounts package is not sending a verification email?