Ir para conteúdo
  • Cadastre-se

dev botao

Envio de Email outlook


Ver Solução Respondido por guilhermekm,

Recommended Posts

  • Membros Pro
1 minuto atrás, Patrick Alves disse:

Acho que pode ser porque vc colocou o app para produção... acredito que a verificação é o processo que eles fazem pra certificar que é vc mesmo... Ainda não coloquei um app em produção... kkkk

Se voltar o app para teste acho que não vai ter mais a verificação...

Pra não ter erro nos testes que fiz eu coloquei o scopo global https://mail.google.com/

Eu vou tentar fazer de várias formas, com ele em produção, homologação, em tudo.

Valter Patrick

Gerente de Projetos na empresa CTEC

(33)98400-0936

GitHub: https://github.com/valterpatrick

Link para o comentário
Compartilhar em outros sites

24 minutos atrás, valterpatrick disse:

o arquivo "Configuração OAUTH Gmail.pdf", que é o passo a passo que eu segui para criar as credenciais

No seu passo a passo acredito ser necessário colocar o scopo, em tese vc tem que dar permissão pra alguma coisa, inclusive na tela de consentimento aparece a descrição dos acessos para os quais o usuário deve consentir

Link para o comentário
Compartilhar em outros sites

  • Membros Pro
4 minutos atrás, Patrick Alves disse:

No seu passo a passo acredito ser necessário colocar o scopo, em tese vc tem que dar permissão pra alguma coisa, inclusive na tela de consentimento aparece a descrição dos acessos para os quais o usuário deve consentir

Ai vem a grande dúvida, quais escopos tenho de colocar para enviar email?
Eu coloquei apenas "https://www.googleapis.com/auth/gmail.send" que é o que preciso, ou seja, apenas enviar email.
Não sei se é necessário colocar outros e quando seleciona uma opção mais ampla, eu tenho de fazer esta autenticação lá do Google que me pede video do youtube e não sei mais o que.

Valter Patrick

Gerente de Projetos na empresa CTEC

(33)98400-0936

GitHub: https://github.com/valterpatrick

Link para o comentário
Compartilhar em outros sites

  • Membros Pro
Em 04/10/2024 at 17:56, Márcio Baroni disse:

Escopo para Gmail no OAuth2 :

https://mail.google.com/ openid

 

Eu não achei este escopo, achei o https://mail.google.com/ sem o openid.
No caso que preciso apenas enviar e-mail, como ficaria?
No caso, como ficou o seu?

 

Valter Patrick

Gerente de Projetos na empresa CTEC

(33)98400-0936

GitHub: https://github.com/valterpatrick

Link para o comentário
Compartilhar em outros sites

  • Membros Pro
Agora, Márcio Baroni disse:

Bom dia @valterpatrick

esse é o escopo "https://mail.google.com/ openid" que uso para mandar e-mail do gmail com aouth2, o openid é para autenticação de usuário que o Google/Microsoft usam...

Estou utilizando credenciais "App para computador" e não marquei o escopo na tela de permissão oauth, só enviei o escopo na requisição e cliquei para permitir, obtive o Access Token e Refresh Token, mas está dando o erro:

Erro: SMTP Error: Unable to send Mail data.
503 5.5.1 specifications. 41be03b00d2f7-7e9f6c4a1c1sm4122261a12.81 - gsmtp

Referência:
https://support.google.com/a/answer/3726730?hl=pt-BR

Valter Patrick

Gerente de Projetos na empresa CTEC

(33)98400-0936

GitHub: https://github.com/valterpatrick

Link para o comentário
Compartilhar em outros sites

Boa tarde, Robson não consegui fazer funcionar, não sei o que fiz de errada, quando tento passar o email ocorre este erro: Não foi possível atender à sua solicitação, unauthorized_client: The client does not exist or is not enabled for consumers. If you are the application developer, configure a new application through the App Registrations in the Azure Portal at https://go.microsoft.com/fwlink/?linkid=2083908

qualquer coisa eu posto como fiz. Obrigado

Link para o comentário
Compartilhar em outros sites

Em 07/10/2024 at 09:25, valterpatrick disse:
Erro: SMTP Error: Unable to send Mail data.
503 5.5.1 specifications. 41be03b00d2f7-7e9f6c4a1c1sm4122261a12.81 - gsmtp

Boa tarde Valter!

Estava fazendo uns testes com outras contas do google aqui e me deparei com uma situação. A conta em questão era de desenvolvedor e não conta do gmail, dava erro ao tentar enviar e debugando percebi que o login no smtp não tinha sido feito, porém o componente indicava sucesso e tentava fazer o envio da mensagem. No google quando acontece erro no login do outh devemos responder um code challenge para capturarmos todas as mensagens.

