Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >通过GMAIL API从PHP站点发送电子邮件

通过GMAIL API从PHP站点发送电子邮件
EN

Stack Overflow用户
提问于 2018-08-12 08:40:17
回答 1查看 4.2K关注 0票数 0

我有一个PHP网站,我从那里发送通知电子邮件给我们的客户。电子邮件是从html表单发送的,在该表单中,我们从数据库生成正文、接收者等。

目前,电子邮件是使用以下代码通过PHP邮件函数发送的:

代码语言:javascript
运行
AI代码解释
复制
function SEND_MAIL($RECIPIENT,$EMAILSUBJECT,$EMAILBODY){
    $emailfrom = 'mail@blabla.com';
    $fromname = 'From name';
    $headers =
                'Return-Path: ' . $emailfrom . "\r\n" .
                'From: ' . $fromname . ' <' . $emailfrom . '>' . "\r\n" .
                'X-Priority: 3' . "\r\n" .
                'X-Mailer: PHP ' . phpversion() .  "\r\n" .
                'Reply-To: ' . $fromname . ' <' . $emailfrom . '>' . "\r\n" .
                'MIME-Version: 1.0' . "\r\n" .
                'Content-Transfer-Encoding: 8bit' . "\r\n" .
                'Content-Type: text/html; charset=ISO-8859-1' . "\r\n";
    $params = '-f ' . $emailfrom;
    $sendit = mail($RECIPIENT, $EMAILSUBJECT, $EMAILBODY, $headers, $params);
}

SEND_MAIL($CONTACTS_EMAIL,$EMAILSUBJECT_PERSON_A,$EMAILBODY_PERSON_A);

我们希望使用GMAIL API替换此函数,因为我们希望跟踪GMAIL帐户中已发送的邮件。我们使用Bluehost作为提供商,因此无法使用到GMAIL服务器的SMTP。我们在很多地方都在使用这个函数,所以如果可能的话,我们倾向于只修改这段代码。我花了几天的时间试着让它工作,最终我得到了一些结果。

到目前为止,我已经在谷歌开发人员控制台中配置了一切,我能够运行quickstart.php (如上所述的in this tutorial)。在本教程中,我们上传了JSON文件,并在设置了从GMAIL复制/粘贴的令牌后,可以访问gmail帐户的文件夹(标签)。

然后我可以使用我在网上找到的代码样本发送一封电子邮件

代码语言:javascript
运行
AI代码解释
复制
session_start();
 require __DIR__ . '/vendor/autoload.php';

  // Replace this with your Google Client ID
  $client_id     = 'blabla.apps.googleusercontent.com';
  $client_secret = 'secret';
  $redirect_uri  = 'https://www.redirecturl'; 

  $client = new Google_Client();
  $client->setClientId($client_id);
  $client->setClientSecret($client_secret);
  $client->setRedirectUri($redirect_uri);

  // We only need permissions to compose and send emails
  $client->addScope("https://www.googleapis.com/auth/gmail.compose");
  $service = new Google_Service_Gmail($client);

  // Redirect the URL after OAuth
  if (isset($_GET['code'])) {
    $client->authenticate($_GET['code']);
    $_SESSION['access_token'] = $client->getAccessToken();
    $redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
    header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
  }

  // If Access Toket is not set, show the OAuth URL
  if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
    $client->setAccessToken($_SESSION['access_token']);
  } else {
    $authUrl = $client->createAuthUrl();
  }

  if ($client->getAccessToken() && isset($_POST['message'])) {

    $_SESSION['access_token'] = $client->getAccessToken();

    // Prepare the message in message/rfc822
    try {

        // The message needs to be encoded in Base64URL
        $emailad=$_POST['emailad'];
        $username=$_POST['username'];
        $emailbody=$_POST['emailbody'];

        $strSubject = $_POST['subject'];

        $strRawMessage = "From: fromname <fromemail>\r\n";
        $strRawMessage .= "To: $username <$emailad>\r\n";
        $strRawMessage .= 'Subject: =?utf-8?B?' . base64_encode($strSubject) . "?=\r\n";
        $strRawMessage .= "MIME-Version: 1.0\r\n";
        $strRawMessage .= "Content-Type: text/html; charset=utf-8\r\n";
        $strRawMessage .= 'Content-Transfer-Encoding: quoted-printable' . "\r\n\r\n";
        $strRawMessage .= "$emailbody\r\n";

        $mime = rtrim(strtr(base64_encode($strRawMessage), '+/', '-_'), '=');
        $msg = new Google_Service_Gmail_Message();
        $msg->setRaw($mime);
        $service->users_messages->send("me", $msg);
    } catch (Exception $e) {
        print($e->getMessage());
        unset($_SESSION['access_token']);
    }
  } ?>
 <? if ( isset ( $authUrl ) ) { ?>
  <a href="<?= $authUrl; ?>"><img src="google.png" title="Sign-in with Google" /></a>
 <? } else { ?>
  <form method="POST" action="">
    <textarea name="emailbody" required></textarea>
    <input type="email" required name="emailad">
    <input type="text"  required name="subject">
    <input type="text"  required name="username">
    <input type="submit" value="submit">
  </form>
<? } ?>

