Jump to content
IElite

Send an email ?

Recommended Posts

Just curious what the options are for sending an email from an SMS app?

I have some information gathered from a user and would like to email the data to a specific email account.

Has anyone implemented sending an email in their app yet?

Share this post


Link to post
Share on other sites

to send emails you need a server side provider (except when you're ok with using mailto: which directs the browser to use the main installed emailclient (if any).

all of the major parties provide an email api (google, amazon) which you can hook in to

Some of the not so major companies are emailjs.com, mailgun, smtpjs and probably many more. Their services are accessable from js based clients

or have your own server based on node (nodemailer) or php (mail)

I usually use a php solution as I have this installed and the script to use is really simple, but have used the Google api as well

 

Share this post


Link to post
Share on other sites

This is a 2-step process

1) see this post 

and follow at least the first steps. Basically establish the link between your app, googles api's and your gmail account.

For option 2a(below) you need at least an api-key and clientId, for option 2b you need the full oauth2 gamut including tokens

2) then do one of the following

2a) make use of Googles javascript client library for gmail 

<!DOCTYPE html>
<html>
  <head>
    <title>Send email using gmail API</title>
    <meta charset='utf-8' />
  </head>
  <body>
    <p>Send email using gmail API.</p>

    <!--Add buttons to initiate auth sequence and sign out-->
    <button id="authorize-button" style="display: none;">Authorize</button>
    <button id="signout-button" style="display: none;">Sign Out</button>

    <div id="content"></div>

    <script type="text/javascript">
      var apiKey = '********2qOeiRlg2humU4YifLyNqt2TrWR2kGk';
      var discoveryDocs = ["https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest"];
      var clientId = '********7354-7kp9br0phbsdfkcsilu660u7uq9p6tqs.apps.googleusercontent.com';
      var scopes = 'https://www.googleapis.com/auth/gmail.send';

      var authorizeButton = document.getElementById('authorize-button');
      var signoutButton = document.getElementById('signout-button');

      function handleClientLoad() {
        // Load the API client and auth2 library
        gapi.load('client:auth2', initClient);
      }
      function initClient() {
        gapi.client.init({
            apiKey: apiKey,
            discoveryDocs: discoveryDocs,
            clientId: clientId,
            scope: scopes
        }).then(function () {
          // Listen for sign-in state changes.
          gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
          // Handle the initial sign-in state.
          updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
          authorizeButton.onclick = handleAuthClick;
          signoutButton.onclick = handleSignoutClick;
        });
      }

      function updateSigninStatus(isSignedIn) {
        if (isSignedIn) {
          authorizeButton.style.display = 'none';
          signoutButton.style.display = 'block';
          makeApiCall();
        } else {
          authorizeButton.style.display = 'block';
          signoutButton.style.display = 'none';
        }
      }

      function handleAuthClick(event) {
        gapi.auth2.getAuthInstance().signIn();
      }

      function handleSignoutClick(event) {
        gapi.auth2.getAuthInstance().signOut();
      }

      // Load the API and make an API call.  Display the results
      function makeApiCall() {
        const message =
        "From: lynk@gmail.com\r\n" + 
        "To: nico@hotmail.com\r\n" +
        "Subject: Subject of this email\r\n\r\n" +
        "with body text here";

        // The body needs to be base64url encoded.
        const encodedMessage = btoa(message)
        //but google style, replacing a couple of characters extra
        const reallyEncodedMessage = encodedMessage.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')

        gapi.client.gmail.users.messages.send({
            userId: 'me',
            resource: {
                raw: reallyEncodedMessage
            }
        }).then(function () { console.log("done!")});
      }
    </script>
    <script async defer src="https://apis.google.com/js/api.js" 
      onload="this.onload=function(){};handleClientLoad()" 
      onreadystatechange="if (this.readyState === 'complete') this.onload()">
    </script>
  </body>
</html>

 

2b)

or make an ajax call (post) to https://www.googleapis.com/upload/gmail/v1/users/userId/messages/send 

and attach a "raw" parameter in the request body with the base64  encoded email as above.

 

I'll "Smart" both of these up a bit when time permits

 

 

Share this post


Link to post
Share on other sites

a "smarted" up example of sending gmails using the gmail client library (replaces html file of option 2a previous post)  