Fiz algumas modificações no componente para contornar isso... logo posto o fonte aqui.

@RobsonLopes consegui enviar com essas configurações:

[Email]
[email protected]
FromName=Patrick
Host=smtp-mail.outlook.com
Port=587
[email protected]
Pass=strongpassword
TLS=Sim

[OAuth2]
AccessTokenUrl=https://login.microsoftonline.com/common/oauth2/v2.0/token
AuthorizationTokenUrl=https://login.microsoftonline.com/common/oauth2/v2.0/authorize
ClientId=seuclientid
ClientSecret=deixe em branco
RedirectURI=http://127.0.0.1:1500
Scope=https://outlook.office.com/SMTP.Send offline_access

Link para o comentário
Compartilhar em outros sites

  • Membros Pro
2 minutos atrás, Patrick Alves disse:

Boa tarde Valter!

Estava fazendo uns testes com outras contas do google aqui e me deparei com uma situação. A conta em questão era de desenvolvedor e não conta do gmail, dava erro ao tentar enviar e debugando percebi que o login no smtp não tinha sido feito, porém o componente indicava sucesso e tentava fazer o envio da mensagem. No google quando acontece erro no login do outh devemos responder um code challenge para capturarmos todas as mensagens.

Fiz algumas modificações no componente para contornar isso... logo posto o fonte aqui.

Em relação a criação das credenciais no google?
Muda alguma coisa?
Como você fez o seu?

 

Valter Patrick

Gerente de Projetos na empresa CTEC

(33)98400-0936

GitHub: https://github.com/valterpatrick

Link para o comentário
Compartilhar em outros sites

8 minutos atrás, valterpatrick disse:

Em relação a criação das credenciais no google?
Muda alguma coisa?
Como você fez o seu?

No caso o email de teste cadastrado no app era de desenvolvedor e não tinha o gmail associado. Só removi esse email e utilizei outro.

Editado por Patrick Alves
Link para o comentário
Compartilhar em outros sites

2 horas atrás, ornei disse:

unauthorized_client: The client does not exist or is not enabled for consumers. If you are the application developer, configure a new application through the App Registrations in the Azure Portal at https://go.microsoft.com/fwlink/?linkid=2083908

Parece que o Cliente ID que vc configurou no componente não existe. Verifica também se cadastrou corretamente o app no azure, quando cadastrei aqui segui essas orientações: https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app?tabs=client-secret. Em Supported account types eu selecionei Accounts in any organizational directory and personal Microsoft accounts e em configure platforms Mobile and desktop applications

Link para o comentário
Compartilhar em outros sites

  • Membros Pro
29 minutos atrás, Patrick Alves disse:

No caso o email de teste cadastrado no app era de desenvolvedor e não tinha o gmail associado. Só removi esse email e utilizei outro.

No meu caso o email de desenvolvedor e do app é o mesmo, eu tenho de fazer diferente?

Valter Patrick

Gerente de Projetos na empresa CTEC

(33)98400-0936

GitHub: https://github.com/valterpatrick

Link para o comentário
Compartilhar em outros sites

Pessoal eu acabei alterando o nome de algumas propriedades e métodos para seguir o padrão (inglês) adotado para o componente. Vai quebrar o código de alguém, mas achei que o melhor momento é agora que ainda não foi adicionado ao repositório. Desculpa ai!!!

Alterações realizadas:

* Mudar eventos de autenticação (antes e depois) para ACBrMail;
* Alterar a classe Autenticador (SubComponent) para propriedade de classe (Persistent);
* Alterar o nome da classe Autenticador para Authenticator (seguir padrão de nomenclatura)
* Alterar o nome da property ExpiraEm para ExpiresIn (seguir padrão de nomenclatura);
* Alterar as propriedades RefreshToken, AccessToken e ExpiresIn para leitura e escrita;
* Alterar o nome do método AutorizacaoInterativa para InteractiveAuthentication (seguir padrão de nomenclatura);
* Alterar o nome do método AtualizarAccessToken para GetAccessToken (seguir padrão de nomenclatura);
* Adicionar propriedade ChallengeError para indicar se deve responder quando o login não é realizado com sucesso;
* Adicionar método GetChallengeError para responder quando o login não é realizado com sucesso;
* Corrigir identificação do login realizado (se for ESMTP, usuário e senha estiver informado, deve ser verificado SMTP.AuthDone);
* Adicionar mensagem de erro decodificando o retorno quando não for possível realizar o login;
* Enviar resposta com ChallengeError para capturar erros adicionais;
* Alterar mensagens do tratamento de erros para inglês (seguir padrão de mensagens de erros);

(unit1 é do exemplo)

