Notify user for document signing after embedded signing - javascript

I am trying to embed docusign api to my application for signing documents from two parties. Until now I have been able to use the docusign "Request a signature through your app (embedded signing)" to allow a specific individual to sign the document through my app.
Now I want to add an additional user's email, who will be notified via email when the first user completes the signing procedure to sign his part of the document.
In the code, I have tried to add a second recipient/signer:
const signer2 = docusign.Signer.constructFromObject({
email: "blah#blah.com",
name: "Blah",
clientUserId: "blah",
recipientId: 2,
routingOrder: "2",
});
add his tabs:
const signHere2 = docusign.SignHere.constructFromObject({
anchorString: "/sn2/",
anchorYOffset: "-10",
anchorUnits: "pixels",
anchorXOffset: "0" });
const signer2Tabs = docusign.Tabs.constructFromObject({
signHereTabs: [signHere2] });
signer2.tabs = signer2Tabs;
and add this signer to the recipients list:
const recipients = docusign.Recipients.constructFromObject({
signers: [signer1, signer2],
});
env.recipients = recipients;
The first signer is able to sign the document embedded through my app and complete the process. However, the second signer never receives the email for signing his part when the first one completes. Any idea?

Remove clientUserId from the second signer like this:
const signer2 = docusign.Signer.constructFromObject({
email: "blah#blah.com",
name: "Blah",
recipientId: 2,
routingOrder: "2",
});

Related

Stripe business profile is not showing on request body

I'm in test mode, I create a custom connected account successfully using JavaScript in frontend and PHP in backend.
The account created successfully but for some reason, the business profile is not showing on request body (I see this in stripe log in dashboard).
I see a warning message before form submition:
business_profile is not a recognized parameter
For your reference, here’s the API coding I used when I did my test:
https://stripe.com/docs/api/accounts/create?lang=php#create_account-business_profile
JavaScript
const accountResult = await stripe.createToken('account', {
business_type: 'company',
company: {...},
business_profile: {
mcc: "5812",
support_email: "test#example.com",
url: "https://example.com",
},
tos_shown_and_accepted: true,
});
PHP
// ...
$account = \Stripe\Account::create([
"country" => "FR",
"type" => "custom",
"account_token" => $account_token,
]);
// ...
stripe.createToken doesn't take a business_profile value, nor does it manage Stripe\Account objects at all - it creates a Stripe\Token. You'll have to update that information via a separate call to the Stripe API. The parameters it does take are documented here:
name, address_line1,address_line2, address_city, address_state, address_zip, address_country, currency

How to create a Stripe subscription with a variable quantity?

Right now I'm successfully creating a Stripe subscription that has a hardcoded quantity:
customer = stripe.Customer.create(email=request.form['stripeEmail'], source=request.form['stripeToken'])
# For the moment, change the quantity parameter for each customer
subscription = stripe.Subscription.create(
customer = customer.id,
items = [
{
'plan': 'plan_*************',
'quantity': 7,
},
],
)
The idea would be to obtain that value for quantity from the frontend. I already have a selector that sets the quantity value programmatically and I'm actually using it to print variable amounts in Stripe Checkout:
<script>
var handler = StripeCheckout.configure({
key: "{{pub_key}}",
image: "https://stripe.com/img/documentation/checkout/marketplace.png",
locale: "auto",
zipCode: true,
token: function(token) {
// You can access the token ID with `token.id`.
// Get the token ID to your server-side code for use.
}
});
document.getElementById("customButton").addEventListener("click", function(e) {
var quantity = document.getElementsByName("selectedQuantity")[0];
var text = quantity.options[quantity.selectedIndex].text;
// Open Checkout with further options:
handler.open({
name: "Company, Inc.",
description: text + " Subscriptions",
amount: 900 * text
});
e.preventDefault();
});
// Close Checkout on page navigation:
window.addEventListener("popstate", function() {
handler.close();
});
</script>
Notice that I'm getting the public key from the backend, but I don't know how to retrieve the quantity value from the frontend in the backend.
How do I do that?
EDIT:
When I wasn't using a custom Checkout integration I had a form that would do this:
<form action="{{ url_for('pay') }}" method="POST">
But there is no form here, so I'm not sure what should the next step be.
How are you submitting the token to your backend server(i.e. how have you implemented the token function)? Once you've done that, you can just submit the quantity in the same way.
One way to do this might be to use a form, add the Stripe token to a hidden input in that form, and then submit it with Javascript.
Here's an example : https://jsfiddle.net/53u96kvw/
Or if you don't have a form at all, you can make an AJAX request with the same information : https://jsfiddle.net/kcp12o3z/

Modelling a Chat like Application in Firebase

