Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subscriber Check Feature - Frontend & Backend #670

Open
fullakingi opened this issue Nov 29, 2021 · 3 comments
Open

Subscriber Check Feature - Frontend & Backend #670

fullakingi opened this issue Nov 29, 2021 · 3 comments

Comments

@fullakingi
Copy link

fullakingi commented Nov 29, 2021

Hi @elitan - made progress on a feature for nhost that checks if an authorised user is on a table called subscribers.

  1. chose project at nhost back-end
  2. create a table called subscribed with the following fields:
  • id (UUID)
  • created_at (timestamp)
  • email (text)
  • subscribed(Boolean)
  1. to populate this table with subscribers we use mailchimp API.
    we set up a webhook " api-xxxxxx.nhost.app"

I am attaching the code for the back-end API:

it is in root/API/mailchimp

const http = require('https');

const graphQL = (query, variables) => {

  const options = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-hasura-admin-secret': process.env.NHOST_HASURA_ADMIN_SECRET     
    },
  };

  return new Promise((resolve, reject) => {
    const request = http.request(
      process.env.NHOST_HASURA_URL,
      options,
      res => {
        if (res.statusCode !== 200) {
          res.resume();
          reject(res.statusMessage);
        }
        res.setEncoding('utf8');
        let rawData = '';
        res.on('data', chunk => {rawData += chunk})
        res.on('end', () => {
          if (!res.complete) {
            reject('Aborted');
          }
          resolve(JSON.parse(rawData));
        });
      }
    );
    request.on('error', reject);
    request.write(JSON.stringify({
      query,
      variables
    }));
    request.end();
  });
};

module.exports = (req, res) => {
  if (req.body && req.body.type && req.body.data && req.body.data.email) {
    graphQL(`mutation ($email: String, $subscribed: Boolean) {
      insert_subscribed_one(
        object: {
          email: $email,
          subscribed: $subscribed
        }, on_conflict: {
          constraint: subscribed_email_key,
          update_columns: [subscribed]
        }) {
        id
      }
    }`, {
      email: req.body.data.email,
      subscribed: req.body.type === 'subscribe'
    }).then((data) => {
      res.writeHead(200, { 'Content-Type': 'text/plain' });
      res.end(JSON.stringify(data));
    }).catch(err => {
      res.writeHead(200, { 'Content-Type': 'text/plain' });
      res.end(err.toString());
    })
  } else {
    res.writeHead(200,  { 'Content-Type': 'text/plain' });
    res.end('Bad request data');
  }
} 

in the frontend (next js), we change the private route:

/* eslint-disable react-hooks/rules-of-hooks */
import { useRouter } from 'next/router'
import { useAuth } from '@nhost/react-auth'
import Image from 'next/image'
import { useQuery, gql } from '@apollo/client'
import { nhost } from '../utils/nhost'

const IS_SUBSCRIBED = gql`
query ($email: String) {
  subscribed(where: {
    email: {_eq: $email}
    subscribed: {_eq: true}
  } ) {
    subscribed
  }
}
`;

function PrivateRouteInternal(props) {
  const router = useRouter()
  const { loading, data } = useQuery(
    IS_SUBSCRIBED,
    {
      variables: {
        email: nhost.auth.user().email
      }
    }
  );
  console.log(nhost.auth.user().email);
  if (loading) {
    return <div className="flex items-center justify-center">
      <p className="text-sm">2. Checking registration status...</p>
      <div>
        <Image
          src="/loading.svg"
          alt="loading icon"
          width={100}
          height={100}
        />
      </div>
    </div>
  }
  console.log(JSON.stringify(data));

  if (!(data && data.subscribed && data.subscribed[0])) {
    setTimeout(() => { router.push('/onboard') }, 3000);
    return <div className="flex items-center justify-center">
      <p className="text-sm justify-center">Email address does not seem to be registered. Please complete registration on the next screen.</p>
      <div>
        <Image
          src="/loading.svg"
          alt="loading icon"
          width={100}
          height={100}
        />
      </div>
    </div>
  }

  return props.children[0];
}


export function PrivateRoute(Component) {
  return (props) => {
    const router = useRouter()
    const { signedIn } = useAuth()
    // wait to see if the user is logged in or not.
    if (signedIn === null) {
      return <div className="flex items-center justify-center">
        <p className="text-sm">1: Checking authorisation...</p>
        <Image
          src="/loading.svg"
          alt="loading icon"
          width={100}
          height={100}
        />
      </div>
    }

    if (!signedIn) {
      router.push('/login')
      return <div>Redirecting...</div>
    }

    return <PrivateRouteInternal><Component {...props} /></PrivateRouteInternal>;
  }
}

We are still refining the front-end private route file.

@elitan
Copy link
Contributor

elitan commented Nov 29, 2021

Hi @fullakingi, we're focusing all of our efforts at Nhost on Nhost v2 right now, which will come with a new serverless functions-service (instead of the current custom API).

I'd suggest waiting for Nhost v2 to make serverless functions on Nhost. We hope to have Nhost v2 publicly available in a few weeks from now.

@fullakingi
Copy link
Author

Ok. I don't have a choice as my client want the feature now as we have too many users.

Ok I look forward to seeing the serverless functions. Excited for Nhost V2. The API is easy for us now. It works fine for us.I just need to know if it will be a breaking change as it is critical for us to be prepared, or will you retain nhost V1 for legacy accounts?

@elitan
Copy link
Contributor

elitan commented Nov 30, 2021

Just to confirm, do you have any issue with the above-mentioned code? Or just wanted to provide the code as a reference for others to learn from?

Nhost v2 will have no effect on the current project being hosted on Nhost. They are separated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants