FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour New FWH 25.01
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
New FWH 25.01
Posted: Wed Feb 19, 2025 08:16 AM
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 1096
Joined: Fri Oct 28, 2005 02:27 AM
Re: New FWH 25.01
Posted: Wed Feb 19, 2025 08:30 AM

What are the minimum Windows version required to run programs created with FWH+[x]Hb nowadays?

FWH 11.08/FWH 19.12

BCC5.82/BCC7.3

xHarbour/Harbour
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: New FWH 25.01
Posted: Wed Feb 19, 2025 08:38 AM

Dear Hua,

Not sure if we still support Windows 7

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 300
Joined: Wed Jul 11, 2007 11:06 AM
Re: New FWH 25.01
Posted: Wed Feb 19, 2025 03:14 PM

Hi

What about this :

We will provide support for the oAuth2 on the next version FWH

with samples to send e-mail using GMail/Outlook(Office365).

Thanks,

Philippe

Posts: 7317
Joined: Thu Oct 18, 2012 07:17 PM
Re: New FWH 25.01
Posted: Thu Feb 20, 2025 08:35 AM
Jack wrote: Hi
What about this :
We will provide support for the oAuth2 on the next version FWH
with samples to send e-mail using GMail/Outlook(Office365).

Thanks,

Philippe
I think it is an initiative by laiton maybe antonio is not aware
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: New FWH 25.01
Posted: Thu Feb 20, 2025 09:35 AM
Jack wrote: Hi
What about this :
We will provide support for the oAuth2 on the next version FWH
with samples to send e-mail using GMail/Outlook(Office365).

Thanks,

Philippe
It is coming. We will publish an updated FWH 25.01 asap.
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 104
Joined: Tue Feb 09, 2021 04:20 PM
Re: New FWH 25.01
Posted: Sun Feb 23, 2025 04:31 PM

My mix works with FWH 25.01

Many thanks.

José M. C. Quintas Brazil

gtwvg, fivewin 25.12, hwgui, mingw 15.2 (32 bits)

Posts: 231
Joined: Fri Jul 20, 2012 01:49 AM
Re: New FWH 25.01
Posted: Tue Feb 25, 2025 06:45 PM
Hello everyone,

An example of how Harbour + FWH works with OAuth.


Here is a sample of the code.
Code Sample
#include "fivewin.ch"

static oGmail, hStore

function main()

	local oDlg
	local oName, cName := ""
	local oEmail, cEmail := ""
	local oPhoto, oSend
	local oConnect, oDisconnect

	hStore := readStore( hb_dirBase() + "gmail.json" )

	oGmail := TGmail():new()

	oGmail:setConfig( {;
		"client_id" => "your_client_id",;
		"client_secret" => "your_client_secret",;
		"redirect_uri" => "http://localhost:2025/";
	} )

	if !empty( hStore[ "token" ] )
		oGmail:setToken( hStore[ "token" ] )
	endif

	define dialog oDlg resource "GMAIL"

		redefine image oPhoto id 4002 of oDlg
		redefine say oName var cName id 4003 of oDlg
		redefine say oEmail var cEmail id 4004 of oDlg

		redefine button oDisconnect id 4005 of oDlg action onDisconnect( oDlg, { oPhoto, oName, oEmail, oSend, oDisconnect }, { oConnect } )
		redefine button oSend id 4006 of oDlg action onSendMail()

		redefine button oConnect id 4001 of oDlg action onConnect( oDlg, { oPhoto, oName, oEmail, oSend, oDisconnect }, { oConnect } )

		oDlg:bStart := { || updateControls( oDlg, { oPhoto, oName, oEmail, oSend, oDisconnect }, { oConnect } ) }

		oDlg:lHelpIcon := .f.

	activate dialog oDlg centered

	saveStore( hb_dirBase() + "gmail.json", hStore )

return nil

function onConnect( oDlg, aConnect, aDisconnect )

	local cToken

	if !oGmail:isAuth()
		cToken := oGmail:auth()
		if !empty( cToken )
			hStore[ "token" ] := cToken
		else
			msgStop( "Authentication failed!" )
		endif
	endif

	updateControls( oDlg, aConnect, aDisconnect )

return nil