I have a Firebase database structuring question. My scenario is close to a chat application. Here are the specifics
- users(node storing several users of the app)
- id1
name: John
- id2
name: Meg
- id2
name: Kelly
- messages(node storing messages between two users)
- message1
from: id1
to: id2
text: ''
- message2
from: id3
to: id1
text: ''
Now imagine building a conversations view for an individual user. So I want to fetch all messages from that particular user
and to that particular user
I am writing it as follows right now:
let fromMessagesRef = firebase.database().ref('messages').orderByChild('from').equalTo(firebase.auth().currentUser.uid)
fromMessagesRef.once("value").then((snapshot) => {/* do something here*/})
let toMessagesRef = firebase.database().ref('messages').orderByChild('to').equalTo(firebase.auth().currentUser.uid)
toMessagesRef.once("value").then((snapshot) => {/* do something here*/})
Questions:
Is this the right way to model the problem?
If yes, is there a way to combine the above 2 queries?
I would store the data like this:
- users(node storing several users of the app)
- id1
name: John
messages
message1: true
message2: true
- id2
name: Meg
messages
message1: true
message3: true
- id3
name: Kelly
messages
message2: true
message3:true
- messages(node storing messages between two users)
- message1
from: id1
to: id2
text: ''
- message2
from: id3
to: id1
text: ''
- message3
from: id2
to: id3
text: ''
Firebase recommends storing things like this. So in your case your query would be
let fromMessagesRef = firebase.database().child('users').child(firebase.auth().currentUser.uid).child('messages')
This allows it to be very fast as there is no orderBy being done. Then you would loop over each message and get it's profile from the messages node.
The structure you have is one possible way to model this data. If you're building an application like this, I would highly recommend the angularfire-slack tutorial. One potentially faster way to model the data would be to model the data like is suggested in this tutorial https://thinkster.io/angularfire-slack-tutorial#creating-direct-messages
{
"userMessages": {
"user:id1": {
"user:id2": {
"messageId1": {
"from": "simplelogin:1",
"body": "Hello!",
"timestamp": Firebase.ServerValue.TIMESTAMP
},
"messageId2": {
"from": "simplelogin:2",
"body": "Hey!",
"timestamp": Firebase.ServerValue.TIMESTAMP
}
}
}
}
}
The one thing you need to watch for in this case if you choose to do it like this is that before your query, you need to sort which user will be the "primary user" under whom the messages will be stored. As long as you make sure that is the same every time, you should be good to go.
One improvement you could make to this structure is something you already pointed out - flattening your data and moving the messages to another node - like you did in your example.
To answer your second question, if you were to keep that structure, I think you would need both of those queries, because firebase does not support a more complicated OR query that would allow you to search both at the same time.
No. Firebase Auth subsystem is where you want to store the email, displayName, password, and photoURL for each user. The function below is how you do it for a password-based user. oAuth-based users are easier. If you have other properties you want to store, like age for example, put those under a users node with each users uid that Firebase Authentication provides you.
function registerPasswordUser(email,displayName,password,photoURL){
var user = null;
//NULLIFY EMPTY ARGUMENTS
for (var i = 0; i < arguments.length; i++) {
arguments[i] = arguments[i] ? arguments[i] : null;
}
auth.createUserWithEmailAndPassword(email, password)
.then(function () {
user = auth.currentUser;
user.sendEmailVerification();
})
.then(function () {
user.updateProfile({
displayName: displayName,
photoURL: photoURL
});
})
.catch(function(error) {
console.log(error.message);
});
console.log('Validation link was sent to ' + email + '.');
}
As for the messages node, get the random id from Firebase Realtime Database's push method and use that as the id of each message under messages. Firebase queries are used:
var messages = firebase.database().ref('messages');
var messages-from-user = messages.orderByChild('from').equalTo('<your users uid>');
var messages-to-user = messages.orderByChild('to').equalTo('<your users uid>');
messages-from-user.once('value', function(snapshot) {
console.log('A message from <your users uid> does '+(snapshot.exists()?'':'not ')+' exist')
});
messages-to-user.once('value', function(snapshot) {
console.log('A message to <your users uid> does '+(snapshot.exists()?'':'not ')+' exist')
});
Define an index for messages-from-user and messages-to-user in your Rules:
{
"rules": {
"messages": {
".indexOn": ["from", "to"]
}
}
}
Below data structure gives you more flexibility with you data. Instead of having to store each messages that user sent back and forth I would suggest to store it in separate node and store the messageID with each user that is involved in the conversation.
Obviously you need to set the security rules, so other user can't see conversation if they are not in the conversation.
By doing this we are not creating deep chain node inside user info
- users(node storing several users of the app)
- id1
name: John
messages: [msID1, msID9]
- id2
name: Meg
messages: [msID1, msID7]
- id3
name: Kelly
messages: [msID9, msID7]
- messages(node storing messages between two users)
- msID1
from: id1
to: id2
text: ''
- msID7
from: id3
to: id2
text: ''
- msID9
from: id3
to: id1
text: ''
Firebase has actually built a demo (and extendible) chat application called Firechat. The source and documentation is provided, and of particular note is the section on their data structures.
Although they've implemented chatrooms, you can see that they've flattened their data structures as in many of the other answers. You can read more about how and why this is done in the Firebase guide.

