Giter Club home page Giter Club logo

Comments (13)

dstpierre avatar dstpierre commented on July 21, 2024 1

Yes, exactly, this issue is for adding a sendEmail function to the VM (~virtual machine) or runtime the server-side JavaScript function run into.

Server-side functions are not fully fledge JavaScript runtime, for instance, developers cannot import JavaScript library and so on, it's using JavaScript as a dynamic language to perform tasks that would have been not safe to do on the client-side code.

The ExecutionEnvironment exposes internal Go code to this runtime environment and allow the runtime to make those services available via functions callable from inside the runtime.

Example for the email function

err = vm.Set("sendMail", func(call goja.FunctionCall) goja.Value {
  //...
})

In the ExecutionEnvironment type you'll have to add the Emailer interface:

type ExecutionEnvironment struct {
  //...
  Volatile  cache.Volatilizer
  Email     email.Emailer
   //...
}

You can check the fetch function for inspiration on how to receive your parameters, because an object would be better than listing all required argument.

The email.SendMailData is what the Send method from the Emailer interface wants, so your runtime function could also accept this, for instance from a calling point-of-view:

// this is an example of how your helper function would be call inside a server-side- function
function handle() {
  sendMail({
    from: "[email protected]",
    to: "[email protected]",
    subject: "Your trial has expired",
    htmlBody: "<h1>Hello</h1>...",
    textBody: "Hello\n\n...",
  });
}