unit1.pas unit1.dfm ACBrMail.pas

  • Obrigado 2
Link para o comentário
Compartilhar em outros sites

  • Membros Pro
3 minutos atrás, Patrick Alves disse:

Pessoal eu acabei alterando o nome de algumas propriedades e métodos para seguir o padrão (inglês) adotado para o componente. Vai quebrar o código de alguém, mas achei que o melhor momento é agora que ainda não foi adicionado ao repositório. Desculpa ai!!!

Alterações realizadas:

* Mudar eventos de autenticação (antes e depois) para ACBrMail;
* Alterar a classe Autenticador (SubComponent) para propriedade de classe (Persistent);
* Alterar o nome da classe Autenticador para Authenticator (seguir padrão de nomenclatura)
* Alterar o nome da property ExpiraEm para ExpiresIn (seguir padrão de nomenclatura);
* Alterar as propriedades RefreshToken, AccessToken e ExpiresIn para leitura e escrita;
* Alterar o nome do método AutorizacaoInterativa para InteractiveAuthentication (seguir padrão de nomenclatura);
* Alterar o nome do método AtualizarAccessToken para GetAccessToken (seguir padrão de nomenclatura);
* Adicionar propriedade ChallengeError para indicar se deve responder quando o login não é realizado com sucesso;
* Adicionar método GetChallengeError para responder quando o login não é realizado com sucesso;
* Corrigir identificação do login realizado (se for ESMTP, usuário e senha estiver informado, deve ser verificado SMTP.AuthDone);
* Adicionar mensagem de erro decodificando o retorno quando não for possível realizar o login;
* Enviar resposta com ChallengeError para capturar erros adicionais;
* Alterar mensagens do tratamento de erros para inglês (seguir padrão de mensagens de erros);

(unit1 é do exemplo)

unit1.pas 17.07 kB · 0 downloads unit1.dfm 33.08 kB · 0 downloads ACBrMail.pas 45.3 kB · 0 downloads

Vou tentar fazer os testes agora.

Valter Patrick

Gerente de Projetos na empresa CTEC

(33)98400-0936

GitHub: https://github.com/valterpatrick

Link para o comentário
Compartilhar em outros sites

  • Membros Pro
15 horas atrás, Patrick Alves disse:

Pessoal eu acabei alterando o nome de algumas propriedades e métodos para seguir o padrão (inglês) adotado para o componente. Vai quebrar o código de alguém, mas achei que o melhor momento é agora que ainda não foi adicionado ao repositório. Desculpa ai!!!

Alterações realizadas:

* Mudar eventos de autenticação (antes e depois) para ACBrMail;
* Alterar a classe Autenticador (SubComponent) para propriedade de classe (Persistent);
* Alterar o nome da classe Autenticador para Authenticator (seguir padrão de nomenclatura)
* Alterar o nome da property ExpiraEm para ExpiresIn (seguir padrão de nomenclatura);
* Alterar as propriedades RefreshToken, AccessToken e ExpiresIn para leitura e escrita;
* Alterar o nome do método AutorizacaoInterativa para InteractiveAuthentication (seguir padrão de nomenclatura);
* Alterar o nome do método AtualizarAccessToken para GetAccessToken (seguir padrão de nomenclatura);
* Adicionar propriedade ChallengeError para indicar se deve responder quando o login não é realizado com sucesso;
* Adicionar método GetChallengeError para responder quando o login não é realizado com sucesso;
* Corrigir identificação do login realizado (se for ESMTP, usuário e senha estiver informado, deve ser verificado SMTP.AuthDone);
* Adicionar mensagem de erro decodificando o retorno quando não for possível realizar o login;
* Enviar resposta com ChallengeError para capturar erros adicionais;
* Alterar mensagens do tratamento de erros para inglês (seguir padrão de mensagens de erros);

(unit1 é do exemplo)

unit1.pas 17.07 kB · 4 downloads unit1.dfm 33.08 kB · 4 downloads ACBrMail.pas 45.3 kB · 5 downloads

Amigo, muito obrigado.
Deu super certo.

Apenas sugiro que altere esta parte no seu código na unit.pas:

Use GetAccessToken ao invés de InteractiveAuthentication, pois no InteractiveAuthentication ele limpa os campos de token, já no GetAccessToken ele utiliza o InteractiveAuthentication e já retorna o campo certinho.

procedure TForm1.btnConsentimentoClick(Sender: TObject);
const
  msg = 'Será solicitado ao usuário permissão para enviar emails em seu nome.' +
  'O código retornado será armazenado para futura solicitação do token de acesso';
var
  IniFile: string;
  Ini: TIniFile;