function onDisconnect( oDlg, aConnect, aDisconnect )

	local cProfile := hb_dirBase() + "profile_gmail.jpg"

	oGmail:revoke()
	updateControls( oDlg, aConnect, aDisconnect )

	if hb_vfExists( cProfile )
		hb_vfErase( cProfile )
	endif

return nil

function onSendMail()

	if oGmail:send( "lailton@paysoft.com.br", "it is a test", "<b>Message from Gmail oAuth2</b>", .t., {} )
		msgInfo( "Mail sent!" )
	else
		msgStop( "Failed to send email. You may not have authorized the required permissions..." )
	endif

return nil

function updateControls( oDlg, aConnect, aDisconnect )

	local hUser
	local cProfile := hb_dirBase() + "profile_gmail.jpg"

	if oGmail:isAuth()
		hUser := oGmail:me()
	endif

	aEval( aConnect, { |o| o:hide() } )
	aEval( aDisconnect, { |o| o:hide() } )

	if hb_isHash( hUser )

		aEval( aConnect, {|o|o:show(),o:refresh()} )

		if !hb_vfExists( cProfile )
			oGmail:downloadUrl( hUser[ "picture" ], cProfile )
		endif

		// Load Profile Photo
		if hb_vfExists( cProfile )
			aConnect[1]:loadImage(, cProfile )
			aConnect[1]:refresh()
		endif

		aConnect[2]:setText( hUser[ "name" ] )
		aConnect[3]:setText( hUser[ "email" ] )

		aConnect[2]:update()
		aConnect[3]:update()

	else

		aEval( aDisconnect, {|o|o:show(),o:refresh()} )

	endif

	oDlg:update()

return nil

function readStore( cFile )

	local hStore

	if hb_vfExists( cFile )
		hStore := hb_jsonDecode( hb_memoRead( cFile ) )
	endif

	if !hb_isHash( hStore )
		hStore := {;
			"token" => "";
		}
	endif

return hStore

function saveStore( cFile, hStore )

	hb_memoWrit( cFile, hb_jsonEncode( hStore ) )

return hb_vfExists( cFile )
It will be included in FiveWin today for the next version. :D
Regards,

Lailton Fernando Mariano
Posts: 1067
Joined: Wed Nov 09, 2005 02:17 AM
Re: New FWH 25.01
Posted: Tue Feb 25, 2025 06:51 PM

Hi Lailton

Is TGMAIL a new class ?

Sds,
Vilian F. Arraes
vilian@vfatec.com.br
Belém-Pa-Brazil
Posts: 231
Joined: Fri Jul 20, 2012 01:49 AM
Re: New FWH 25.01
Posted: Tue Feb 25, 2025 06:53 PM
vilian wrote:TGmail
Yes, It is TGmail. on the next days I will add too the version for Office365 following same idea.
Regards,

Lailton Fernando Mariano
Posts: 7317
Joined: Thu Oct 18, 2012 07:17 PM
Re: New FWH 25.01
Posted: Wed Feb 26, 2025 08:25 AM
Lailton wrote:
TGmail
Yes, It is TGmail. on the next days I will add too the version for Office365 following same idea.
I remember Cristobal made a Tgmail class some year ago

Have you tried this function ?

Make sure you have configured your application on Google Cloud Console and obtained the client_id, client_secret, and configured the redirect URL correctly.
#include "FiveWin.ch"

FUNCTION SendEmail()
   LOCAL cUrl, cData, cResponse
   LOCAL cAccessToken := "YOUR_ACCESS_TOKEN"  // Get token via OAuth2
   LOCAL cMessage := '{"message": {"subject": "Test Email", "body": {"contentType": "Text", "content": "Hello, this is a test email!"}, "toRecipients": [{"emailAddress": {"address": "example@domain.com"}}]}}'

   cUrl := "https://graph.microsoft.com/v1.0/me/sendMail"
   cData := cMessage

   cResponse := HttpPostRequest(cUrl, cData, "Authorization: Bearer " + cAccessToken)
   
   IF !Empty(cResponse)
      MsgInfo("Email sent successfully!", "Success")
   ELSE
      MsgError("Failed to send email.", "Error")
   ENDIF

RETURN
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
Posts: 7317
Joined: Thu Oct 18, 2012 07:17 PM
Re: New FWH 25.01
Posted: Wed Feb 26, 2025 08:52 AM
This is my Tgmail class Use oAuth2
CLASS Tgmail

   DATA cClientId // OAuth2 Client ID
   DATA cClientSecret // OAuth2 Client Secret
   DATA cRedirectUri // Redirect URI
   DATA cAccessToken // OAuth2 Access Token
   DATA cRefreshToken // OAuth2 Refresh Token
   DATA cAuthUrl // Authorization URL

   METHOD Init( cClientId, cClientSecret, cRedirectUri )
   METHOD GetAuthorizationUrl()
   METHOD GetAccessToken( cCode )
   METHOD SendEmail( cSubject, cBody, cRecipient )

ENDCLASS

// Constructor for Tgmail class
METHOD Init( cClientId, cClientSecret, cRedirectUri )
   ::cClientId := cClientId
   ::cClientSecret := cClientSecret
   ::cRedirectUri := cRedirectUri
   ::cAuthUrl := "https://accounts.google.com/o/oauth2/v2/auth?scope=https://www.googleapis.com/auth/gmail.send&response_type=code&redirect_uri=" + SELF:cRedirectUri + "&client_id=" + SELF:cClientId
   RETURN NIL

// Method to get the authorization URL
METHOD GetAuthorizationUrl()
   RETURN ::cAuthUrl

// Method to get access token using authorization code
METHOD GetAccessToken( cCode )
   LOCAL cUrl, cData, cResponse, cTokenUrl
   LOCAL aJson
   cTokenUrl := "https://oauth2.googleapis.com/token"
   cData := "code=" + cCode + ;
            "&client_id=" + ::cClientId + ;
            "&client_secret=" + ::cClientSecret + ;
            "&redirect_uri=" + ::cRedirectUri + ;
            "&grant_type=authorization_code"

   // Request to get the token
   cResponse := HttpPostRequest( cTokenUrl, cData, "" )
   IF !Empty(cResponse)
      
      aJson := JsonParse( cResponse )
      ::cAccessToken := aJson[ "access_token" ]
      ::cRefreshToken := aJson[ "refresh_token" ]
      RETURN .T.
   ELSE
      RETURN .F.
   ENDIF

// Method to send an email via GMail
METHOD SendEmail( cSubject, cBody, cRecipient )
   LOCAL cUrl, cMessage, cRaw, cResponse

   // Prepare the message in MIME format
   cRaw := "From: 'me'\r\n" + ;
           "To: " + cRecipient + "\r\n" + ;
           "Subject: " + cSubject + "\r\n" + ;
           "Content-Type: text/plain; charset=UTF-8\r\n\r\n" + ;
           cBody

   // Encode the message in base64
   cRaw := Base64Encode( cRaw )

   // Build the request body
   cMessage := '{"raw": "' + cRaw + '"}'

   // URL to send the message
   cUrl := "https://gmail.googleapis.com/upload/gmail/v1/users/me/messages/send?uploadType=multipart"

   // Send HTTP request with access token
   cResponse := HttpPostRequest( cUrl, cMessage, "Authorization: Bearer " + ::cAccessToken )
   IF !Empty(cResponse)
      RETURN .T.
   ELSE
      RETURN .F.
   ENDIF

RETURN NIL

SAMPLES
First of all, you need to create an object of the Tgmail class and initialize it with the authentication data.
LOCAL oGmail
oGmail := Tgmail():New()
// Initialize with the client_id, client_secret and redirect_uri obtained from Google Console
oGmail:Init( "YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET", "YOUR_REDIRECT_URI" )

You can get the authorization URL to visit to get the authorization code.
LOCAL cAuthUrl
cAuthUrl := oGmail:GetAuthorizationUrl()
MsgInfo( "Visita questo URL per autorizzare l'app: " + cAuthUrl, "Autorizzazione OAuth2" )

Once the user has authorized the app and you have received the authorization code, you can get the access_token.
LOCAL cCode, lSuccess
cCode := "AUTHORIZATION_CODE_OBTAINED_FROM_USER"  // Ottieni il codice di autorizzazione
lSuccess := oGmail:GetAccessToken( cCode )
IF lSuccess
   MsgInfo( "Token di accesso ottenuto!", "Successo" )
ELSE
   MsgError( "Errore durante l'ottenimento del token.", "Errore" )
ENDIF

Once you have the access_token, you can send an email.
LOCAL lSuccess
lSuccess := oGmail:SendEmail( "Test Email", "Ciao, questa è una prova di invio email!", "recipient@example.com" )
IF lSuccess
   MsgInfo( "Email inviata con successo!", "Successo" )