correct way to use Stripe's stripe_account header from oauth with meteor

I'm trying to build a platform based on Meteor that uses Stripe Connect. I want to use the "preferred" authentication method from Stripe (Authentication via the Stripe-Account header, https://stripe.com/docs/connect/authentication) so that I can create plans and subscribe customers on behalf of my users. I cannot get it to work. I tried with a second params object, similar to the exemple in the documentation:
var stripeplancreate = Meteor.wrapAsync(Stripe.plans.create, Stripe.plans);
var plan = stripeplancreate({
amount: prod.price,
interval: prod.interv,
name: prod.name,
currency: prod.curr,
id: prod.id+"-"+prod.price+"-"+prod.curr+"-"+prod.interv,
metadata: { prodId: prod._id, orgId: org._id },
statement_descriptor: prod.descr
},{stripe_account: org.stripe_user_id});
but I get "Exception while invoking method 'createStripeProduct' Error: Stripe: Unknown arguments ([object Object]). Did you mean to pass an options object? See https://github.com/stripe/stripe-node/wiki/Passing-Options." which does not seem to accurately reflect the issue but prompted me to try adding stripe_account in the params object itself:
var stripeplancreate = Meteor.wrapAsync(Stripe.plans.create, Stripe.plans);
var plan = stripeplancreate({
amount: prod.price,
(...)
statement_descriptor: prod.descr,
stripe_account: org.stripe_user_id
});
I then get the following error: "Exception while invoking method 'createStripeProduct' Error: Received unknown parameter: stripe_account"
Any ideas? Has anybody managed to have Stripe Connect stripe_account authentication work with Meteor, especially with Meteor.wrapAsync(...)?
This should work for wrapAsync, HOWEVER check out my answer here for possible issues with wrapAsync - Wrapping Stripe create customer callbacks in Fibers in Meteor:
Here is also a great video on wrapAsync: https://www.eventedmind.com/feed/meteor-meteor-wrapasync
var createStripePlanAsync = function(shoppingCartObject, callback){
stripe.plans.create({
amount: shoppingCartObject.plan.totalPrice,
interval: shoppingCartObject.plan.interval,
name: shoppingCartObject.plan.planName,
currency: "usd",
id: shoppingCartObject.plan.sku //this ID needs to be unique!
}, function(err, plan) {
// asynchronously called
callback(err, plan);
});
};
var createStripePlanSync = Meteor.wrapAsync(createStripePlanAsync);
var myShoppingCart = {
customerInfo: {
name: "Igor Trout"
},
plan: {
totalPrice: 5000,
interval: "month",
name: "Set Sail For Fail Plan",
sku: "062015SSFF"
}
};
// Creates the plan in your Stripe Account
createStripePlanSync(myShoppingCart);
Later when you subscribe a customer to a plan you just refer to the plan via the id that you gave the plan when you first created it.
After much trying multiple things, for now, I just managed to get it working using the stripe-sync package instead of the "normal" one + wrapAsync.
try{
var plan = Stripe.plans.create({
amount: prod.price,
...
},{stripe_account: org.stripe_user_id});
}catch(error){
// ... process error
}

Access user email address in Meteor JS app

I am building an app using Meteor and need to access the stored email address of a logged-in user.
I am currently using:
var userObj = Meteor.user();
console.log(userObj);
to access the user. However, I am only able to access the id. The email address is stored in a nested object that looks like this:
[Object {address="address#gmail.com", verified=false}]
I have tried various ways to traverse the JSON object but can't figure out how to access the value I need.
Meteor.user().emails[0].address works for me.
Here's what the doc says:
By default the server publishes username, emails, and profile. See
Meteor.users for more on the fields used in user documents.
Example user document:
{
_id: "bbca5d6a-2156-41c4-89da-0329e8c99a4f", // Meteor.userId()
username: "cool_kid_13", // unique name
emails: [
// each email address can only belong to one user.
{ address: "cool#example.com", verified: true },
{ address: "another#different.com", verified: false }
],
createdAt: 1349761684042,
profile: {
// The profile is writable by the user by default.
name: "Joe Schmoe"
},
services: {
facebook: {
id: "709050", // facebook id
accessToken: "AAACCgdX7G2...AbV9AZDZD"
},
resume: {
loginTokens: [
{ token: "97e8c205-c7e4-47c9-9bea-8e2ccc0694cd",
when: 1349761684048 }
]
}
}
}
You don't specify how you are authenticating users. For example, if you were using Google authentication only, the email address would be found only in
Meteor.user().services.google.email
So, it depends.
Try this:
Meteor.user().emails[0].address
Regards,

Categories

Resources