begin
  Application.MessageBox(msg, 'Informação', 64);
  AjustaParametrosDeEnvio;
  
  //Antes:
  {ACBrMail1.Authenticator.InteractiveAuthentication;}
  //Depois:
  ACBrMail1.Authenticator.GetAccessToken;

  // ACBrMail1.Authenticator.AuthorizeToken contem o codigo de autorização para solicitar access token
  // Apos autorização atualizar tokens de acesso inválidos
  IniFile := ChangeFileExt(Application.ExeName, '.ini');
  Ini := TIniFile.Create(IniFile);
  try
    Ini.WriteString('OAuth2', 'RefreshToken', ACBrMail1.Authenticator.RefreshToken);
    Ini.WriteString('OAuth2', 'AccessToken', ACBrMail1.Authenticator.AccessToken);
    Ini.WriteDateTime('OAuth2', 'ExpiraEm', ACBrMail1.Authenticator.ExpiresIn);
  finally
    Ini.Free;
  end;
end;

 

Eu vou tentar agora com o Hotmail

 

  • Curtir 1

Valter Patrick

Gerente de Projetos na empresa CTEC

(33)98400-0936

GitHub: https://github.com/valterpatrick

Link para o comentário
Compartilhar em outros sites

4 horas atrás, valterpatrick disse:

Use GetAccessToken ao invés de InteractiveAuthentication, pois no InteractiveAuthentication ele limpa os campos de token, já no GetAccessToken ele utiliza o InteractiveAuthentication e já retorna o campo certinho.

Se usarmos GetAccessToken e a propriedade AccessToken estiver informada não vai ser chamado InteractiveAuthentication. A ideia do botão é justamente pedir o consentimento do usuário mesmo que em algum momento no passado já tenha sido feito isso, por isso que InteractiveAuthentication limpa os tokens, os que estavam informados não são mais válidos com o novo consentimento.

Se ainda não foi dado consentimento, GetAccessToken vai fazer todo o processo. ACBrMail.Send já chama GetAccessToken capturando o AccessToken, mesmo que InteractiveAuthentication não faça todo processo e se InteractiveAuthentication ainda não foi chamado, GetAccessToken chama ele pra vc.

Acho interessante por exemplo, na tela onde configura os parâmetros para envio do email colocar o botão chamando InteractiveAuthentication. No uso do programa para enviar os emails vai ser chamado ACBrMail.Send que chama GetAccessToken que se encarrega de obter ou atualizar o AccessToken. Supondo que no futuro vc precise alterar um scopo ou a chave secreta no seu app, é só o usuário ir nos parâmetros e clicar no botão para pedir o consentimento novamente e tudo volta a funcionar.

Link para o comentário
Compartilhar em outros sites

  • Consultores
Em 09/10/2024 at 17:47, Patrick Alves disse:

Pessoal eu acabei alterando o nome de algumas propriedades e métodos para seguir o padrão (inglês) adotado para o componente. Vai quebrar o código de alguém, mas achei que o melhor momento é agora que ainda não foi adicionado ao repositório. Desculpa ai!!!

Alterações realizadas:

* Mudar eventos de autenticação (antes e depois) para ACBrMail;
* Alterar a classe Autenticador (SubComponent) para propriedade de classe (Persistent);
* Alterar o nome da classe Autenticador para Authenticator (seguir padrão de nomenclatura)
* Alterar o nome da property ExpiraEm para ExpiresIn (seguir padrão de nomenclatura);
* Alterar as propriedades RefreshToken, AccessToken e ExpiresIn para leitura e escrita;
* Alterar o nome do método AutorizacaoInterativa para InteractiveAuthentication (seguir padrão de nomenclatura);
* Alterar o nome do método AtualizarAccessToken para GetAccessToken (seguir padrão de nomenclatura);
* Adicionar propriedade ChallengeError para indicar se deve responder quando o login não é realizado com sucesso;
* Adicionar método GetChallengeError para responder quando o login não é realizado com sucesso;
* Corrigir identificação do login realizado (se for ESMTP, usuário e senha estiver informado, deve ser verificado SMTP.AuthDone);
* Adicionar mensagem de erro decodificando o retorno quando não for possível realizar o login;
* Enviar resposta com ChallengeError para capturar erros adicionais;
* Alterar mensagens do tratamento de erros para inglês (seguir padrão de mensagens de erros);

(unit1 é do exemplo)

unit1.pas 17.07 kB · 19 downloads unit1.dfm 33.08 kB · 17 downloads ACBrMail.pas 45.3 kB · 21 downloads

Muito obrigado pela contribuição

Adicionei no nosso backlog (TK-6112).

Assim que possível daremos um retorno.

  • Curtir 2

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.

The popup will be closed in 10 segundos...