ELSE
   MsgError( "Errore durante l'invio dell'email.", "Errore" )
ENDIF
You will need some auxiliary functions like HttpPostRequest and Base64Encode. Here is an example of how you could implement them:

// Function to perform an HTTP POST request
FUNCTION HttpPostRequest( cUrl, cData, cHeaders )
   LOCAL cResponse
   cResponse := HttpPost( cUrl, cData, cHeaders )
   RETURN cResponse
//Function to encode in base64
FUNCTION Base64Encode( cData )
   RETURN HB_BASE64ENCODE( cData )


This Tgmail class allows you to integrate with GMail via OAuth2, getting the access token and using it to send emails. Make sure you configure your application correctly on Google Cloud Console and manage the OAuth2 authorization flow.
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
Posts: 7317
Joined: Thu Oct 18, 2012 07:17 PM
Re: New FWH 25.01
Posted: Wed Feb 26, 2025 09:06 AM
My Office365 class

The Tgmail class I provided is specifically for integrating with the GMail API via OAuth2,
so it would not work directly for Office 365 (Outlook). However,

we can adapt it to also work with Office 365 (Microsoft Graph API),
which is the official API for interacting with Microsoft services, including Outlook and OneDrive.

Authentication via OAuth2:

To get the access_token, you will need to configure your application in the Azure Portal,
similar to how you did for GMail.
Microsoft Graph uses a similar authentication flow to GMail
but with different URLs and parameters.
Sending an email via Microsoft Graph:

The HTTP request to send the email will be directed to a different
URL than GMail, namely https://graph.microsoft.com/v1.0/me/sendMail.

Adapting the Tgmail class for Office 365 (Microsoft Graph API)
Below I show you how you can adapt the Tgmail class for Office 365.

The new class will be called Toffice365.

With this Toffice365 class, you can integrate your application with Office 365 (Microsoft Outlook) via OAuth2,
get an access_token,
and use it to send emails via the Microsoft Graph API.
CLASS Toffice365

   DATA cClientId // OAuth2 Client ID
   DATA cClientSecret // OAuth2 Client Secret
   DATA cRedirectUri // Redirect URI
   DATA cAccessToken // OAuth2 Access Token
   DATA cRefreshToken // OAuth2 Refresh Token
   DATA cAuthUrl // Authorization URL

   METHOD Init( cClientId, cClientSecret, cRedirectUri )
   METHOD GetAuthorizationUrl()
   METHOD GetAccessToken( cCode )
   METHOD SendEmail( cSubject, cBody, cRecipient )

ENDCLASS

// Constructor for Toffice365 class
METHOD Init( cClientId, cClientSecret, cRedirectUri )
   ::cClientId := cClientId
   ::cClientSecret := cClientSecret
   ::cRedirectUri := cRedirectUri
   ::cAuthUrl := "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?" + ;
                    "client_id=" + SELF:cClientId + ;
                    "&response_type=code" + ;
                    "&redirect_uri=" + SELF:cRedirectUri + ;
                    "&scope=Mail.Send"
   RETURN NIL

// Method to get the authorization URL
METHOD GetAuthorizationUrl()
   RETURN ::cAuthUrl

// Method to get access token using authorization code
METHOD GetAccessToken( cCode )
   LOCAL cUrl, cData, cResponse, cTokenUrl
   LOCAL aJson
   cTokenUrl := "https://login.microsoftonline.com/common/oauth2/v2.0/token"
   cData := "code=" + cCode + ;
            "&client_id=" + SELF:cClientId + ;
            "&client_secret=" + SELF:cClientSecret + ;
            "&redirect_uri=" + SELF:cRedirectUri + ;
            "&grant_type=authorization_code"

   // Request to get the token
   cResponse := HttpPostRequest( cTokenUrl, cData, "" )
   IF !Empty(cResponse)
      
      aJson := JsonParse( cResponse )
      ::cAccessToken := aJson[ "access_token" ]
      ::cRefreshToken := aJson[ "refresh_token" ]
      RETURN .T.
   ELSE
      RETURN .F.
   ENDIF