a form with 3 buttons (button1 : log in / button2: log out / button3 : send gmail)

....

var document external 'document': variant;
var console  external 'console':  variant;
var gapi     external 'gapi':     variant;

implementation

{ TForm1 }

procedure TForm1.InitializeForm;
begin
  inherited;
  // this is a good place to initialize components

  var Script := document.createElement('script');
  Script.src := 'https://apis.google.com/js/api.js';
  Script.setAttribute('async','');
  Script.setAttribute('defer','');
  document.head.appendChild(Script);
  Script.onload := procedure
  begin
    // Load the API client and auth2 library
    gapi.load('client:auth2', procedure
    begin
      gapi.client.init(class
        apiKey        = '********2qOeiRlg2humU4YifLyNqt2TrWR2kGk';
        discoveryDocs = ["https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest"];
        clientId      = '********7354-7kp9br0phbsdfkcsilu660u7uq9p6tqs.apps.googleusercontent.com';
        scope         = 'https://www.googleapis.com/auth/gmail.send';
      end);
    end);
  end;
end;

procedure TForm1.W3Button1Click(Sender: TObject);   //log in
begin
  gapi.auth2.getAuthInstance().signIn();
end;

procedure TForm1.W3Button2Click(Sender: TObject);   //log out
begin
  gapi.auth2.getAuthInstance().signOut();
end;

procedure TForm1.W3Button3Click(Sender: TObject);   // send gmail
begin
//
  asm
    const message =
    "From: from@gmail.com\r\n" +
    "To: to@hotmail.com\r\n" +
    "Subject: Subject of your email\r\n\r\n" +
    "with body of text here, separated by a blank line";

    // The body needs to be base64url encoded.
    const encodedMessage = btoa(message);

    //replace all + with -, replace all / with _, and remove the trailing = to make it URL-safe
    //const reallyEncodedMessage = encodedMessage.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')
    //problem : Smart compiler can't handle \ characters

    gapi.client.gmail.users.messages.send({
      userId: 'me',
      resource: {
        raw: encodedMessage      //should be : reallyEncodedMessage
      }
    }).then(function () { console.log("done")});
  end;
//
end;


 

 

Share this post


Link to post
Share on other sites

@lynkfs

I am trying your "smart" example out above

However, it is crashing on this part of the code. If I comment out this entire bit of code, then everything else compiles and runs fine.


      gapi.client.init(class
        apiKey        = '*****yAlr4k8Qkb8MpbjSbGBIi5h9067lZ4b5Cs';
        discoveryDocs = ["https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest"];
        clientId      = '*****3111041-b3sfpthnis4ofc94d4qg9eo93q9rd7co.apps.googleusercontent.com';
        scope         = 'https://www.googleapis.com/auth/gmail.send';
      end);

I am getting this error: 

Uncaught #<Object>  [line #103]

Yes, the astrisks are there to mask my keys , i am using my full key and clientId

 

if I comment out the ClientId and Scope, it will also compile and run without errors

gapi.client.init(class
        apiKey        = '*****yAlr4k8Qkb8MpbjSbGBIi5h9067lZ4b5Cs';
        discoveryDocs = ["https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest"];
        //clientId      = '*****3111041-b3sfpthnis4ofc94d4qg9eo93q9rd7co.apps.googleusercontent.com';
        //scope         = 'https://www.googleapis.com/auth/gmail.send';
      end);


However, if I uncomment just the clientId out of those two, then i get this message:

client_id and scope must both be provided to initialize OAuth.  [line #71]

so, then i uncomment the scope and again, i get the uncaught object error message

Share this post


Link to post
Share on other sites

Sorry, I guess that was the wrong terminology to use. I haven't yet actually tried to send an email. All i have done was to add the all the code you provided above, particularly the smart enabled code.  When I run my app , without sending the email, I get that error.  I can't delete the scope line because it will complain - as I stated above.  Not sure I can also delete the clientId ?  Do you think?

Share this post


Link to post
Share on other sites
2 hours ago, lynkfs said:

This api doesn't allow local execution (file:///C:/Users/.../www/index.html) but requires a http(s) based url (https://.../www/index.html)

so index.html / index.js needs to be server-side

Oh ok, so if I upload the project to my server, then it should work?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×