最后一种方法也需要来自google的令牌,并请求帐户访问。

因此,我们希望使用这两种方法中的一种来替换我们的SEND_MAIL函数。我还想知道是否有可能永远不会使访问令牌过期,这样如果我们允许访问一次,我们就永远不需要通过Gmail接受程序。

谢谢你的帮忙!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-12 13:43:28

没有办法获得不过期的访问令牌,但有一种方法可以获得所谓的刷新token。刷新令牌永远不会过期,直到您取消授权您的应用程序时才可用。

我使用了您提供的代码,经过一些小的调整和更改,我能够使用Google Gmail API发送一封电子邮件。唯一的缺点刷新令牌和原始访问令牌需要存储在数据库或文件中,以便Google PHP API可以查看令牌,但这限制了必须重新登录和重新授权您的应用程序的需要。

验证文件--此文件只能使用一次。它是在数据库中设置令牌。设置令牌后,您可以从服务器中删除此文件。

代码语言:javascript
运行
AI代码解释
复制
<?php
require '/var/www/html/vendor/autoload.php'; // For Google Client Composer

// Replace this with your Google Client ID
$client_id     = 'blabla.apps.googleusercontent.com';
$client_secret = 'secret';
$redirect_uri  = 'https://www.redirecturl'; 

$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->setAccessType('offline'); //Added for Refresh Token
$client->setApprovalPrompt('force'); //Added for Refresh Token

// We only need permissions to compose and send emails
$client->addScope("https://www.googleapis.com/auth/gmail.compose");

// Redirect the URL after OAuth
if (isset($_GET['code'])) {
  $client->authenticate($_GET['code']);
  $_SESSION['access_token'] = $client->getAccessToken();
}

// If Access Token is not set, show the OAuth URL
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
  $display = "display: none";
  $client->setAccessToken($_SESSION['access_token']);
} else {
  $authUrl = $client->createAuthUrl();
}

$access_token = $client->getAccessToken();

echo '<a href="'.$authUrl.'" style="'.$display.'">Authorize ME PLZ</a>';

if ($access_token != null) {
  echo "You're In!";
}

// Saves Access Token Into Database to be Used In SEND_MAIL function
$mysqli = new mysqli('servername', 'username', 'password', 'database');
$stmt = $mysqli->prepare("INSERT INTO refresh_token (refresh, original) VALUES (?, ?)");
$stmt->bind_param("ss", json_encode($access_token), json_encode($access_token)); // Updated to remove warning
$stmt->execute();
$stmt->close();
?>

SEND_MAIL函数--从数据库获取用于验证Gmail API的值:

代码语言:javascript
运行
AI代码解释
复制
<?php

