I already developed applicaton for google app script that can send email messages, but right now there is a need for me to send gtalk chat/xmpp message to user from my script.
my question is, is it possible for me to send gtalk chat/xmpp message directly from google app script? if it is not possible then is there any work around about this?
Basically, there are two types of messages you can automate through the App script.
Synchronous: building a boot that can respond to user inputs.
Asynchronous: specified trigger-based messaging systems. like submitting a google form or time-based.
Let's talk about Asynchronous
You can do it by Using incoming webhooks.
Create a Google Chart Room > Create a webhook URL. click_here
Use this Code:
function myFunction() {
var WebWhooklink = "PEST_YOUR_WEBHOOK_URL_HERE"
var message = { text: "Hello Chat"};
var payload = JSON.stringify(message);
var options = {
method: 'POST',
contentType: 'application/json',
payload: payload
};
var response = UrlFetchApp.fetch(WebWhooklink, options ).getContentText();
}
There is no built-in support for sending Google Chat messages. You can file a feature request on the issue tracker.
If you are able to make HTTP requests to external services from with in a google app script then you might be able to use an HTTP to XMPP gateway such as this:
http://chatmongers.com/blog/introducing-the-chatmongershttp-to-xmpp-gateway/
There would be a number of constraints you may still have to work through. The most common one being that privacy extensions block all messages from users that are not in the destination user's roster, but that's going to be a problem no matter how you manage to get XMPP messages sent.
Related
With the Google Apps Script Google Workspace services is it possible to forward a message as an attachment rather than just the normal forward as described here - https://developers.google.com/apps-script/reference/gmail/gmail-message#forwardrecipient?
Edit: I need this to work on the currently viewed message. Something similar to this:
function onGmailMessageOpen(e) {
const message = GmailApp.getMessageById(e.messageMetadata.messageId);
message.forward("abc#def.com");
}
where onGmailMessageOpen is the contextualTrigger function.
You can't directly forward a message as attachment by using Google Apps Script only
As a workaround I suggest you to use extra services and the following code:
function forwardAsAttachment() {
var messageRaw = Gmail.Users.Messages.get("email#example.com", "IDexample", {format: "raw"});
var message = Utilities.newBlob(messageRaw.raw, "message/rfc822", "Subject");
MailApp.sendEmail("recipient#example.com", "Title", "Body", {
attachments: [message]
});
}
First of all I added the Gmail API service into the project and retrieved the desired message in order to get the RAW message.
Then I created a Blob formatted as RFC822 which is the raw message expected by the service and then sent the message formatted and base64URL encoded.
References
Gmail API in Google Apps
MailApp
Utilities
We're using Gsuite Enterprise/Piazzaweb at work. I'm using basic scripts to get information from my own mailbox, no problems there. But I want to pull information from a couple of shared mailboxes in which I'm delegated. For example billing#mycompany.com. But I can't find any information regarding this and if it's even possible to reach a delegated mailbox with App script.
I've been sending e-mails from the delegated mailbox with app script without any problem.
Hopefully somebody can tell me more about this.
Thanks in advance.
In order to use Service Accounts in Apps Script, you have to do the following:
Build the OAuth service for your Service Account with the following library: OAuth2 for Apps Script.
Call the corresponding API by making the corresponding HTTP request via UrlFetchApp.fetch(url, params).
1. Build the OAuth service:
Once you have added the specified library to your script, you have to do this in order to build the OAuth service with delegated credentials, :
const PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----\nxxxxxxxxxxxxxxxxxxxxx\n-----END PRIVATE KEY-----\n';
const CLIENT_EMAIL = 'xxxxxxxxxxxxxxxxxxxxx.iam.gserviceaccount.com'; // Service account email
const USER_EMAIL = 'email_address_to_impersonate'; // Account to impersonate
const SCOPE = 'https://www.googleapis.com/auth/gmail.readonly' // Change according to your preferences
function getGmailService() {
return OAuth2.createService('Gmail: ' + USER_EMAIL)
.setTokenUrl('https://oauth2.googleapis.com/token')
.setPrivateKey(PRIVATE_KEY)
.setIssuer(CLIENT_EMAIL)
.setSubject(USER_EMAIL)
.setPropertyStore(PropertiesService.getScriptProperties())
.setScope(SCOPE);
}
Where PRIVATE_KEY refers to the key found in the Service Account JSON credentials, CLIENT_EMAIL is the Service Account email, and USER_EMAIL refers to the email address whose INBOX you want to access.
It's important to note that SCOPE should be one of the scopes you specified when delegating authority.
2. Access the API:
Once the OAuth service is built, you use it to retrieve an access token with which you can access the desired resource. Of course, GmailApp service and the Advanced Gmail Service won't be of use here, since you have to access the API using the service you just built. Because of this, the way to access the API will be making the corresponding HTTP request via UrlFetch.
I'm not sure what you want to do exactly, and the exact request would depend on that, but for example, if you wanted to list the messages from the impersonated user, you could do this:
function readInbox() {
var service = getGmailService();
console.log(service.getAccessToken());
if (service.hasAccess()) {
var url = 'https://www.googleapis.com/gmail/v1/users/me/messages';
var response = UrlFetchApp.fetch(url, {
headers: {
Authorization: 'Bearer ' + service.getAccessToken()
}
});
var result = JSON.parse(response.getContentText());
console.log(JSON.stringify(result, null, 2));
}
}
Note:
I'm assuming here that you have already created a Service Account and granted domain-wide authority, and that your issue was just using it in Apps Script.
In Gmail API Reference, check the HTTP request, Parameters and Request body sections corresponding to the API method you want to use, if you need information on how to make the HTTP request (URL to access, HTTP method, request parameters, etc.).
Reference:
OAuth2 for Apps Script
Apps Script OAuth2 > GoogleServiceAccount.gs
You cant use delegation from apps script as apps script doesn't support using service accounts. You would need to make an oauth2 flow and have that user authorize it. Answer provided by #Zig Mandel
On top of what #ZigMandel said: unless this is a google domains or google for work account to my knowledge you cant use service accounts with gmail. you need to use Oauth2. Answer provided by #DalmTo
I don't know if this would solve the problem, but a feature request has been placed on Google Cloud Community and on Google Issue Tracker to enable access to Gmail Apps Script add-ons from delegated mailboxes.
The more upvotes, the more chances Google seriously looks at this issue ;).
I deployed a Google Apps Script Web App which uses a service account to access the Google Directory. I deployed it that everyone has access to the app and that the app runs under the user executing it.
I would like to trigger this web app by calling the POST trigger from another app script which is part of a Google form. Something like this:
function onPost(){
var data = {
'name': 'Bob Smith',
'age': 35,
'pets': ['fido', 'fluffy']
};
var options = {
'method' : 'post',
'contentType': 'application/json',.
'payload' : JSON.stringify(data)
};
var resp = UrlFetchApp.fetch('https://script.google.com/a/my.domain.com/m.../exec', options);
}
However, I get back:
Exception: Request failed for https://script.google.com returned code 401.
When I try to use the GET trigger with some query parameters the response back looks like a google sign in page.
How can I trigger my web app from another app script all in the same domain?
Updated code with token:
function onPost(){
var token = ScriptApp.getOAuthToken();
var data = {
'name': 'Bob Smith',
'age': 35,
'pets': ['fido', 'fluffy']
};
var options = {
'headers':'Bearer '+token,
'method' : 'post',
'contentType': 'application/json',.
'payload' : JSON.stringify(data)
};
var resp = UrlFetchApp.fetch('https://script.google.com/a/my.domain.com/m.../exec', options);
}
The response back looks like a Google sign-in page
This is because you received the 401 Unauthorized HTTP status code prompting you that the request should contain valid user credentials. Since Google primarily uses OAuth 2.0, you will need to include an Authorization header set to Bearer YourTokenHere.
As of recently, the OAuth token can be obtained via getOAuthToken(), which will contain a claim in its payload that will match scopes granted to the application that is making the request (either automatically or explicitly).
You can also use the official OAuth 2.0 library if you need more fine-grained control over token management, or build from scratch if you feel like it, the Utilities class has everything you need for generating a custom JWT.
I deployed it that everyone has access to the app and that the app runs under the user executing it
Web Apps have several deployment modes across two permission settings:
"Execute the app as"
Me
User accessing the web app
"Who has access to the app"
Only myself
Anyone
Anyone, even anonymous
Google won't let you just strip the security and expose a public API (which is a good thing), so if you want everyone to be able to access your Web App without authorization, you will have to authorize the script yourself and let your users access the application under your authority.
Only one combination of options allows you to do that:
Execute as me, access to anyone, even anonymous
I am trying to set up a chron job to connect to the instagram API, grab 'my feed' and download the images. I cannot get past the OAuth 2.0 step. I have already looked at a number of resources including:
How to authorize with oauth 2.0 from appscript to Google APIs? - methods are deprecated and I cannot get the pop up to for the oauth to show up.
https://code.google.com/p/google-apps-script-issues/issues/detail?id=2580 and all the links that follow in the discussion. I cannot figure out how to apply this to work without an html page.
http://www.googleappsscript.org/home/downloading-instagram-photos-to-your-google-drive-using-google-apps-script works well for hash tags, but I would like to be able to get the feed from my user account.
Any help would be greatly appreciated, this is the best I have been able to figure out, if I could get the pop up to work I would be good to go, but I cannot.
function startInstagram () {
var redurl = getCallbackURL(getInstagram);
var consumerKey = '#######';
var consumerSecret = '#######';
var parameters = {
method : 'post',
payload:
'grant_type=authorization_code'+'&client_id='+consumerKey+'&client_secret='+consumerSecret+'&grant_type=authorization_code&redirect_uri='+redurl+'&response_type=token'
};
var token = UrlFetchApp.fetch('https://api.instagram.com/oauth/authorize/', parameters).getContentText();
Logger.log(['token', token]);
}
function getInstagram (vars) {
var res = {};
Logger.log(['get', vars]);
return;
}
function getCallbackURL(callbackFunction) {
var scriptUrl = 'https://script.google.com/d/<ID>';
var urlSuffix = '/usercallback?state=';
var stateToken = ScriptApp.newStateToken()
.withMethod(callbackFunction)
.withTimeout(60*10*5)
.createToken();
return scriptUrl + urlSuffix + stateToken;
}
There is a GitHub repository that describes a library for using OAuth2 in Apps Script. In its README file, it shows how to use the library with Drive API as an example. If you substitute the Instagram API for Drive in the example code, you should be close to what you need.
The Instagram API Authorization docs covers most of what you'll need to do to get an access token -- the steps parallel the instructions in the GitHub library.
You'll need to make sure your script is a registered application with Instagram so you can get the client ID and client secret and so you can set the redirect URI, which will be of the form
https://script.google.com/macros/d/{PROJECT KEY}/usercallback
for Apps Scripts.
If you are only interested in downloading your photos, the basic scope permissions (granted by default) should be sufficient.
Once you have a valid access token, you should be able to make requests from the Instagram API using UrlFetchApp.fetch().
URL: https://script.google.com/a/macros/MyDomain.com/s/MyProjectId/exec
To trigger the doGet() inside my Google Script, with URL:
Success: Manually Input above Url in the browser.
Failure: Fetch by Google Script UrlFetchApp.fetch(URL)
Is Fetch by program not allowed for Google Script's URL? Or have I made any stupid mistake?
I have tried to fetch by post method also to test doPost(), but got same result.
N.B.I have added my domain & script.google.com into APIs & auth/Push, and handled OAuth. No more authorization popup. So suppose not these issues.
~~~~~~~~~~~~~~~~~~~~~~~~~
Some people say this problem come from Google Apps's security in front of doGet() & doPost(). But after testing, it is failure no matter I run it on personal Gmail account or Google Apps account, and no matter run it as Developer, Domain users or Anonymous Anyone. Below is the demo code, without including the lengthy standard authorization code.
var REDIRECT_URL = 'https://script.google.com/macros/s/.../exec';
var SysEmail = "EmailAddress";
function doGet(e) {
MailApp.sendEmail(SysEmail, 'Test', 'doGet has received Push Notification');
}
//Running below function should trigger above doGet() theoretically, but not actually.
function TestGetByManual(){
var payload =
{
"kind" : "Test",
};
var options =
{
"method" : "get",
"followRedirects" : true,
"payload" : payload
};
var vResult = UrlFetchApp.fetch(REDIRECT_URL, options);
//vResult is Google's Login page.
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
After latest testings, I find that Google behave like this:
Since Google's security is so strong, setting parameter "followRedirects" to true is helpless. When Fetch meet Google before doGet() or doPost(), it will be stopped due to Authority reviewing. If it is fetched by manual (e.g. users' installation through browser), an authorization window will be pop-up (esp. if doGet() include authorization code inside). But if it is fetched by another App like my case, everything seems stop and doGet() and its authorization code will never be called!
The only workaround is: If I can set the App to execute as me and accessible by Anonymous, then there will be no Authority checking and everything go directly. Unluckily, even ignoring security issue, only personal Gmail account can make this setting. I, using Google Apps account, cannot make this "Anonymous" setting.
If authorization code will be called, I think there is still hope. But if my testing result is correct and no authorization code will be called before stop, I believe it is a dead corner.
The case here is still better. If the caller is not a controllable custom function, but an uncontrollable system function like Drive.changes.watch(), everything will be further helpless. (See my another post, which is my ultimate goal: Use Google Script's Web App as Webhook to receive Push Notification directly)
If any senior here can contact Google's Arun Nagarajan, really please help get a confirmation from him.
Works fine for me with the following code:
var REDIRECT_URL = 'https://script.google.com/macros/s/AKf.../exec';
var SysEmail = "anemail";
function doGet(e) {
MailApp.sendEmail(SysEmail, 'Test', 'doGet has received Push Notification');
}
function TestGetByManual(){
var vResult = UrlFetchApp.fetch(REDIRECT_URL);
Logger.log(vResult);
}
Make sure you save a new version and re-publish the webapp with that version and using the correct published url.