Something like that, your helper runtime function basically needs to do this:

  1. Parse the input (refer to the fetch example for a very similar one.
  2. Call the env.Email.Send() with the struc you've parsed in 1

To test, the quickest way like we said is to add a sendMail call in the functions_test.go and use the make test-core which you should see the output of the dev Emailer impl which prints to the console.

Let me know how it goes.

from core.

g41797 avatar g41797 commented on July 21, 2024

Hi

  • Is it urgent issue?
  • Is functions_test.go suitable for the testing?
  • What is your dev environment?

Thanks
@g41797

from core.

dstpierre avatar dstpierre commented on July 21, 2024

Hey @g41797 my answers:

Is it urgent issue?

No, I'm planning on releasing v1.5 in the following weeks, but this can be released later, say v1.5.1*

Is functions_test.go suitable for the testing?

Yes, you could either add your call to the sendEmail helper function in the existing function test or create a new one, it's up to you. While testing the dev EmailProvider is used, so it will print out the content of the email to the console. I suggest running make test-core or go test to see this output while testing.

What is your dev environment?

I've created a video here. Lately I've been using GitHub Codespaces sometimes which includes a PostgreSQL, MongoDB and Redis inside a Docker. When I ran Linux I had those locally, but now I had to run on Windows for accessibility reasons, and WSL2 and Docker are not the best match (for me at least). I tried Podman, which sometimes works and sometimes not.

Side note, the make alltest is currently not working since the implementation of the full-text search feature. But you'd be good with testing just the core.

I've recently implemented a SQLite data provider as well removing the need to have any other services installed, coupled with the memory Redis, it's easier to just git clone and start implementing.

Basically your steps are:

  1. git clone [email protected]:staticbackendhq/core.git
  2. Copy the .demo.env to .env -> cp .demo.env .env
  3. Edit .env to use your choice of database / redis

If you're going to use the PostgreSQL or Mongo setting, change the host to localhost if you're using Docker. Same for Redis

As an example, here's what I'm currently using as .env file, which uses SQLite and a memory mplementation instead of Redis and will print email to console instead of sending them:

APP_ENV=dev

APP_SECRET=a-very-long-key-should-be-32long

APP_URL=http://localhost:8099

# For PostgreSQL
#DATABASE_URL=host=localhost user=postgres password=postgres dbname=postgres sslmode=disable
#DATA_STORE=pg

# For MongoDB
# DATABASE_URL=mongodb://localhost:27017
# DATA_STORE=mongo

# For SQLite
DATABASE_URL=dev.db
DATA_STORE=sqlite

JWT_SECRET=changeMe
MAIL_PROVIDER=dev
STORAGE_PROVIDER=local
[email protected]
FROM_NAME=Your company
# REDIS_HOST=localhost:6379
REDIS_HOST=mem
REDIS_PASSWORD=
LOCAL_STORAGE_URL=http://localhost:8099

Once you have this file created you should be able to run make test-core as well as start the server with make start

Please look inside the Makefile if you're not using make to get those commands.

Hope that helps and let me know if you'd want me to assign this issue to you.

from core.

g41797 avatar g41797 commented on July 21, 2024

ok
next week i will get on board

from core.

g41797 avatar g41797 commented on July 21, 2024

i am on board
please assign #84 to me

Additional settings for testing under vscode:
Add .env path to launch.json

    {
        "name": "Launch test function",
        "type": "go",
        "request": "launch",
        "mode": "test",
        "program": "${workspaceFolder}/core/sendmail_test.go",
        "args": [
            "-test.run",
            "Test_Sendmail"
        ],
        "envFile": "/home/g41797/go/pkg/mod/github.com/staticbackendhq/core/_**.env**_"
    },

I submitted #93 for this case

make test-core

ERR error establishing PubSub subscription error="dial tcp: address mem: missing port in address"

After set REDIS_HOST=mem:6789 - error disappeared

make test-core
2023/05/25 15:55:21 constraint failed: UNIQUE constraint failed: sb_customers.email (2067)

make start
fatal: No names found, cannot describe anything.
May 25 16:01:05 INF server started Addr=http://localhost:8099
May 25 16:01:10 ERR error establishing PubSub subscription error="dial tcp: lookup mem: no such host"
May 25 16:01:10 ERR error establishing PubSub subscription error="dial tcp: lookup mem: no such host"

Looks something wrong with .env & my environment

APP_ENV=dev

APP_SECRET=a-very-long-key-should-be-32long

APP_URL=http://localhost:8099

For SQLite

DATABASE_URL=dev.db
DATA_STORE=sqlite

JWT_SECRET=changeMe
MAIL_PROVIDER=dev
STORAGE_PROVIDER=local
FROM_EMAIL=[email protected]
FROM_NAME=Your company

REDIS_HOST=mem:6789
REDIS_PASSWORD=
LOCAL_STORAGE_URL=http://localhost:8099

Possibly you can clarify the reason of the failure

from core.

dstpierre avatar dstpierre commented on July 21, 2024

Hey, I merged #91 which I believe will fixed the issue regarding the pubsub connection (adding the "mem" in the REDIS_HOST was good, but there was still an issue in the backend.Setup should be better now.

I'd do a git pull origin main and merge into your branch and retry the make test-core and the make start

Let me know how it goes.

from core.

dstpierre avatar dstpierre commented on July 21, 2024

Alos @g41797 I'm getting intermitant error for the sqlite implementation and running the test, error is "DATABASE IS BUSY".

For stability you might want to use either PostgreSQL or Mongo. The SQLite isn't released yet and seems to generates randon issues.

from core.

g41797 avatar g41797 commented on July 21, 2024

me2:
membership_test.go:63: HTTP Status:500 Internal Server Error Error:database is locked (5) (SQLITE_BUSY)

from core.

g41797 avatar g41797 commented on July 21, 2024

make test-core [postgres]
May 26 10:06:54 FTL failed to create connection with postgres error="dial tcp:
lookup db: no such host"

After change in .env:
DATABASE_URL=host=localhost port=5432 user=postgres password=postgres dbname=postgres sslmode=disable

make test-core:
PASS
github.com/staticbackendhq/core coverage: 13.9% of statements
ok github.com/staticbackendhq/core 6.390s

So i hope local environment is ready

Do i need also update .demo.env & CONTIBUTING.md ?

from core.

dstpierre avatar dstpierre commented on July 21, 2024

The .demo.env has host=db due to the name in the docker-compose-demo.yml`

This part is certainly confusing, I'll try to clarify this in the CONTRIBUTING.md no worries.

And yes, since make test-core passes, you're all set now.

from core.

g41797 avatar g41797 commented on July 21, 2024
http.Handle("/sudo/sendmail", middleware.Chain(http.HandlerFunc(sudoSendMail), stdRoot...))

[client]backend.SendMai ==> POST ..."/sudo/sendmail"... => [serversudoSendMail] ==> backend.Emailer.Send...

So send mail already exists for the client

"...ability to send email from server-side function" - ExecData

OK i got the point:

  • Server-side function is JS code dynamically uploaded to backend
  • JS code has possibility to call go functions registered in ExecutionEnvironment

Black magic done using goja

addHelpers - allows usage of go code via http request
addDatabaseFunctions - allows direct call

Please confirm or not confirm

from core.

g41797 avatar g41797 commented on July 21, 2024

"...at line:114 in the addHelpers function, we could expose the email function..."

As far as I understand, it's OK to add dedicated function addSendMail(...) and don't forget to call it within Execute(...)

	_, err = handler(goja.Undefined(), args...)
	go env.complete(err)
	if err != nil {
		return fmt.Errorf("error executing your function: %v", err)
	}

Looks check of err is obsolete

Existing SendMailData struct has more fields then
from:
to:
subject:
htmlBody:
textBody:
(FromName,ToName,ReplyTo,Body)
How to proceed?

Initialization of ExecutionEnvironment (backend.go):

		exe.Auth = auth
		exe.BaseName = conf.Name
		exe.DataStore = DB
		exe.Volatile = Cache
		exe.Search = Search
		exe.Email = Emailer

(where Email email.Mailer) - never called for TestFunctionsExecuteDBOperations at least if i called it as specific test
as result err := env.Email.Send(data) failed (Email is nil)

I added init of Email closer to execute:

   	env := &function.ExecutionEnvironment{
		Auth:      auth,
		BaseName:  conf.Name,
		DataStore: backend.DB,
		Data:      fn,
		Email:     backend.Emailer,
	}
type JSSendMailArg struct {
	From     string `json:"from"`
	To       string `json:"to"`
	Subject  string `json:"subject"`
	HTMLBody string `json:"htmlBody"`
	TextBody string `json:"textBody"`
}

btw json mapping doesn't exist in JSFetchOptionsArg

		sendMail({
			from: "[email protected]",
			to: "[email protected]",
			subject: "End test",
			htmlBody: "<h1>Bye</h1>...",
			textBody: "Bye\n\n...",
		  });

Result:

====== SENDING EMAIL ======
from:  [email protected]
ReplyTo:  
to:  [email protected]
subject:  End test
body
Bye

Created PR #95
Please review

from core.

dstpierre avatar dstpierre commented on July 21, 2024

#95 is merged, thank you.

from core.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.