Custom Sign Up form (Velo) using register() api | triggeredemails API Issue

Question:
I want to set up custom sign up form using code (velo) for my site for which I am using register API to register by approaval token but I am not being able to send verification email at all using triggeredemails (emailcontact()) api to the user. It is getting stuck at - "[“Registration failed:”,"Contact does not have valid email for site “]”. How do I go past it?

Product:
WIX Editor - Velo

What are you trying to achieve:
I need to have custom sign up for my website that gets triggered only for users who meet certain criteria.

What have you already tried:
I have also tried ensuring email is in proper format, separately creating a contact for the user, query and send the email for the user.

Here’s my backend code (register.web.js):
import { Permissions, webMethod } from ‘wix-web-module’;
import { authentication } from ‘wix-members-backend’;
import { triggeredEmails } from ‘wix-crm-backend’;

export const doRegistration = webMethod(Permissions.Anyone, async (email, password, firstName, lastName) => {
// Convert email to lowercase to ensure case-insensitive handling
const emailLowercase = email.toLowerCase();

const registrationOptions = {
    contactInfo: {
        firstName: firstName,
        lastName: lastName,
        emails: [emailLowercase] // Use the lowercase email
    }
};

try {
    const registration = await authentication.register(emailLowercase, password, registrationOptions);
    console.log('Member registration attempt:', registration);

    if (registration.status.toLowerCase() === "pending" && registration.approvalToken) {
        const emailOptions = {
            variables: {
                name: firstName,
                verifyLink: `https://www.firstcontact.lgbt/post-registration?token=${registration.approvalToken}`
            }
        };

        await triggeredEmails.emailContact('verifyRegistration', registration.member.contactId, emailOptions);
        console.log('Verification email sent using triggeredEmails.');
        return { success: true, message: "Registration successful, confirmation email sent." };
    } else {
        return { success: false, message: "Registration successful but did not enter approval flow." };
    }
} catch (error) {
    console.error('Registration failed:', error);
    return { success: false, message: `Registration failed due to error: ${error.message}` };
}

});

export const doApproval = webMethod(Permissions.Anyone, async (token) => {
try {
const sessionToken = await authentication.approveByToken(token);
console.log(‘Member approved with session token:’, sessionToken);
return { approved: true, sessionToken: sessionToken };
} catch (error) {
console.error(‘Approval failed:’, error);
return { approved: false, reason: Approval failed due to error: ${error.message} };
}
});

For which API you get the exception/error for?

So, I am taking for emailContact( ) TriggeredEmails API. It correctly identifies the contact ID of the user for correct site but says doesn’t have valid email ID for that. I ran the query to find out the details associated with that contact ID in the Wix CRM using getContact () and it gives all the details correctly including the email ID. So, I do not why is it not recognising the email ID.

This is more or less. the code I use for registration and it works on wix-studio:

import { authentication, authorization } from “wix-members-backend”;
import { triggeredEmails } from “wix-crm-backend”;

let authResults = await authentication.register(email, password, {
contactInfo: {
firstName: firstName,
lastName: lastName,
phones: phones,
emails: [email],
},
privacyStatus: “PUBLIC”,
});

// emailId is the trigger email id
result = await triggeredEmails.emailMember(emailId, authResults.member._id, options);

Thank you for sharing this; I keep encountering the same error. Did you separately give any separate permissions for the triggered emails? I have generated the email ID that I use in the following code.

import { Permissions, webMethod } from 'wix-web-module';
import { authentication } from 'wix-members-backend';
import { triggeredEmails } from 'wix-crm-backend';

