我有一个部分我的软件,最近已经停止正常工作。该程序应该允许用户上传一个pdf到我们的团队谷歌驱动器帐户,然后该程序将发送一封电子邮件给我们办公室的其他一些人进行审查。这一直有效,直到周一,我的用户上传的内容和电子邮件开始来自我的谷歌账户,而不是他们自己的。它不会发生在每个人身上,可能1/3到1/2的用户遇到这个问题。有时程序会以我的身份发送电子邮件,有时它会在请求https://gmail.googleapis.com/gmail/v1/users/username/messages/send?alt=json时抛出<HttpError 403返回'Delegation denied for 'my.email@ email.com'>。由于我的上传和发送电子邮件功能没有任何变化,我认为这与权限或程序如何分发有关?任何见解将不胜感激。
我已经用python3写好了所有的东西,并编译了一个exe,用pyinstaller分发给我的团队。pyinstaller --onefile path/to/code.py
我想解决的问题:以管理员身份运行让用户重新启动他们的PC我让我的团队中的某个人直接运行py文件并且运行正常最初我删除了pyinstaller的--hidden-import ='googleapiclient'最初在电子邮件部分我有userId ='me'并且我将其更改为拉入用户的实际电子邮件地址。(pyinstaller的想法是锁定“我”作为我的个人电子邮件。该代码在上传后运行,所以这似乎不是问题所在。)
相关的上传代码,以防有人发现问题:
self.SCOPES = ['https://www.googleapis.com/auth/gmail.modify',
'https://www.googleapis.com/auth/spreadsheets',
'https://www.googleapis.com/auth/drive']
credentials.json:
{
"installed":{
"client_id":"client_id.apps.googleusercontent.com",
"project_id":"project_ID",
"auth_uri":"https://accounts.google.com/o/oauth2/auth",
"token_uri":"https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs",
"client_secret":"secret_code",
"redirect_uris":[
"urn:ietf:wg:oauth:2.0:oob",
"http://localhost"
]
}
}
def upload(self, letterfile, plansfile, parentdrive):
# Check for json credentials for google drive and API access
try:
x = os.stat(os.path.join(self.prefs['data'], 'token.json'))
result = time.time() - x.st_mtime
if result > 129600:
os.remove(os.path.join(self.prefs['data'], 'token.json'))
except:
pass
creds = None
jsonpath = os.path.join(self.prefs['data'], 'token.json')
if os.path.exists(jsonpath):
creds = Credentials.from_authorized_user_file(jsonpath,
self.SCOPES)
# If there are no (valid) credentials available, let the user log in.
try:
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
os.path.join(self.prefs['data'], 'credentials.json'),
self.SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open(os.path.join(self.prefs['data'], 'token.json'), 'w') as token:
token.write(creds.to_json())
except BaseException as e:
print(f'Error with credentials.json check: {e}')
# Build the services to access the Gmail API and Drive API
driveService = build('drive', 'v3', credentials=creds)
file = letterfile
folderLink = f'https://drive.google.com/drive/folders/{parentdrive}'
# Work with different attachment formats (Text, Image, or PDF). This
# will need to be a FOR loop to iterate through all imported files
# from the app
content_type, encoding = mimetypes.guess_type(file)
if content_type is None or encoding is not None:
content_type = 'application/octet-stream'
main_type, sub_type = content_type.split('/', 1)
if main_type == 'text':
with open(file, 'rb') as fp:
msg = MIMEText(fp.read(), _subtype=sub_type)
fp.close()
elif main_type == 'image':
with open(file, 'rb') as fp:
msg = MIMEImage(fp.read(), _subtype=sub_type)
fp.close()
else:
with open(file, 'rb') as fp:
msg = MIMEBase(main_type, sub_type)
msg.set_payload(fp.read())
fp.close()
calcfile = os.path.basename(letterfile)
try:
planname = os.path.basename(plansfile)
except BaseException as e:
planname = []
for planfile in plansfile:
planname.append(os.path.basename(planfile))
# Upload file to Drive Project Folder
file_metadata = {'name': calcfile, 'parents': [parentdrive]}
media = MediaFileUpload(letterfile,
mimetype=content_type,
resumable=True)
tempcalcfile = driveService.files().create(body=file_metadata,
media_body=media,
supportsAllDrives=True).execute()
try:
plan_metadata = {'name': planname, 'parents': [parentdrive]}
media = MediaFileUpload(plansfile,
mimetype=content_type,
resumable=True)
tempplansfile = driveService.files().create(body=plan_metadata,
media_body=media,
supportsAllDrives=True).execute()
except BaseException as e:
for i in range(len(planname)):
plan_metadata = {'name': planname[i], 'parents': [parentdrive]}
media = MediaFileUpload(plansfile[i],
mimetype=content_type,
resumable=True)
tempplansfile = driveService.files().create(body=plan_metadata,
media_body=media,
supportsAllDrives=True).execute()
print('Files sent to Drive Folder through API')
1条答案
按热度按时间rryofs0p1#
我有一个文件夹,里面存放着credentials.json、我的token.json文件,以及其他一些分发给我的团队的文件。我不小心与他们共享了我的token.json文件,所以当google Oauth2运行时,它以我的身份读取文件,而不是以用户的身份。
我让我的团队删除了token.json文件,这迫使用户重新授权,创建一个新的token.json并修复了这个问题。