require '/var/www/html/vendor/autoload.php';

   function SEND_MAIL($RECIPIENT,$EMAILSUBJECT,$EMAILBODY){

      //Get Refresh Token From Database set when running Authentication File
      $conn = new mysqli("servername", "username", "password", 'database');

      $sql = "SELECT * FROM refresh_token";
      $result = $conn->query($sql);
      if ($result->num_rows > 0) {
          while($row = $result->fetch_assoc()) {
             $token = $row['original'];
             $refresh_token = $row['refresh'];
          }
      }
      $conn->close();

      // Replace this with your Google Client ID
      $client_id     = 'blabla.apps.googleusercontent.com';
      $client_secret = 'secret';
      $redirect_uri  = 'https://www.redirecturl'; 

      $client = new Google_Client();
      $client->setClientId($client_id);
      $client->setClientSecret($client_secret);
      $client->setRedirectUri($redirect_uri);
      $client->addScope("https://www.googleapis.com/auth/gmail.compose");
      $client->setAccessType('offline');
      $client->setApprovalPrompt('force');

      $client->setAccessToken($token);

      if ($client->isAccessTokenExpired()) {
      $client->refreshToken($refresh_token);
      $newtoken = $client->getAccessToken();
      $client->setAccessToken($newtoken);
      }

      $service = new Google_Service_Gmail($client);

      $fromemail = "<the-email-you-want-to-send-from>@gmail.com";

      $strRawMessage = "From: Email <$fromemail> \r\n";
      $strRawMessage .= "To: <$RECIPIENT>\r\n";
      $strRawMessage .= 'Subject: =?utf-8?B?' . base64_encode($EMAILSUBJECT) . "?=\r\n";
      $strRawMessage .= "MIME-Version: 1.0\r\n";
      $strRawMessage .= "Content-Type: text/html; charset=utf-8\r\n";
      $strRawMessage .= 'Content-Transfer-Encoding: quoted-printable' . "\r\n\r\n";
      $strRawMessage .= "$EMAILBODY\r\n";
      $mime = rtrim(strtr(base64_encode($strRawMessage), '+/', '-_'), '=');
      $msg = new Google_Service_Gmail_Message();
      $msg->setRaw($mime);
      $service->users_messages->send("me", $msg);
   }

   SEND_MAIL('test@me.com', 'Test', 'Hey!');

   ?>
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51807161

复制
相关文章
Flutter教程app
截图 前言 使用Flutter开发Flutter教程,<-_<-有点意思! 功能 夜间模式、文字大小、文字方向、设备切换 部件属性配置 示例代码查看 目前'基础部件','MD部件'可食用 支持代码块左右拖拽 更多功能,敬请期待 下载地址 https://www.coolapk.com/apk/197700
rhyme_lph
2018/09/13
1.5K0
Flutter教程app
ChatGPT们都在用哪些域名?
.chat 点击前往 .chat 首年注册仅售10元 .shop |.art 点击前往 .shop |.art等域名批量注册优惠中 说到AI,随着ChatGPT的风靡,各类AI工具、APP以及相关网站仿佛雨后春笋一般,瞬间遍布互联网的各个角落。 但其实不然,无论是OpenAI、IBM、谷歌等众多企业早已布局积累多年,比如1997年IBM深蓝击败国际象棋冠军卡斯帕罗夫;2012年AlexNet横扫ImageNet榜单;2016年AlphaGo击败李世石,大量的AI公司早已剑拔弩张。众多的AI类公司并非一
腾讯云DNSPod团队
2023/05/17
8140
ChatGPT们都在用哪些域名?
Flutter Web - 优雅的兼容 Flutter App 代码
与上文一脉相承,上文展示了如何使用 Flutter UI 绘制 Web 页面的架构形态。
Swift社区
2022/12/12
1.7K0
Flutter Web - 优雅的兼容 Flutter App 代码
Flutter App架构:领域模型
你是不是曾经在代码里把UI、业务逻辑、网络请求混在一个类里,看起来像一锅大杂烩?我也这样做过 ✋。总而言之,APP开发是困难的。像领域驱动设计Domain-Driven Design (DDD) 之类的书可以帮助我们开发复杂的软件工程项目。DDD的核心是model,是我们要解决的问题需要掌握的重要知识和概念。一个好的领域模型是决定一个项目成功或失败的重要因素。模型很重要,但也不会脱离系统。最简单的app也需要一些UI(就是用户所看到好)和与服务端的接口交互,用来获取有意义的信息。
用户1974410
2022/09/20
1.6K0
Flutter App架构:领域模型
Flutter Lesson 4: Flutter组件之App布局组件
首先来看一下我怎么来学习Flutter,我要了解每一个组件,同时,这又是一个App,所以,我的目标是直接生产一个App,里面就是对Flutter组件的介绍,同时写上一些demo以及源代码,这一个点子源于React Native With Code这一款App,在我学习React Native的时候给予了我很大的帮助。如果要构建这样的一款App,我需要先构建一个App首页,包含了一个可以滚动的列表,如果可以,还可以添加一些其他的组件。以及基础的布局组件。
踏浪
2019/07/31
1.8K0
Flutter Lesson 4: Flutter组件之App布局组件
60个DevOps开源工具,你在用哪些?
你喜欢免费的东西吗?获得开发者社区支持的自动化,开源的工具是大家梦寐以求的。这里列举了 60 多款最棒的开源工具,可以帮助你很好的实行 DevOps。 一、开发工具 版本控制&协作开发 1.版本控制系
马哥linux运维
2018/11/30
1.1K0
60个DevOps开源工具,你在用哪些?
60个DevOps开源工具,你在用哪些?
运维行业正在变革,推荐阅读:30万年薪Linux运维工程师成长魔法 你喜欢免费的东西吗?获得开发者社区支持的自动化,开源的工具是大家梦寐以求的。这里列举了 60 多款最棒的开源工具,可以帮助你很好的实
小小科
2018/05/04
2K0
60个DevOps开源工具,你在用哪些?
60个DevOps开源工具,你在用哪些?
你喜欢免费的东西吗?获得开发者社区支持的自动化,开源的工具是大家梦寐以求的。这里列举了 60 多款最棒的开源工具,可以帮助你很好的实行 DevOps。 一、开发工具 版本控制&协作开发 1.版本控制系
小小科
2018/09/28
8690
开源项目——FLutter开发录音APP
一个录音小工具,github地址,https://github.com/ThinkerJack/flutter_record。
思想者杰克
2021/11/04
1.8K0
Why is Flutter a Good Choice for App Development?
Recently, Flutter app development has become a new easy, and productive way to create applications. Lots of the teams considering it as a possible technology for the next project, which is no surprise, since it has advantages of the native framework while being cross-platform. In this article, we will focus on how Flutter development is different in general and how Flutter mobile development for iOS works in particular.
用户8617680
2021/05/13
5430
Why is Flutter a Good Choice for App Development?
强大的Flutter App升级功能
应用程序升级功能是App的基础功能之一,如果没有此功能会造成用户无法升级,应用程序的bug或者新功能老用户无法触达,甚至损失这部分用户。
老孟Flutter
2020/09/11
2.3K0
Flutter--Flutter中Widget、App的生命周期
  在App的开发过程中,我们通常都需要了解App以及各个页面的生命周期,方便我们在App进入前台时启动一些任务,在进入后台后暂停一些任务。同时,各个页面的生命周期也很重要,每个页面消失时要做一些内存清理、计时器清除、通知清除等操作。所以,本文主要就是学习一下在flutter开发App的时候,如何去怼App以及各个页面的生命周期进行监听和回调。