// Method to send an email via Office 365 (Microsoft Graph)
METHOD SendEmail( cSubject, cBody, cRecipient )
   LOCAL cUrl, cMessage, cRaw, cResponse

   // Prepara il messaggio in formato MIME
   cRaw := '{"message": {' + ;
           '"subject": "' + cSubject + '",' + ;
           '"body": {"contentType": "Text", "content": "' + cBody + '"},' + ;
           '"toRecipients": [{"emailAddress": {"address": "' + cRecipient + '"}}]' + ;
           '}}'

   // URL to send message via Microsoft Graph
   cUrl := "https://graph.microsoft.com/v1.0/me/sendMail"

   // Send HTTP request with access token
   cResponse := HttpPostRequest( cUrl, cRaw, "Authorization: Bearer " + SELF:cAccessToken )
   IF !Empty(cResponse)
      RETURN .T.
   ELSE
      RETURN .F.
   ENDIF

RETURN NIL


SAMPLES as tgmail samples
LOCAL oOffice365
oOffice365 := Toffice365():New()

// Initializes with the client_id, client_secret and redirect_uri obtained from Azure Portal
oOffice365:Init( "YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET", "YOUR_REDIRECT_URI" )
LOCAL cAuthUrl
cAuthUrl := oOffice365:GetAuthorizationUrl()
MsgInfo( "Visita questo URL per autorizzare l'app: " + cAuthUrl, "Autorizzazione OAuth2" )
LOCAL cCode, lSuccess
cCode := "AUTHORIZATION_CODE_OBTAINED_FROM_USER"  // Codice di autorizzazione
lSuccess := oOffice365:GetAccessToken( cCode )
IF lSuccess
   MsgInfo( "Token di accesso ottenuto!", "Successo" )
ELSE
   MsgError( "Errore durante l'ottenimento del token.", "Errore" )
ENDIF

LOCAL lSuccess
lSuccess := oOffice365:SendEmail( "Test Email", "Ciao, questa è una prova di invio email!", "recipient@example.com" )
IF lSuccess
   MsgInfo( "Email inviata con successo!", "Successo" )
ELSE
   MsgError( "Errore durante l'invio dell'email.", "Errore" )
ENDIF


Functions
// Funzione per eseguire una richiesta HTTP POST
FUNCTION HttpPostRequest( cUrl, cData, cHeaders )
LOCAL cResponse
cResponse := HttpPost( cUrl, cData, cHeaders )
RETURN cResponse
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)

I use : FiveWin for Harbour March-April 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
Posts: 114
Joined: Fri Jul 21, 2006 07:15 PM
Re: New FWH 25.01
Posted: Wed Apr 02, 2025 06:58 PM
Hi Silvio.
Do your class works with xHarbour too?
Regards and thanks.
Silvio.Falconi wrote: My Office365 class

The Tgmail class I provided is specifically for integrating with the GMail API via OAuth2,
so it would not work directly for Office 365 (Outlook). However,

we can adapt it to also work with Office 365 (Microsoft Graph API),
which is the official API for interacting with Microsoft services, including Outlook and OneDrive.

Authentication via OAuth2:

To get the access_token, you will need to configure your application in the Azure Portal,
similar to how you did for GMail.
Microsoft Graph uses a similar authentication flow to GMail
but with different URLs and parameters.
Sending an email via Microsoft Graph:

The HTTP request to send the email will be directed to a different
URL than GMail, namely https://graph.microsoft.com/v1.0/me/sendMail.

Adapting the Tgmail class for Office 365 (Microsoft Graph API)
Below I show you how you can adapt the Tgmail class for Office 365.

The new class will be called Toffice365.

With this Toffice365 class, you can integrate your application with Office 365 (Microsoft Outlook) via OAuth2,
get an access_token,
and use it to send emails via the Microsoft Graph API.
CLASS Toffice365

   DATA cClientId // OAuth2 Client ID
   DATA cClientSecret // OAuth2 Client Secret
   DATA cRedirectUri // Redirect URI
   DATA cAccessToken // OAuth2 Access Token
   DATA cRefreshToken // OAuth2 Refresh Token
   DATA cAuthUrl // Authorization URL

   METHOD Init( cClientId, cClientSecret, cRedirectUri )
   METHOD GetAuthorizationUrl()
   METHOD GetAccessToken( cCode )
   METHOD SendEmail( cSubject, cBody, cRecipient )

ENDCLASS

