How to implement unsubscribe usecase for website - google-app-engine

I'm sending automated emails and hence I should deliver an unsubscribe function. I have a User entity that is not used much, only when a user registers and the emails can be send to users who are not registered as Users. So when I send an email and I must include an unsubscribe link, should I keep a whole separate entity / class for class Unsubscriptions or include them as a variable in the User class whether or not a user is registered to receive emails?
Did you use any method for unsubscribe that you can recommend? Are there any frameworks for unsubriptions? GAE that I'm using has a very primitive framework for sending and receiving emails and I understand that Amazon has a much more developed API for manging large email list, but I suppose I can still do it all in GAE without Amazon though that would take longer time so I'm considering managing large email lists from Amazon. I have > 10 000 registered users that I never emailed and I'd like to email them a reminder that they are welcome to use my application and that they can unsubscribe from future mailings.

Each new class implies a new query, which adds to the total cost. Pack as much information that is practical into the User class. A simple boolean in the User class should work for active/inactive or subscribe/unsubscribe. Your app needs to accept emails to receive the Unsubscribe request and set the associated boolean to False.

Related

Amazon Cognito (with AWS Amplify + React): Best way to make signups possible only through one-time signup links?

I am writing a web application that will have users outside of my company, but should not have a general "sign up" page. The flow that I am trying to build:
We send new users (customers who have signed a contract with us) a single-use link (e.g. service.com/signup?uuid=[uuid])
The link leads to a page where they set their password. This completes their account creation.
The email for the account is already defined, and connected to the link that was sent to them. For this reason, an email confirmation should not be necessary.
There is also a value for each account called "role", which is not user-facing. When we define a new user, we define a new "role" with it. The UUID of sign-up link is connected to both an email address and a "role".
My current implementation works like this:
One of our existing internal databases has a table of uuids and their corresponding emails and roles. When we want to create a new user, we add a new row with their email and "role". This triggers an invite email that includes the signup link.
The web application, which is written with React + AWS Amplify, shows a signup page built with Amplify's Authenticator UI for React. Custom JS prefills the email field and makes it not editable.
The user sets their password, and behind the scenes React calls a Lambda function to get the email address and role associated with that link. The new account is created with the email, role, and provide password. The user doesn't see any UI related to the "role" because it is only for internal use.
I am aware that this may not be the wisest way to do this. I have a feeling that new accounts should be created by us via Cognito first, and the user should be sent a link to set a password for their already-created account. I don't know the best way to do this, though, especially if I would like to keep the ability to make the signup process more complex (e.g. requiring 2FA, so the user needs to provide a phone number as well as a password and then verify it).
There are several ways I can think of approaching this set of problems, but I feel like my knowledge of AWS is not developed enough to have an instinct for the "correct" way. Is there something I should be doing differently?

Firestore: create hidden data when creating new document

I'm adding a new document every time a user is logged in with Google authentication and that user does not exist in firestore.
What I want is to add a 'USER' role when creating this new USER.
I was expecting to do this outside the react application so it can not be hacked into creating different types of users by calling the Firestore api.
At first I thought of a function but now they are only allowed by having a paid plan.
Thanks in advance for the help.
If you want to implement a role-based access control to your Firestore database, the recommended approach is to use Custom Claims. This indeed requires using the Admin SDK via Cloud Functions or a server you own.
Activating Cloud Functions indeed requires entering the details of a credit card but there is a free tier which allows up to 2M invocations/month for free. So, unless your app is very popular, you'll be only billed for each container required to deploy a function but this is a negligible cost of few tenths of $.
If you don't have any credit card, there is another solution: using some Firestore documents to declare the users roles, as explained here in the doc.
I wanted to add this as a comment but I guess you could make use of the firestore rules to make sure that the role value sent by the client is always set to user and not anything else or you could make sure that this USER role added it a boolean value and in the rules make sure he can only edit his own document this way he won't be able to change his role even if he set it to false it won't give him a different role

How send notification into ms teams user from custom tab

I'm designing a custom team tab using React that calls third party API, I need after executing the API successfully, user gets notified . What is the best way to achieve this? I used Bot in my project, but not sure how can I call it from my custom tab class. I'm aware of the existence of proactive messaging, is it the only way to do it? If it is, a pointer on how to implement it to a custom tab would be appreciated.
If you're wanting to message the user 1-1 (like in the personal app), then proactive messaging is definitely what you need (inside a Team, there are other options), and considering you have the bot already in place that's perfect. The only thing you might be missing are the details required to send the actual proactive message (the best time to get them is when the bot is first installed by the user). In particular, you need ConversationId and ServiceUrl.
With regards the concept of Proactive Messaging, basically once the bot is installed, and you have the required values, you can -send- the message from any backend code at all. That can include, for example, custom tab's backend api. You need to identify the user, which you can do using the Teams Context (it's not the safest way but it's the easiest), and then look up the values in your own backend store (e.g. database or whatever) to get the ConversationId and ServiceUrl, then just message the user in your backend.