export const doRegistration = webMethod(Permissions.Anyone, async (email, password, firstName, lastName) => {
    // Convert email to lowercase to ensure case-insensitive handling
    const emailLowercase = email.toLowerCase();

   const registrationOptions = {
        contactInfo: {
            firstName: firstName,
            lastName: lastName,
            emails: [emailLowercase] // Use the lowercase email
        },
        privacyStatus: "PUBLIC" // Set privacy status to PUBLIC
    };

    try {
        const registration = await authentication.register(emailLowercase, password, registrationOptions);
        console.log('Member registration attempt:', registration);

        if (registration.status.toLowerCase() === "pending" && registration.approvalToken) {
            const emailOptions = {
                variables: {
                    name: firstName,
                    verifyLink: `https://www.firstcontact.lgbt/post-registration?token=${registration.approvalToken}`
                }
            };

            await triggeredEmails.emailMember('verifyRegistration', registration.member.contactId, emailOptions);
            console.log('Verification email sent using triggeredEmails.');
            return { success: true, message: "Registration successful, confirmation email sent." };
        } else {
            return { success: false, message: "Registration successful but did not enter approval flow." };
        }
    } catch (error) {
        console.error('Registration failed:', error);
        return { success: false, message: `Registration failed due to error: ${error.message}` };
    }
});

export const doApproval = webMethod(Permissions.Anyone, async (token) => {
    try {
        const sessionToken = await authentication.approveByToken(token);
        console.log('Member approved with session token:', sessionToken);
        return { approved: true, sessionToken: sessionToken };
    } catch (error) {
        console.error('Approval failed:', error);
        return { approved: false, reason: `Approval failed due to error: ${error.message}` };
    }
});

The emailId that is the parameter sent to emailMember is generated when you create a template to be used for the registration, you cannot generate it yourself.

In other words, in order to send an email via triggerEmails you need first to defined an email template and use the id of the template when invoking emailMember().

https://russian-dima.wixsite.com/meinewebsite/blank-6
Old but gold :grin:

Yes, ‘verifyRegistration’ is the ID of email template I created. I changed the ID for the eamil template for easier reference. Am I missing out on anything?

This is to send email to current member; I need to send it to a contact who is a member we just registered with pending status. So, it will have to be emailContact withing triggeredEmails for me.

What you are trying to achieve is a E-Mail-Verification process after a member has signed-up on your site, becomming a member? This is correct?

Your setup-flow should look like…

  1. User enters your site.
  2. User starts the sign-up-process.
  3. User fills in all needed user-data.
  4. User clicks the REGISTRATION-BUTTON → registration starts.
  5. Before all this happens → you have setted up your triggered-email and got the trigger-ID of that created e-mail in your case → (verifyRegistration).
  6. Inside of your triggered e-mail → you have setted-up the variables including the → VERIFICATION-TOKEN <— you want to send included inside the email, which will be sent to the user’s registered e-mail for → REGISTRATION-VERIFICATION-PROCESS.
  7. Email goes out to → user entered REGISTRATION-EMAIL.
  8. User open the recieved → VERIFICATION-EMAIL.
  9. Opening the e-mail → will lead the user to a specific CONFIRMATION-SITE (PAGE), where you have integrated some code for VERIFICATION-PROCESS.
  10. As soon the user has been navigated to the CONFIRMATION-PAGE → the CONFIRMATION-PROCESS starts automatically within → $w.onReady()
  11. Now the included CONFIRMATION-TOKEN, which has been **sent via URL-QUERY (by pressing the included BUTTON inside of the CONFIRMATION-EMAIL)**to your CONFIRMATION-PAGE will be used for CONFIRMATION.

Isn’t this what you are trying to achieve ?

Yes! Just one tiny edition (but the main reason why I am going this route) that the registration process gets triggered only for the user who meet certain minimum threshold score calculated based on their responses to custom fields on the front end.

Yes! Just one tiny edition (but the main reason why I am going this route) that the registration process gets triggered only for the user who meet certain minimum threshold score calculated based on their responses to custom fields on the front end.

Are you sure that you can change the template id? I didn’t know this is allowed

I will reply in few days. —> not enough free-time at moment sorry.

Yes, you can!

The problem got resolved for me. The issue was the user was not marked as subscriber, so system was not recognising the email as valid.

1 Like

No worries! The problem got resolved for me. The issue was the user was not marked as subscriber, so system was not recognising the email as valid.

1 Like