mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-28 18:01:36 +00:00
Merge branch 'main' of https://github.com/GAM-team/GAM
This commit is contained in:
@@ -4926,10 +4926,10 @@ gam print schema|schemas [todrive <ToDriveAttribute>*]
|
|||||||
gam sendemail [recipient|to] <RecipientEntity>
|
gam sendemail [recipient|to] <RecipientEntity>
|
||||||
[from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>]
|
[from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>]
|
||||||
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
[subject <String>] [<MessageContent>]
|
[subject <String>] [<MessageContent>] [html [<Boolean>]]
|
||||||
(replace <Tag> <String>)*
|
(replace <Tag> <String>)*
|
||||||
(replaceregex <RESearchPattern> <RESubstitution> <Tag> <String>)*
|
(replaceregex <RESearchPattern> <RESubstitution> <Tag> <String>)*
|
||||||
[html [<Boolean>]] (attach <FileName> [charset <Charset>])*
|
(attach <FileName> [charset <Charset>])*
|
||||||
(embedimage <FileName> <String>)*
|
(embedimage <FileName> <String>)*
|
||||||
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
@@ -4937,10 +4937,10 @@ gam sendemail [recipient|to] <RecipientEntity>
|
|||||||
gam <UserTypeEntity> sendemail recipient|to <RecipientEntity>
|
gam <UserTypeEntity> sendemail recipient|to <RecipientEntity>
|
||||||
[replyto <EmailAddress>]
|
[replyto <EmailAddress>]
|
||||||
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
[subject <String>] [<MessageContent>]
|
[subject <String>] [<MessageContent>] [html [<Boolean>]]
|
||||||
(replace <Tag> <String>)*
|
(replace <Tag> <String>)*
|
||||||
(replaceregex <RESearchPattern> <RESubstitution> <Tag> <String>)*
|
(replaceregex <RESearchPattern> <RESubstitution> <Tag> <String>)*
|
||||||
[html [<Boolean>]] (attach <FileName> [charset <Charset>])*
|
(attach <FileName> [charset <Charset>])*
|
||||||
(embedimage <FileName> <String>)*
|
(embedimage <FileName> <String>)*
|
||||||
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
@@ -4948,14 +4948,21 @@ gam <UserTypeEntity> sendemail recipient|to <RecipientEntity>
|
|||||||
gam <UserTypeEntity> sendemail from <EmailAddress>
|
gam <UserTypeEntity> sendemail from <EmailAddress>
|
||||||
[replyto <EmailAddress>]
|
[replyto <EmailAddress>]
|
||||||
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
[subject <String>] [<MessageContent>]
|
[subject <String>] [<MessageContent>] [html [<Boolean>]]
|
||||||
(replace <Tag> <String>)*
|
(replace <Tag> <String>)*
|
||||||
(replaceregex <RESearchPattern> <RESubstitution> <Tag> <String>)*
|
(replaceregex <RESearchPattern> <RESubstitution> <Tag> <String>)*
|
||||||
[html [<Boolean>]] (attach <FileName> [charset <Charset>])*
|
(attach <FileName> [charset <Charset>])*
|
||||||
(embedimage <FileName> <String>)*
|
(embedimage <FileName> <String>)*
|
||||||
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
[threadid <String>]
|
[threadid <String>]
|
||||||
|
gam <UserTypeEntity> sendreply
|
||||||
|
(((query <QueryGmail> [querytime<String> <Date>]*) [or|and])+) | (ids <MessageIDEntity>)
|
||||||
|
[replyto <EmailAddress>]
|
||||||
|
[subject <String>] [<MessageContent>] [html [<Boolean>]]
|
||||||
|
(attach <FileName> [charset <CharSet>])*
|
||||||
|
(embedimage <FileName> <String>)*
|
||||||
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
|
|
||||||
# Shared Drives - Administrator
|
# Shared Drives - Administrator
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,23 @@
|
|||||||
|
7.36.03
|
||||||
|
|
||||||
|
Added command to send email replies that causes Gmail to recognize the message
|
||||||
|
in conversation mode for the user sending the reply and the user receiving the reply;
|
||||||
|
GAM supplies the necessary headers and options.
|
||||||
|
```
|
||||||
|
gam <UserTypeEntity> sendreply
|
||||||
|
(((query <QueryGmail> [querytime<String> <Date>]*) [or|and])+) | (ids <MessageIDEntity>)
|
||||||
|
[replyto <EmailAddress>]
|
||||||
|
[subject <String>] [<MessageContent>] [html [<Boolean>]]
|
||||||
|
(attach <FileName> [charset <CharSet>])*
|
||||||
|
(embedimage <FileName> <String>)*
|
||||||
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
|
|
||||||
|
gam user user@domain.com sendreply query "rfc822MsgId:<CAAMmEdqj43...1OsQ@mail.gmail.com>" textmessage "Thanks for the information"
|
||||||
|
gam user user@domain.com sendreply ids 19cfc3506c02c22b textmessage "Thanks for the information"
|
||||||
|
```
|
||||||
|
|
||||||
|
* See: https://github.com/GAM-team/GAM/wiki/Send-Email#conversation-mode
|
||||||
|
|
||||||
7.36.02
|
7.36.02
|
||||||
|
|
||||||
Added option `threadid <String>` to `gam [<UserTypeEntity>] sendemail` that causes Gmail to recognize the message
|
Added option `threadid <String>` to `gam [<UserTypeEntity>] sendemail` that causes Gmail to recognize the message
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
||||||
__version__ = '7.36.02'
|
__version__ = '7.36.03'
|
||||||
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
||||||
|
|
||||||
# pylint: disable=wrong-import-position
|
# pylint: disable=wrong-import-position
|
||||||
@@ -7341,7 +7341,8 @@ def _addEmbeddedImagesToMessage(message, embeddedImages):
|
|||||||
# Send an email
|
# Send an email
|
||||||
def send_email(msgSubject, msgBody, msgTo, i=0, count=0, clientAccess=False, msgFrom=None, msgReplyTo=None,
|
def send_email(msgSubject, msgBody, msgTo, i=0, count=0, clientAccess=False, msgFrom=None, msgReplyTo=None,
|
||||||
html=False, charset=UTF8, attachments=None, embeddedImages=None,
|
html=False, charset=UTF8, attachments=None, embeddedImages=None,
|
||||||
msgHeaders=None, ccRecipients=None, bccRecipients=None, mailBox=None, threadId=None):
|
msgHeaders=None, ccRecipients=None, bccRecipients=None, mailBox=None, threadId=None,
|
||||||
|
action=Act.SENDEMAIL):
|
||||||
def checkResult(entityType, recipients):
|
def checkResult(entityType, recipients):
|
||||||
if not recipients:
|
if not recipients:
|
||||||
return
|
return
|
||||||
@@ -7397,12 +7398,13 @@ def send_email(msgSubject, msgBody, msgTo, i=0, count=0, clientAccess=False, msg
|
|||||||
if mailBox is None:
|
if mailBox is None:
|
||||||
mailBox = msgFromAddr
|
mailBox = msgFromAddr
|
||||||
_, mailBoxAddr = cleanAddr(mailBox)
|
_, mailBoxAddr = cleanAddr(mailBox)
|
||||||
action = Act.Get()
|
parentAction = Act.Get()
|
||||||
Act.Set(Act.SENDEMAIL)
|
Act.Set(action)
|
||||||
if not GC.Values[GC.SMTP_HOST]:
|
if not GC.Values[GC.SMTP_HOST]:
|
||||||
if not clientAccess:
|
if not clientAccess:
|
||||||
userId, gmail = buildGAPIServiceObject(API.GMAIL, mailBoxAddr)
|
userId, gmail = buildGAPIServiceObject(API.GMAIL, mailBoxAddr)
|
||||||
if not gmail:
|
if not gmail:
|
||||||
|
Act.Set(parentAction)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
userId = mailBoxAddr
|
userId = mailBoxAddr
|
||||||
@@ -7444,7 +7446,7 @@ def send_email(msgSubject, msgBody, msgTo, i=0, count=0, clientAccess=False, msg
|
|||||||
server.quit()
|
server.quit()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
Act.Set(action)
|
Act.Set(parentAction)
|
||||||
|
|
||||||
def addFieldToFieldsList(fieldName, fieldsChoiceMap, fieldsList):
|
def addFieldToFieldsList(fieldName, fieldsChoiceMap, fieldsList):
|
||||||
fields = fieldsChoiceMap[fieldName.lower()]
|
fields = fieldsChoiceMap[fieldName.lower()]
|
||||||
@@ -15385,32 +15387,35 @@ def getRecipients():
|
|||||||
return [normalizeEmailAddressOrUID(emailAddress, noUid=True, noLower=True) for emailAddress in recipients]
|
return [normalizeEmailAddressOrUID(emailAddress, noUid=True, noLower=True) for emailAddress in recipients]
|
||||||
return getNormalizedEmailAddressEntity(shlexSplit=True, noLower=True)
|
return getNormalizedEmailAddressEntity(shlexSplit=True, noLower=True)
|
||||||
|
|
||||||
# gam sendemail [recipient|to] <RecipientEntity> [from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>]
|
# gam sendemail [recipient|to] <RecipientEntity>
|
||||||
|
# [from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>]
|
||||||
# [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
# [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
# [subject <String>] [<MessageContent>]
|
# [subject <String>] [<MessageContent>] [html [<Boolean>]]
|
||||||
# (replace <Tag> <String>)*
|
# (replace <Tag> <String>)*
|
||||||
# (replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
|
# (replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
|
||||||
# [html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
|
# (attach <FileName> [charset <CharSet>])*
|
||||||
# (embedimage <FileName> <String>)*
|
# (embedimage <FileName> <String>)*
|
||||||
# [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
# [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
# (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
# (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
# [threadid <String>]
|
# [threadid <String>]
|
||||||
# gam <UserTypeEntity> sendemail recipient|to <RecipientEntity> [replyto <EmailAddress>]
|
# gam <UserTypeEntity> sendemail recipient|to <RecipientEntity>
|
||||||
|
# [replyto <EmailAddress>]
|
||||||
# [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
# [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
# [subject <String>] [<MessageContent>]
|
# [subject <String>] [<MessageContent>] [html [<Boolean>]]
|
||||||
# (replace <Tag> <String>)*
|
# (replace <Tag> <String>)*
|
||||||
# (replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
|
# (replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
|
||||||
# [html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
|
# (attach <FileName> [charset <CharSet>])*
|
||||||
# (embedimage <FileName> <String>)*
|
# (embedimage <FileName> <String>)*
|
||||||
# [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
# [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
# (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
# (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
# [threadid <String>]
|
# [threadid <String>]
|
||||||
# gam <UserTypeEntity> sendemail from <EmailAddress> [replyto <EmailAddress>]
|
# gam <UserTypeEntity> sendemail from <EmailAddress>
|
||||||
|
# [replyto <EmailAddress>]
|
||||||
# [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
# [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
# [subject <String>] [<MessageContent>]
|
# [subject <String>] [<MessageContent> ][html [<Boolean>]]
|
||||||
# (replace <Tag> <String>)*
|
# (replace <Tag> <String>)*
|
||||||
# (replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
|
# (replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
|
||||||
# [html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
|
# (attach <FileName> [charset <CharSet>])*
|
||||||
# (embedimage <FileName> <String>)*
|
# (embedimage <FileName> <String>)*
|
||||||
# [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
# [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
# (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
# (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
@@ -15531,6 +15536,125 @@ def doSendEmail(users=None):
|
|||||||
attachments=attachments, embeddedImages=embeddedImages, msgHeaders=msgHeaders, mailBox=mailBox, threadId=threadId)
|
attachments=attachments, embeddedImages=embeddedImages, msgHeaders=msgHeaders, mailBox=mailBox, threadId=threadId)
|
||||||
Ind.Decrement()
|
Ind.Decrement()
|
||||||
|
|
||||||
|
# gam <UserTypeEntity> sendreply
|
||||||
|
# (((query <QueryGmail> [querytime<String> <Date>]*) [or|and])+) | (ids <MessageIDEntity>)
|
||||||
|
# [replyto <EmailAddress>]
|
||||||
|
# [subject <String>] [<MessageContent>] [html [<Boolean>]]
|
||||||
|
# (attach <FileName> [charset <CharSet>])*
|
||||||
|
# (embedimage <FileName> <String>)*
|
||||||
|
# (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
|
def doSendReply(users):
|
||||||
|
def _getHeaderValue(name):
|
||||||
|
for header in messageInfo['payload']['headers']:
|
||||||
|
if name == header['name']:
|
||||||
|
return _decodeHeader(header['value'])
|
||||||
|
return ''
|
||||||
|
|
||||||
|
notify = {'subject': '', 'message': '', 'html': False, 'charset': UTF8}
|
||||||
|
query = ''
|
||||||
|
queryTimes = {}
|
||||||
|
messageIds = []
|
||||||
|
msgHeaders = {}
|
||||||
|
msgReplyTo = None
|
||||||
|
attachments = []
|
||||||
|
embeddedImages = []
|
||||||
|
while Cmd.ArgumentsRemaining():
|
||||||
|
myarg = getArgument()
|
||||||
|
if myarg == 'query':
|
||||||
|
selectLocation = Cmd.Location()
|
||||||
|
if query:
|
||||||
|
query += ' '
|
||||||
|
query += f'({getString(Cmd.OB_QUERY)})'
|
||||||
|
elif myarg.startswith('querytime'):
|
||||||
|
queryTimes[myarg] = getDateOrDeltaFromNow().replace('-', '/')
|
||||||
|
elif myarg in {'or', 'and'}:
|
||||||
|
if query:
|
||||||
|
query += f' {myarg.upper()}'
|
||||||
|
elif myarg == 'ids':
|
||||||
|
selectLocation = Cmd.Location()
|
||||||
|
messageIds = getEntityList(Cmd.OB_MESSAGE_ID)
|
||||||
|
elif myarg == 'subject':
|
||||||
|
notify['subject'] = getString(Cmd.OB_STRING)
|
||||||
|
elif myarg in SORF_MSG_FILE_ARGUMENTS:
|
||||||
|
notify['message'], notify['charset'], notify['html'] = getStringOrFile(myarg)
|
||||||
|
elif myarg == 'replyto':
|
||||||
|
msgReplyTo = getString(Cmd.OB_EMAIL_ADDRESS)
|
||||||
|
elif myarg == 'html':
|
||||||
|
notify['html'] = getBoolean()
|
||||||
|
elif myarg == 'attach':
|
||||||
|
attachments.append((getFilename(), getCharSet()))
|
||||||
|
elif myarg == 'embedimage':
|
||||||
|
embeddedImages.append((getFilename(), getString(Cmd.OB_STRING)))
|
||||||
|
elif myarg in SMTP_HEADERS_MAP:
|
||||||
|
if myarg in SMTP_DATE_HEADERS:
|
||||||
|
msgDate, _, _ = getTimeOrDeltaFromNow(True)
|
||||||
|
msgHeaders[SMTP_HEADERS_MAP[myarg]] = formatdate(time.mktime(msgDate.timetuple()) + msgDate.microsecond/1E6, True)
|
||||||
|
else:
|
||||||
|
msgHeaders[SMTP_HEADERS_MAP[myarg]] = getString(Cmd.OB_STRING)
|
||||||
|
elif myarg == 'header':
|
||||||
|
header = getString(Cmd.OB_STRING, minLen=1)
|
||||||
|
msgHeaders[SMTP_HEADERS_MAP.get(header.lower(), header)] = getString(Cmd.OB_STRING)
|
||||||
|
else:
|
||||||
|
unknownArgumentExit()
|
||||||
|
if query and messageIds:
|
||||||
|
Cmd.SetLocation(selectLocation-1)
|
||||||
|
usageErrorExit(Msg.ARE_MUTUALLY_EXCLUSIVE.format('query <QueryGmail>', 'ids <MessageIDEntity>'))
|
||||||
|
notify['message'] = notify['message'].replace('\r', '').replace('\\n', '\n')
|
||||||
|
i, count, users = getEntityArgument(users)
|
||||||
|
for user in users:
|
||||||
|
i += 1
|
||||||
|
user, gmail = buildGAPIServiceObject(API.GMAIL, user, i, count)
|
||||||
|
if not gmail:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
if query:
|
||||||
|
printGettingAllEntityItemsForWhom(Ent.MESSAGE, user, i, count, query=query)
|
||||||
|
listResult = callGAPIpages(gmail.users().messages(), 'list', 'messages',
|
||||||
|
pageMessage=getPageMessageForWhom(),
|
||||||
|
throwReasons=GAPI.GMAIL_THROW_REASONS+GAPI.GMAIL_LIST_THROW_REASONS,
|
||||||
|
userId='me', q=query, fields='nextPageToken,messages(id)',
|
||||||
|
maxResults=GC.Values[GC.MESSAGE_MAX_RESULTS])
|
||||||
|
messageIds = [message['id'] for message in listResult]
|
||||||
|
except (GAPI.failedPrecondition, GAPI.permissionDenied, GAPI.invalid, GAPI.invalidArgument) as e:
|
||||||
|
entityActionFailedWarning([Ent.USER, user], str(e), i, count)
|
||||||
|
continue
|
||||||
|
except GAPI.serviceNotAvailable:
|
||||||
|
userGmailServiceNotEnabledWarning(user, i, count)
|
||||||
|
continue
|
||||||
|
jcount = len(messageIds)
|
||||||
|
if jcount == 0:
|
||||||
|
entityNumEntitiesActionNotPerformedWarning([Ent.USER, user], Ent.MESSAGE, jcount, Msg.NO_ENTITIES_MATCHED.format(Ent.Plural(Ent.MESSAGE)), i, count)
|
||||||
|
setSysExitRC(NO_ENTITIES_FOUND_RC)
|
||||||
|
continue
|
||||||
|
entityPerformActionModifierNumItems([Ent.USER, user], Act.MODIFIER_TO, jcount, Ent.RECIPIENT, i, count)
|
||||||
|
Ind.Increment()
|
||||||
|
j = 0
|
||||||
|
for messageId in messageIds:
|
||||||
|
j += 1
|
||||||
|
try:
|
||||||
|
messageInfo = callGAPI(gmail.users().messages(), 'get',
|
||||||
|
throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.NOT_FOUND, GAPI.INVALID_MESSAGE_ID],
|
||||||
|
userId='me', id=messageId, fields='id,threadId,payload(headers)')
|
||||||
|
threadId = messageInfo['threadId']
|
||||||
|
msgHeaders['References'] = msgHeaders['In-Reply-To'] = _getHeaderValue('Message-ID')
|
||||||
|
msgSubject = notify['subject'] if notify['subject'] else f"Re: {_getHeaderValue('Subject')}"
|
||||||
|
recipient = _getHeaderValue('From')
|
||||||
|
send_email(msgSubject, notify['message'], recipient, j, jcount,
|
||||||
|
msgFrom=user, msgReplyTo=msgReplyTo, html=notify['html'], charset=notify['charset'],
|
||||||
|
attachments=attachments, embeddedImages=embeddedImages, msgHeaders=msgHeaders, threadId=threadId,
|
||||||
|
action=Act.SENDREPLY)
|
||||||
|
except GAPI.notFound:
|
||||||
|
entityActionFailedWarning([Ent.USER, user, Ent.MESSAGE, messageId], Msg.DOES_NOT_EXIST, j, jcount)
|
||||||
|
except GAPI.invalidMessageId:
|
||||||
|
entityActionFailedWarning([Ent.USER, user, Ent.MESSAGE, messageId], Msg.INVALID_MESSAGE_ID, j, jcount)
|
||||||
|
except (GAPI.failedPrecondition, GAPI.permissionDenied, GAPI.invalid, GAPI.invalidArgument) as e:
|
||||||
|
entityActionFailedWarning([Ent.USER, user], str(e), i, count)
|
||||||
|
break
|
||||||
|
except GAPI.serviceNotAvailable:
|
||||||
|
userGmailServiceNotEnabledWarning(user, i, count)
|
||||||
|
break
|
||||||
|
Ind.Decrement()
|
||||||
|
|
||||||
ADDRESS_FIELDS_PRINT_ORDER = ['contactName', 'organizationName', 'addressLine1', 'addressLine2', 'addressLine3', 'locality', 'region', 'postalCode', 'countryCode']
|
ADDRESS_FIELDS_PRINT_ORDER = ['contactName', 'organizationName', 'addressLine1', 'addressLine2', 'addressLine3', 'locality', 'region', 'postalCode', 'countryCode']
|
||||||
|
|
||||||
def _showCustomerAddressPhoneNumber(customerInfo):
|
def _showCustomerAddressPhoneNumber(customerInfo):
|
||||||
@@ -80879,6 +81003,7 @@ USER_COMMANDS = {
|
|||||||
'profile': (Act.SET, setProfile),
|
'profile': (Act.SET, setProfile),
|
||||||
'sendas': (Act.ADD, createUpdateSendAs),
|
'sendas': (Act.ADD, createUpdateSendAs),
|
||||||
'sendemail': (Act.SENDEMAIL, doSendEmail),
|
'sendemail': (Act.SENDEMAIL, doSendEmail),
|
||||||
|
'sendreply': (Act.SENDREPLY, doSendReply),
|
||||||
'signature': (Act.SET, setSignature),
|
'signature': (Act.SET, setSignature),
|
||||||
'signout': (Act.SIGNOUT, signoutTurnoff2SVUsers),
|
'signout': (Act.SIGNOUT, signoutTurnoff2SVUsers),
|
||||||
'turnoff2sv': (Act.TURNOFF2SV, signoutTurnoff2SVUsers),
|
'turnoff2sv': (Act.TURNOFF2SV, signoutTurnoff2SVUsers),
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Copyright (C) 2024 Ross Scroggs All Rights Reserved.
|
# Copyright (C) 2026 Ross Scroggs All Rights Reserved.
|
||||||
#
|
#
|
||||||
# All Rights Reserved.
|
# All Rights Reserved.
|
||||||
#
|
#
|
||||||
@@ -107,6 +107,7 @@ class GamAction():
|
|||||||
SAVE = 'save'
|
SAVE = 'save'
|
||||||
SEND = 'send'
|
SEND = 'send'
|
||||||
SENDEMAIL = 'snem'
|
SENDEMAIL = 'snem'
|
||||||
|
SENDREPLY = 'sner'
|
||||||
SET = 'set '
|
SET = 'set '
|
||||||
SETUP = 'setu'
|
SETUP = 'setu'
|
||||||
SHARE = 'shar'
|
SHARE = 'shar'
|
||||||
@@ -225,6 +226,7 @@ class GamAction():
|
|||||||
SAVE: ['Saved', 'Save'],
|
SAVE: ['Saved', 'Save'],
|
||||||
SEND: ['Sent', 'Send'],
|
SEND: ['Sent', 'Send'],
|
||||||
SENDEMAIL: ['Email Sent', 'Send Email'],
|
SENDEMAIL: ['Email Sent', 'Send Email'],
|
||||||
|
SENDREPLY: ['Reply Sent', 'Send Reply'],
|
||||||
SET: ['Set', 'Set'],
|
SET: ['Set', 'Set'],
|
||||||
SETUP: ['Set Up', 'Set Up'],
|
SETUP: ['Set Up', 'Set Up'],
|
||||||
SHARE: ['Shared', 'Share'],
|
SHARE: ['Shared', 'Share'],
|
||||||
|
|||||||
@@ -465,11 +465,12 @@ gam user recipient@domain.com sendemail to sender@domain.com references "<CAAMab
|
|||||||
If you want to have Gmail recognize the reply in conversation mode in the Sent folder of the original recipient,
|
If you want to have Gmail recognize the reply in conversation mode in the Sent folder of the original recipient,
|
||||||
you must include `threadid <String>`; you can get the 'threadId` with:
|
you must include `threadid <String>`; you can get the 'threadId` with:
|
||||||
```
|
```
|
||||||
gam user recipient@domain.com show messages query "rfc822MsgId:<CAAMabc...XYZQ@mail.gmail.com>"
|
gam user recipient@domain.com show threads query "rfc822MsgId:<CAAMabc...XYZQ@mail.gmail.com>"
|
||||||
Getting all Messages that match query ((rfc822MsgId:<CAAMabc...XYZQ@mail.gmail.com>)) for recipient@domain.com
|
Getting all Messages that match query ((rfc822MsgId:<CAAMabc...XYZQ@mail.gmail.com>)) for recipient@domain.com
|
||||||
Got 1 Message that matched query ((rfc822MsgId:<CAAMabc...XYZQ@mail.gmail.com>)) for recipient@domain.com...
|
Got 1 Message that matched query ((rfc822MsgId:<CAAMabc...XYZQ@mail.gmail.com>)) for recipient@domain.com...
|
||||||
User: recipient@domain.com, Show 1 Message
|
User: recipient@domain.com, Show 1 Thread
|
||||||
Message: 19cfd414fe48430d
|
Thread: 19cfd414fe48430d
|
||||||
|
Message: 19cfd414fe48430d
|
||||||
...
|
...
|
||||||
|
|
||||||
gam user recipient@domain.com sendemail to sender@domain.com references "<CAAMabc...XYZQ@mail.gmail.com>" in-reply-to "<CAAMabc...XYZQ@mail.gmail.com>" subject "Re: Original subject" textmessage "Reply text" threadid 19cfd414fe48430d
|
gam user recipient@domain.com sendemail to sender@domain.com references "<CAAMabc...XYZQ@mail.gmail.com>" in-reply-to "<CAAMabc...XYZQ@mail.gmail.com>" subject "Re: Original subject" textmessage "Reply text" threadid 19cfd414fe48430d
|
||||||
|
|||||||
Reference in New Issue
Block a user