mukekeheart
2021/02/02
3.1K0
Go语言 | 哪些大公司在用go语言?
Go大概09年面世以来,已经8年了,也算是8年抗战。在这8年中,已经有很多公司开始使用Go语言开发自己的服务,甚至完全转向Go开发,也诞生了很多基于Go的服务和应用,比如Dokcer、k8s等,现在我们看下,有哪些大公司在用Go语言了。
飞雪无情
2018/08/28
4.6K0
flutter接入现有的app详细介绍
接入的方式,我是参考的官方的介绍文档,我这里尝试的是android的接入方式,还算比较顺利。
老码小张
2018/08/14
2.6K1
在 Flutter App 中使用相机和图库/flutter的图像选择[Flutter专题12]
接下来,我们需要配置设置。对于Android平台,不需要任何东西。对于 iOS,打开在 ios/Runner 文件夹下找到的 Info.plist 文件,然后添加以下键。
徐建国
2021/11/30
1.6K0
Flutter携程App_08_Flutter水平垂直滚动列表ListView
本节代码利用Flutter的ListView组件实现垂直/水平方向滚动的列表,效果图如下:
码农帮派
2020/04/01
1.2K0
Flutter携程App_08_Flutter水平垂直滚动列表ListView
【专业技术】还有人在用Qt开发app嘛?
编者按: 这个世界不缺工程师,但是缺大师。如果在Qt里写个app,传统做法,需要熟悉API,熟悉C++,熟悉Qt本身的实现,同时还要熟悉编程环境。 现在出现了一种类似于脚本Javascript的语言,利用它,我们可以少编写一些程序逻辑。可不,最近我就利用它开发出了个浏览器。大家都没有。 欢迎来到声明式UI语言QML的世界.在本入门教程中,我们使用QML创建一个简单的文本编辑器.阅读这个教程后,就可以使用QML和Qt C++开发应用程序了. 安装 首先需要安装包含Qt Quick的Qt最新版本,现在是Qt4.
程序员互动联盟
2018/03/14
4.8K0
【专业技术】还有人在用Qt开发app嘛?
点击加载更多

相似问题

ExternalException: GDI+中发生一般错误

20

位图保存gdi+中发生一般错误

12

GDI+中发生一般错误。如何修复?

110

asp.net : GDI+中发生一般错误

22

保存映像时发生一般的GDI+错误

11
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档