How to track different authenticated users' actions using Mixpanel

I have built a React application. The application requires users to login/signup first using Auth0. I have also implemented Mixpanel into my application to track the events (e.g. mixpanel.track('Click event A')). However, I would like to track the actions/events for each different individual user.
For example:
'mary#gmail.com' has clicked on event A for 3 times;
'eric#gmail.com' has clicked on event A for 2 times..etc
Can anyone give me specific steps or directions for how to approach to this purpose ?
P.S: I have read https://help.mixpanel.com/hc/en-us/articles/115004497803-Identity-Management-Best-Practices, it states to use mixpanel.alias(id) when users signup and mixpanel.identify(id) when users login. However, since I am using Auth0, I am not sure where should I include the mixpanel.alias(id).
Given that you only track events after the user has logged in (as per your comment) I don't see any reason for you to use mixpanel.alias.
When Auth0 successfully authorizes a user call mixpanel.identify. Following this the logged in user will be associated with all events that you track.
webAuth.popup.authorize({
redirectUri: 'https://YOUR_APP/popup_response_handler.html'
//Any additional options can go here
}, function(err, authResult) {
if(!err){
mixpanel.identify('USER_ID_HERE');
mixpanel.track('Successful Login');
}
});
Mixpanel uses a distinct_id to relate each track event with a certain profile on their system.
You can use people set events to enrich the profile with user data.
Alias is the mechanism they have to bind a profile’s history of events to a new id, normally used to correlate the actions of an anonymous user with a random distinct_id to the same user, now registered and with a determined user id.
The major limitation on mixpanel’s implementation is that they can only do 1 alias per profile. So, if a user already did the whole navigate anonymous and signup process, but comes again to your site anonymously and does a login, the second time he navigates anonymously will create a different history track of events that you can’t assign to the user.
Since you only want to track identified users, there’s no need to use alias.
Mixpanel provides a JavaScript library that automatically creates a distinct_id for any user, identified or not, that navigates to your site and doesn’t have a distinct_id yet. You need to use the library method identify with your user’s id so that instead of sending the track events with the distinct_id, it does so with your user id.
Now, the mixpanel library is quite heavy and does a lot of things you may not need. Like the distinct_id/identify thing I mentioned, plus browser info, domain and other filds that will automatically populate your track events. If you like that, fine.
If not, you can use the http api they have, which is very easy to use. You can simply do a post request indicating the user id and the event tracked, and you will have the same result without having to depend on the library.

Paypal Integration in Web application

The scenario is that users of web application can purchase digital items. The web application will use Paypal Instant Payment Notification.
The IPN protocol consists of three steps:
PayPal sends your IPN listener a message that notifies you of the event
Your listener sends the complete unaltered message back to PayPal; the message must contain the same fields in the same order and be encoded in the same way as the original message
PayPal sends a single word back, which is either VERIFIED if the message originated with PayPal or INVALID if there is any discrepancy with what was originally sent.
Let's say it's VERIFIED, how could I know who have completed the transaction or purchased the item (user of the web application) if the user used other email address in his/her paypal? I have stored the email address of the user in session but what if he/she have different paypal email? Paypal email is included in IPN message.
For other details, maybe not useful, the application is written in Struts2 in Google-App-Engine.
You'll need a way to correlate the IPN data coming back with the user. Either by asking them to provide their paypal email or using the username/password generation facility in the IPN service. Here is a somewhat inelegant but functional approach:
When the IPN comes in off the wire, persist the paypal generated username/password and payer_id (in perhaps the datastore).
If you can't correlate by email, then when the user comes back to your site request that they enter the username/password generated from paypal's site once (just to correlate).
Lookup the username/password and then correlate their userid from the UserService back to the payerid.
The reason to use IPN is for subscription services as you can get IPN messages when the subscription is terminated, cancelled, or when payments come in (for an account that stopped paying).
The most important thing to think about is how to correlate a user of your site back to the payer_id (or even payer_ids in some cases) that are used to pay for the services they are using.
On another note, I wouldn't use the session to store information for IPN callbacks, those actually can take a LONG time sometimes (say when the x.com conference is on and everyone is hammering paypal).
If you have a running application or a better description of the look & feel, I might be able to come up with a more elegant suggestion. Let me know if this helps at all.
Why don't you use PayPal's express checkout? This way you negotiate server2server a token and then you can check with PayPal the result of that token on user's return.
If users are buying directly from your application it's easier to implement.
And I think it'is more robust than the method you're using (I never heard of it before :D )

Resources