// Constructor for Toffice365 class
METHOD Init( cClientId, cClientSecret, cRedirectUri )
   ::cClientId := cClientId
   ::cClientSecret := cClientSecret
   ::cRedirectUri := cRedirectUri
   ::cAuthUrl := "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?" + ;
                    "client_id=" + SELF:cClientId + ;
                    "&response_type=code" + ;
                    "&redirect_uri=" + SELF:cRedirectUri + ;
                    "&scope=Mail.Send"
   RETURN NIL

// Method to get the authorization URL
METHOD GetAuthorizationUrl()
   RETURN ::cAuthUrl

// Method to get access token using authorization code
METHOD GetAccessToken( cCode )
   LOCAL cUrl, cData, cResponse, cTokenUrl
   LOCAL aJson
   cTokenUrl := "https://login.microsoftonline.com/common/oauth2/v2.0/token"
   cData := "code=" + cCode + ;
            "&client_id=" + SELF:cClientId + ;
            "&client_secret=" + SELF:cClientSecret + ;
            "&redirect_uri=" + SELF:cRedirectUri + ;
            "&grant_type=authorization_code"

   // Request to get the token
   cResponse := HttpPostRequest( cTokenUrl, cData, "" )
   IF !Empty(cResponse)
      
      aJson := JsonParse( cResponse )
      ::cAccessToken := aJson[ "access_token" ]
      ::cRefreshToken := aJson[ "refresh_token" ]
      RETURN .T.
   ELSE
      RETURN .F.
   ENDIF

// Method to send an email via Office 365 (Microsoft Graph)
METHOD SendEmail( cSubject, cBody, cRecipient )
   LOCAL cUrl, cMessage, cRaw, cResponse

   // Prepara il messaggio in formato MIME
   cRaw := '{"message": {' + ;
           '"subject": "' + cSubject + '",' + ;
           '"body": {"contentType": "Text", "content": "' + cBody + '"},' + ;
           '"toRecipients": [{"emailAddress": {"address": "' + cRecipient + '"}}]' + ;
           '}}'

   // URL to send message via Microsoft Graph
   cUrl := "https://graph.microsoft.com/v1.0/me/sendMail"

   // Send HTTP request with access token
   cResponse := HttpPostRequest( cUrl, cRaw, "Authorization: Bearer " + SELF:cAccessToken )
   IF !Empty(cResponse)
      RETURN .T.
   ELSE
      RETURN .F.
   ENDIF

RETURN NIL


SAMPLES as tgmail samples
LOCAL oOffice365
oOffice365 := Toffice365():New()

// Initializes with the client_id, client_secret and redirect_uri obtained from Azure Portal
oOffice365:Init( "YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET", "YOUR_REDIRECT_URI" )
LOCAL cAuthUrl
cAuthUrl := oOffice365:GetAuthorizationUrl()
MsgInfo( "Visita questo URL per autorizzare l'app: " + cAuthUrl, "Autorizzazione OAuth2" )
LOCAL cCode, lSuccess
cCode := "AUTHORIZATION_CODE_OBTAINED_FROM_USER"  // Codice di autorizzazione
lSuccess := oOffice365:GetAccessToken( cCode )
IF lSuccess
   MsgInfo( "Token di accesso ottenuto!", "Successo" )
ELSE
   MsgError( "Errore durante l'ottenimento del token.", "Errore" )
ENDIF

LOCAL lSuccess
lSuccess := oOffice365:SendEmail( "Test Email", "Ciao, questa è una prova di invio email!", "recipient@example.com" )
IF lSuccess
   MsgInfo( "Email inviata con successo!", "Successo" )
ELSE
   MsgError( "Errore durante l'invio dell'email.", "Errore" )
ENDIF


Functions
// Funzione per eseguire una richiesta HTTP POST
FUNCTION HttpPostRequest( cUrl, cData, cHeaders )
LOCAL cResponse
cResponse := HttpPost( cUrl, cData, cHeaders )
RETURN cResponse
FWH / xHarbour / BCC / MySql

Visual Studio / Harbour / DotNet Maui / C#
Posts: 284
Joined: Mon Oct 24, 2005 08:04 PM
Re: New FWH 25.01
Posted: Wed May 28, 2025 10:39 PM

Silvio,

Where can I get the HttpPost and JsonParse functions?

Thanks,

Randal

Continue the discussion