def main(): import argparse import configparser parser = argparse.ArgumentParser( description='Export ContentVersion (Files) from Salesforce') parser.add_argument( '-q', '--query', metavar='query', required=True, help= 'SOQL to limit the valid ContentDocumentIds. Must return the Ids of parent objects.' ) parser.add_argument('-o', '--outputdir', metavar='outputdir', required=True, help='Output directory for writing extracted files.') parser.add_argument('-t', '--type', metavar='type', required=True, help='Type for download.') args = parser.parse_args() # Get settings from config file config = configparser.ConfigParser(allow_no_value=True) config.read('download-' + args.type.strip() + '.ini') username = config['salesforce']['username'] password = config['salesforce']['password'] token = config['salesforce']['security_token'] domain = config['salesforce']['domain'] if domain: domain += '.my' else: domain = 'login' batch_size = int(config['salesforce']['batch_size']) is_sandbox = config['salesforce']['connect_to_sandbox'] loglevel = logging.getLevelName(config['salesforce']['loglevel']) logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=loglevel) content_document_query = 'SELECT ContentDocumentId, LinkedEntityId, LinkedEntity.Name, ContentDocument.Title, ' \ 'ContentDocument.FileExtension FROM ContentDocumentLink ' \ 'WHERE LinkedEntityId in ({0})'.format(args.query.strip()) #output = config['salesforce']['output_dir'] output = args.outputdir.strip() query = "SELECT ContentDocumentId, Title, VersionData, FileExtension FROM ContentVersion " \ "WHERE IsLatest = True AND FileExtension != 'snote'" if is_sandbox == 'True': domain = 'test' # Output logging.info('Export ContentVersion (Files) from Salesforce') logging.info('Username: '******'Signing in at: https://' + domain + '.salesforce.com') logging.info('Output directory: ' + output) # Connect - https://pypi.org/project/simple-salesforce/ sf = Salesforce(username=username, password=password, security_token=token, domain=domain) logging.debug("Connected successfully to {0}".format(sf.sf_instance)) # Get Content Document Ids logging.debug("Querying to get Content Document Ids...") valid_content_document_ids = None if content_document_query: valid_content_document_ids = get_content_document_ids( sf=sf, output_directory=output, query=content_document_query) logging.info("Found {0} total files".format( len(valid_content_document_ids))) # Begin Downloads fetch_files(sf=sf, query_string=query, valid_content_document_ids=valid_content_document_ids, output_directory=output, batch_size=batch_size)
import os import sys import time from webwhatsapis import WhatsAPIDriver from simple_salesforce import Salesforce from config import * sf = Salesforce(username=username, password=password, security_token=security_token) def run(): driver = WhatsAPIDriver(extra_params={'executable_path': './geckodriver'}, loadstyles=True, headless=False) print("Waiting for QR") # driver.get_qr('qr.png') # does not work driver.screenshot('./ref/qr.png') driver.wait_for_login(600) print("Bot started") time.sleep(5) driver.subscribe_new_messages(NewMessageObserver()) print("Waiting for new messages...") # driver.screenshot('./ref/12.png') """ Locks the main thread while the subscription in running """ while True: time.sleep(60)
import os import time import random BASE_DIR = './' load_dotenv(os.path.join(BASE_DIR, '.env.iotxporg')) USERNAME = os.getenv('USERNAME') PASSWORD = os.getenv('PASSWORD') SECURITY_TOKEN = os.getenv('SECURITY_TOKEN') print("uname %s pw %s token %s" % (USERNAME, PASSWORD, SECURITY_TOKEN)) sf = Salesforce(username=USERNAME, password=PASSWORD, security_token=SECURITY_TOKEN) print(sf) def read_temp(): temp_c = 27.0 + (25 * random.random()) temp_f = temp_c * 9.0 / 5.0 + 32.0 return temp_c while True: print(read_temp()) data = [{ 'serial_no__c': '1001', 'door_open__c': 'false',
from simple_salesforce import Salesforce from arcgis.gis import GIS from arcgis.features import FeatureLayerCollection, FeatureLayer import psycopg2 as pg import requests load_dotenv(find_dotenv()) #get by os.environ.get("VALUE") #custom imports from load_locations import load_locations from load_cpe_locations import load_cpe_locations from create_datafile import create_datafile from enable_exports import enable_exports # establish connection objects to SF and to DB sf = Salesforce(username=os.environ.get("SF_USERNAME"), password=os.environ.get("SF_PASSWORD"), security_token=os.environ.get("SF_TOKEN")) try: conn = pg.connect(port=os.environ.get("DB_PORT"), host=os.environ.get("DB_HOST"), dbname=os.environ.get("DB_NAME"), user=os.environ.get("DB_USER"), password=os.environ.get("DB_PASS")) except: print("Unable to connect to DB - Exiting") exit() cur = conn.cursor() gis = GIS(os.environ.get("AGOL_SERVICE_URL"), os.environ.get("AGOL_USER"), os.environ.get("AGOL_PASS")) # Get and Push into Truncated Tables - totally replaces all data in both locations and cpe_locations table
def main(): import argparse parser = argparse.ArgumentParser( description='Export ContentVersion (Files) from Salesforce') parser.add_argument('-u', '--user', metavar='username', required=True, help='Your Salesforce username') parser.add_argument('-p', '--password', metavar='password', required=True, help='Your Salesforce password') parser.add_argument('-t', '--token', metavar='security_token', required=True, help='Your Security Token') parser.add_argument('-sb', '--sandbox', metavar='sandbox', required=False, default='True', help='is this a sandbox instance?') parser.add_argument( '-q', '--query', metavar='query', required=True, help= 'SOQL query (has to contain Title and VersionData and SELECT FROM ContentVersion)' ) parser.add_argument( '-cdq', '--content_document_query', metavar='cdqquery', required=False, help= 'SOQL to limit the valid ContentDocumentIds, if this is set you need ContentDocumentId ' 'in your ContentVersion query') parser.add_argument('-o', '--output', required=False, default='output', help='Specify output directory') args = parser.parse_args() domain = None if args.sandbox == 'True': domain = 'test' sf = Salesforce(username=args.user, password=args.password, security_token=args.token, domain=domain) valid_content_document_ids = None if args.content_document_query: valid_content_document_ids = get_content_document_ids( sf=sf, query=args.content_document_query) fetch_files(sf=sf, query_string=args.query, valid_content_document_ids=valid_content_document_ids, output_directory=args.output)
import logging from django.conf import settings from simple_salesforce import Salesforce logger = logging.getLogger(__name__) def dummy_method(name): return lambda *args, **kwargs: logger.warning( f'dummy metohd {name} called (args %s, kwargs %s)', args, kwargs) class DummyObjectHandler: def __init__(self, name): self.create = dummy_method(f'{name}.create') class SalesforceDummy: def __init__(self, name): self.Lead = DummyObjectHandler(f'{name}.Lead') if settings.SALESFORCE_INSTANCE is None: salesforce = SalesforceDummy('salesforce') else: salesforce = Salesforce( instance=settings.SALESFORCE_INSTANCE, session_id=settings.SALESFORCE_ACCESS_TOKEN, )
from mysql.connector.constants import ClientFlag from sfdc_config import SFUSER,SFPW,SF_TOKEN,DBUSER,DBPW,DBHOST,DBNAME,opportunity_directory,OPPORTUNITY_FIELD_TYPE_MAP,OPPORTUNITY_FIELD_DICT,OPPORTUNITY_ORDERED_FIELDS FIELD_TYPE_MAP=OPPORTUNITY_FIELD_TYPE_MAP FIELD_DICT = OPPORTUNITY_FIELD_DICT ORDERED_FIELDS = OPPORTUNITY_ORDERED_FIELDS directory = opportunity_directory #make CSVs for main table and split values the_date = time.strftime("%d-%m-%Y") file_out = directory+'opportunity%s.csv' % (the_date) csv_out = open(file_out, 'wb') csv_handler = csv.writer(csv_out, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) sf = Salesforce(password=SFPW, username=SFUSER, security_token=SF_TOKEN) #connect to DB #note that the client_flag allows the mysql module to access files on the computer cnx = mysql.connector.connect(user=DBUSER, password=DBPW, host=DBHOST, database=DBNAME, client_flags=[ClientFlag.LOCAL_FILES]) cursor = cnx.cursor() sosl = "SELECT %s FROM Opportunity" % ','.join(FIELD_DICT.values()) p = sf.query_all(sosl) #for all records in the returned sql index = 1 for record in p['records']: row = []
class FulcrumRecordToSalesforceRecord: _sfdcSession_id, _sfdcInstance = SalesforceLogin(username=_sfdcUsername, password=_sfdcPassword, security_token=_sfdcToken, domain=_sfdcDomain) sfdc = Salesforce(instance=_sfdcInstance, session_id=_sfdcSession_id) fulcrum = Fulcrum(key=_fulcrumXApiToken) fulcrumHeaders = {'X-ApiToken': _fulcrumXApiToken} def sf_api_call(self, action, parameters={}, method='get', data={}, multipart=False, boundary=None): """ Helper function to make calls to Salesforce REST API. Parameters: action (the URL), URL params, method (get, post or patch), data for POST/PATCH. """ headers = {} if multipart == False: headers = { 'Content-type': 'application/json', 'Accept-Encoding': 'gzip', 'Authorization': 'OAuth ' + self._sfdcSession_id, } else: headers = { 'Content-type': 'multipart/form-data; boundary=' + boundary, 'Accept-Encoding': 'gzip', 'Authorization': 'OAuth ' + self._sfdcSession_id, } if method == 'get': r = requests.request(method, 'https://' + self._sfdcInstance + action, headers=headers, params=parameters, timeout=30) elif method in ['post', 'patch']: r = requests.request(method, 'https://' + self._sfdcInstance + action, headers=headers, json=data, params=parameters, timeout=10) else: # other methods not implemented in this example raise ValueError('Method should be get or post or patch.') #print('Debug: API %s call: %s' % (method, r.url) ) if r.status_code < 300: if method == 'patch': return None else: return r.json() else: raise Exception('API error when calling %s : %s' % (r.url, r.content)) # Generates a random string def id_generator(self, size=32, chars=string.ascii_uppercase + string.digits): return ''.join(random.choice(chars) for _ in range(size)) #checks to see if a key exists in a dictonary def checkKey(self, dictionary, key): try: if key in dictionary.keys(): return True else: return False except KeyError: return False ## pass JSON Directly def composite_salesforce_create(self, objectId, records): response = self.sfdc.restful(method='POST', path='composite/tree/' + objectId, json=records) return response #must have Salesforce record IDs def composite_salesforce_update(self, objectId, extCustomField, extIdValue, records): response = self.sfdc.restful(method='PATCH', path='composite/sobjects', json=records) return response def composite_salesforce_request(self, objectId, extCustomField, extIdValue, records): response = self.sfdc.restful(method='POST', path='composite/sobjects/' + objectId, json=records) return reponse # Data should either be a single JSON encapsulating base64 encoded blob up to 34MB # Or a multipart message encapsulating a base64 encoded blob up to 2GB # https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_sobject_insert_update_blob.htm def contentVersion_salesforce_create(self, data): return self.sf_api_call('/services/data/v40.0/sobjects/ContentVersion', method="post", data=data) def contentVersion_2GB_salesforce_create(self, data, boundary): return self.sf_api_call('/services/data/v40.0/sobjects/ContentVersion', method="post", data=data, multipart=True, boundary=boundary) # Data should be an ID def contentVersion_salesforce_get(self, data): return self.sf_api_call( '/services/data/v40.0/sobjects/ContentVersion/%s' % data) def contentDocumentLink_salesforce_create(self, data): return self.sf_api_call( '/services/data/v40.0/sobjects/ContentDocumentLink', method='post', data=data) def create_output_json(self, recordJson): recordJson = json.dumps(recordJson) recordJson = recordJson[1:-1] recordJson = recordJson.replace('null', '') return recordJson def process_generate_field(self, fieldId, fieldValue, fieldType='Data'): print ' ' + str(fieldType) + ': ' + str(_sfdcPrefix) + str( fieldId) + '__c:' + str(fieldValue) if fieldType == 'Latitude' or fieldType == 'Longitude': return { _sfdcPrefix + fieldId + '__' + fieldType + '__s': fieldValue } else: return {_sfdcPrefix + fieldId + '__c': fieldValue} def upload_2GB_file_to_salesforce_and_attach_to_record( self, recordId, fileTitle, fileDescription, fileName, fileContents): boundary = self.id_generator() fileContents = base64.b64encode(fileContents) #Multi part request can handle 2GB Max ContentVersionMetadata = { 'Title': fileTitle, 'Description': fileDescription, 'PathOnClient': fileName, } ContentVersionData = """--""" + boundary + """ Content-Disposition: form-data; name="entity_content"; Content-Type: application/json { "Title" : """ + '"' + fileTitle + '"' + """, "Description" : """ + '"' + fileDescription + '"' + """, "PathOnClient" : """ + '"' + fileName + '"' + """ } --""" + boundary + """ Content-Disposition: form-data; name="VersionData"; filename=""" + '"' + fileName + '"' + """ Content-Type: application/octet-stream """ + fileContents + """ --""" + boundary + """--""" # 1: Insert the Content Document ContentVersion = self.contentVersion_2GB_salesforce_create( data=ContentVersionData, boundary=boundary) ContentVersionId = ContentVersion.get('id') # 2: Get the ContentDocumentId from the just inserted ContentVersion ContentVersion = self.contentVersion_salesforce_get(ContentVersionId) ContentDocumentId = ContentVersion.get('ContentDocumentId') # 3: Create a ContentDocumentLink between the ContentDocumentId and the Record contentDocumentLinkMetadata = { 'ContentDocumentId': ContentDocumentId, 'LinkedEntityId': recordId, 'ShareType': 'V' } ContentDocumentLink = self.contentDocumentLink_salesforce_create( contentDocumentLinkMetadata) return { 'ContentVersionId': ContentVersionId, 'ContentDocumentId': ContentDocumentId, 'ContentDocumentLink': ContentDocumentLink } def upload_file_to_salesforce_and_attach_to_record(self, recordId, fileTitle, fileDescription, fileName, fileContent, fulcrumId): fileContent = base64.b64encode(fileContent) #Single part request can handle ~34MB Max ContentVersionData = { 'Title': fileTitle, 'Description': fileDescription, 'PathOnClient': fileName, 'VersionData': fileContent, _sfdcPrefix + 'Fulcrum_Id__c': fulcrumId, # _sfdcPrefix + 'Location__c':fulcrumLocation } # 1: Insert the Content Document ContentVersion = self.contentVersion_salesforce_create( data=ContentVersionData) ContentVersionId = ContentVersion.get('id') # 2: Get the ContentDocumentId from the just inserted ContentVersion ContentVersion = self.contentVersion_salesforce_get(ContentVersionId) ContentDocumentId = ContentVersion.get('ContentDocumentId') # 3: Create a ContentDocumentLink between the ContentDocumentId and the Record contentDocumentLinkMetadata = { 'ContentDocumentId': ContentDocumentId, 'LinkedEntityId': recordId, 'ShareType': 'V' } ContentDocumentLink = self.contentDocumentLink_salesforce_create( contentDocumentLinkMetadata) return { 'ContentVersionId': ContentVersionId, 'ContentDocumentId': ContentDocumentId, 'ContentDocumentLink': ContentDocumentLink } def process_file_fields(self, record, recordId): #print record newFiles = [] for fieldId in record['form_values']: files = self.detect_file_field_type_and_process_field( fieldId, record, recordId=recordId) #print files if isinstance(files, dict): newFiles.append(files) return newFiles def process_video_field(self, fieldValue, recordId): print 'Downloading Video File From Fulcrum ... ' + fieldValue[ 'video_id'] baseurl = _fulcrumBaseURL + 'videos/' + fieldValue['video_id'] blob = requests.request('GET', baseurl + '.mp4', headers=self.fulcrumHeaders) if blob.status_code == 200: videoMetadata = self.fulcrum.videos.find(fieldValue['video_id']) print 'Uploading Video File To Salesforce... ' + recordId self.upload_file_to_salesforce_and_attach_to_record( recordId=recordId, fileTitle=fieldValue['video_id'] + ' Video', fileDescription=fieldValue['caption'], fileName=fieldValue['video_id'] + '.mp4', fileContent=blob.content, fulcrumId=fieldValue['video_id']) blob = requests.request('GET', baseurl + '/track.json', headers=self.fulcrumHeaders) if blob.status_code == 200: print 'Uploading Video Track To Salesforce... ' + recordId self.upload_file_to_salesforce_and_attach_to_record( recordId=recordId, fileTitle=fieldValue['video_id'] + ' JSON Track', fileDescription='JSON Track Of\n' + fieldValue['caption'], fileName=fieldValue['video_id'] + '-track.json', fileContent=blob.content) blob = requests.request('GET', baseurl + '/track.geojson', headers=self.fulcrumHeaders) if blob.status_code == 200: print 'Uploading Video GeoJSON Track To Salesforce... ' + recordId self.upload_file_to_salesforce_and_attach_to_record( recordId=recordId, fileTitle=fieldValue['video_id'] + ' GEO JSON Track', fileDescription='GeoJSON Track Of\n' + fieldValue['caption'], fileName=fieldValue['video_id'] + '-track.geojson', fileContent=blob.content) blob = requests.request('GET', baseurl + '/track.gpx', headers=self.fulcrumHeaders) if blob.status_code == 200: print 'Uploading Video GPX Track To Salesforce... ' + recordId self.upload_file_to_salesforce_and_attach_to_record( recordId=recordId, fileTitle=fieldValue['video_id'] + ' GPX Track', fileDescription='GPX Track Track Of\n' + fieldValue['caption'], fileName=fieldValue['video_id'] + '-track.gpx', fileContent=blob.content) blob = requests.request('GET', baseurl + '/track.kml', headers=self.fulcrumHeaders) if blob.status_code == 200: print 'Uploading Video KML Track To Salesforce... ' + recordId self.upload_file_to_salesforce_and_attach_to_record( recordId=recordId, fileTitle=fieldValue['video_id'] + ' KML Track', fileDescription='KML Track Track Of\n' + fieldValue['caption'], fileName=fieldValue['video_id'] + '-track.kml', fileContent=blob.content) return def process_photo_field(self, fieldValue, recordId): print 'Downloading Photo File From Fulcrum ... ' + fieldValue[ 'photo_id'] blob = requests.request('GET', _fulcrumBaseURL + 'photos/' + fieldValue['photo_id'] + '.jpg', headers=self.fulcrumHeaders) if blob.status_code == 200: print 'Uploading Photo File To Salesforce... ' + recordId self.upload_file_to_salesforce_and_attach_to_record( recordId=recordId, fileTitle=fieldValue['photo_id'] + ' Photo', fileDescription=fieldValue['caption'], fileName=fieldValue['photo_id'] + '.jpg', fileContent=blob.content, fulcrumId=fieldValue['photo_id']) return def process_signature_field(self, fieldValue, recordId): print 'Downloading Signature File From Fulcrum ... ' + fieldValue[ 'signature_id'] blob = requests.request('GET', _fulcrumBaseURL + 'signature/' + fieldValue['signature_id'] + '.png', headers=self.fulcrumHeaders) if blob.status_code == 200: print 'Uploading Signature File To Salesforce... ' + recordId self.upload_file_to_salesforce_and_attach_to_record( recordId=recordId, fileTitle=fieldValue['photo_id'] + ' Signature', fileDescription='Signed At: ' + fieldValue['timestamp'], fileName=fieldValue['signature_id'] + '.png', fileContent=blob.content, fulcrumId=fieldValue['signature_id']) return def process_audio_field(self, fieldValue, recordId): print 'Downloading Audio File From Fulcrum ... ' + fieldValue[ 'audio_id'] blob = requests.request('GET', _fulcrumBaseURL + 'audio/' + fieldValue['audio_id'] + '.mp4', headers=self.fulcrumHeaders) if blob.status_code == 200: print 'Uploading Audio File To Salesforce... ' + recordId self.upload_file_to_salesforce_and_attach_to_record( recordId=recordId, fileTitle=fieldValue['audio_id'] + ' Video', fileDescription=fieldValue['caption'], fileName=fieldValue['audio_id'] + '.mp4', fileContent=blob.content, fulcrumId=fieldValue['audio_id']) blob = requests.request('GET', _fulcrumBaseURL + 'audio/' + fieldValue['audio_id'] + '/track.json', headers=self.fulcrumHeaders) if blob.status_code == 200: print 'Uploading Audio Track To Salesforce... ' + recordId self.upload_file_to_salesforce_and_attach_to_record( recordId=recordId, fileTitle=fieldValue['audio_id'] + ' JSON Track', fileDescription='JSON Track Of\n' + fieldValue['caption'], fileName=fieldValue['audio_id'] + '-track.json', fileContent=blob.content) blob = requests.request('GET', _fulcrumBaseURL + 'audio/' + fieldValue['audio_id'] + '/track.geojson', headers=self.fulcrumHeaders) if blob.status_code == 200: print 'Uploading Audio GeoJSON Track To Salesforce... ' + recordId self.upload_file_to_salesforce_and_attach_to_record( recordId=recordId, fileTitle=fieldValue['audio_id'] + ' GEO JSON Track', fileDescription='GeoJSON Track Of\n' + fieldValue['caption'], fileName=fieldValue['audio_id'] + '-track.geojson', fileContent=blob.content) blob = requests.request('GET', _fulcrumBaseURL + 'audio/' + fieldValue['audio_id'] + '/track.gpx', headers=self.fulcrumHeaders) if blob.status_code == 200: print 'Uploading Audio GPX Track To Salesforce... ' + recordId self.upload_file_to_salesforce_and_attach_to_record( recordId=recordId, fileTitle=fieldValue['audio_id'] + ' GPX Track', fileDescription='GPX Track Track Of\n' + fieldValue['caption'], fileName=fieldValue['audio_id'] + '-track.gpx', fileContent=blob.content) blob = requests.request('GET', _fulcrumBaseURL + 'audio/' + fieldValue['audio_id'] + '/track.kml', headers=self.fulcrumHeaders) if blob.status_code == 200: print 'Uploading Audio KML Track To Salesforce... ' + recordId self.upload_file_to_salesforce_and_attach_to_record( recordId=recordId, fileTitle=fieldValue['audio_id'] + ' KML Track', fileDescription='KML Track Track Of\n' + fieldValue['caption'], fileName=fieldValue['audio_id'] + '-track.kml', fileContent=blob.content) return def process_date_field(self, fieldId, fieldValue): #Generate Date Time return self.process_generate_field(fieldId, fieldValue, 'Date') def process_datetime_field(self, record, isDateField, fieldId, fieldValue): #Generate Date Time # Check to see if the last field processed was a Date Field if isDateField != _isDateFieldDefault: dateValue = record['form_values'][isDateField] dateTimeValue = dateValue + ' ' + fieldValue return self.process_generate_field(isDateField + '_' + fieldId, dateTimeValue, 'DateTime') #Not paired with a Date Field else: return self.process_generate_field(fieldId, fieldValue, 'Time') def process_address_and_choice_field(self, fieldId, subFieldKey, subFieldValue): if subFieldValue == 'sub_thoroughfare': return self.process_generate_field(fieldId + '_1', subFieldValue, 'Street Number') elif subFieldKey == 'thoroughfare': return self.process_generate_field(fieldId + '_2', subFieldValue, 'Street Name') elif subFieldKey == 'suite': return self.process_generate_field(fieldId + '_3', subFieldValue, 'Suite') elif subFieldKey == 'locality': return self.process_generate_field(fieldId + '_4', subFieldValue, 'City') elif subFieldKey == 'sub_admin_area': return self.process_generate_field(fieldId + '_5', subFieldValue, 'County') elif subFieldKey == 'admin_area': return self.process_generate_field(fieldId + '_6', subFieldValue, 'State/Province') elif subFieldKey == 'postal_code': return self.process_generate_field(fieldId + '_7', subFieldValue, 'Postal Code') elif subFieldKey == 'country': return self.process_generate_field(fieldId + '_8', subFieldValue, 'Country') elif subFieldKey == 'choice_values': choices = [] multiSelectChoices = subFieldValue[0] for choice in subFieldValue: choices.append(choice) if multiSelectChoices != choice: multiSelectChoices += ';' + choice if len(choices) == 1: self.process_generate_field(fieldId, choices, 'Choices') else: return self.process_generate_field(fieldId, multiSelectChoices, 'Multiselect Choices') elif subFieldKey == 'other_values': for choice in subFieldValue: return self.process_generate_field(fieldId, choice, 'Other Choice') # Determine the type of field and process it. This handles files. def detect_file_field_type_and_process_field(self, fieldId, record, recordId, detail=False): fieldValue = '' if detail == False: fieldValue = record['form_values'][fieldId] elif detail == True: fieldValue = record[fieldId] isDictField = isinstance(fieldValue, dict) isListField = isinstance(fieldValue, list) #print fieldValue if isListField == True: for complexFieldValue in fieldValue: #print complexFieldValue isComplexDictField = isinstance(complexFieldValue, dict) if isComplexDictField == True: isRepeatingSections = self.checkKey( complexFieldValue, 'form_values') isPhotoField = self.checkKey(complexFieldValue, 'photo_id') isVideoField = self.checkKey(complexFieldValue, 'video_id') isAudioField = self.checkKey(complexFieldValue, 'audio_id') if isPhotoField == True: print "Photo Field Detected..." return self.process_photo_field( complexFieldValue, recordId) elif isVideoField == True: print "Video Field Detected..." return self.process_video_field( complexFieldValue, recordId) elif isAudioField == True: print "Audio Field Detected..." return self.process_audio_field( complexFieldValue, recordId) elif isRepeatingSections == True: print "Child Record Detected..." return self.process_file_fields( complexFieldValue, recordId) elif isDictField == True: isSignatureField = self.checkKey(fieldValue, 'signature_id') if isSignatureField == True: print "Signature Field Detected..." return self.process_signature_field(fieldValue, recordId) # Determine the type of field and process it. This handles data. def detect_field_type_and_process_field(self, fieldId, record, isDateField=_isDateFieldDefault, detail=False): fieldValue = '' if detail == False: fieldValue = record['form_values'][fieldId] elif detail == True: fieldValue = record[fieldId] isListField = isinstance(fieldValue, list) isDictField = isinstance(fieldValue, dict) if isListField == True: for complexFieldValue in fieldValue: isRepeatingSections = self.checkKey(complexFieldValue, 'form_values') isDictComplexField = isinstance(complexFieldValue, dict) isJunctionObject = self.checkKey(complexFieldValue, 'record_id') elif isDictField == True: for subFieldKey in fieldValue: subFieldValue = fieldValue[subFieldKey] return self.process_address_and_choice_field( fieldId, subFieldKey, subFieldValue) # Date Time field elif re.match(r"([0-2][0-9]:[0-5][0-9])", fieldValue): return self.process_datetime_field(record, isDateField, fieldId, fieldValue) # Date field elif re.match(r"([1-2][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9])", fieldValue): #Mark that this loop was a Date, in prep for a Time Field isDateField = fieldId return self.process_date_field(fieldId, fieldValue) #easy field else: return self.process_generate_field(fieldId, fieldValue) def generate_junction_records(self, complexFormValues): return def generate_detail_fields(self, complexFormValues): dict(complexFormValues) sfdcFields = [] for detailRecord in complexFormValues: isDateField = _isDateFieldDefault fieldAppend = self.detect_field_type_and_process_field( detailRecord, complexFormValues, isDateField, True) #print fieldAppend if isinstance(fieldAppend, dict): sfdcFields.append(fieldAppend) if isDateField != detailRecord: isDateField = _isDateFieldDefault sfdcFields = json.dumps(sfdcFields).replace('[', '').replace( ']', '').replace('{', '').replace('}', '') return sfdcFields def generate_fields(self, record): sfdcFields = [] isDateField = _isDateFieldDefault #print record for fieldId in record['form_values']: fieldAppend = self.detect_field_type_and_process_field( fieldId, record, isDateField) #print fieldAppend if isinstance(fieldAppend, dict): sfdcFields.append(fieldAppend) # If this Loop was not a Date Field, Reset Back to Default Value if isDateField != fieldId: isDateField = _isDateFieldDefault sfdcFields = json.dumps(sfdcFields).replace('[', '').replace( ']', '').replace('{', '').replace('}', '') return sfdcFields def create_sfdc_fulcrum_record(self, record): objectId = (_sfdcPrefix + record['form_id'] + '__c').replace('-', '_') sfdcCreateRecords = self.generate_sfdc_fulcrum_record(record) sfdcCreateRecords = json.loads(sfdcCreateRecords) return fulcrumToSalesforce.composite_salesforce_create( objectId, sfdcCreateRecords) def update_sfdc_fulcrum_record(self, record): objectId = (_sfdcPrefix + record['form_id'] + '__c').replace('-', '_') sfdcObject = SFType(objectId, self.sfdc.session_id, self.sfdc.sf_instance) recordExists = sfdcObject.get_by_custom_id( _sfdcPrefix + 'fulcrum_id__c', record['id']) if recordExists: ## Get Child Records for fieldId in record['form_values']: fieldValue = record['form_values'][fieldId] isListField = isinstance(fieldValue, list) if isListField == True: complexFieldType = fieldValue[0] isRepeatingSections = self.checkKey( complexFieldType, 'form_values') isJunctioonObject = self.checkKey(complexFieldType, 'record_id') if isRepeatingSections == True: objectId = _sfdcPrefix + record['form_id'][ 0:13].replace('-', '_') + '_' + fieldId + '_d__c' objectReferenceId = _sfdcPrefix + record['form_id'][ 0:13].replace('-', '_') + '_' + fieldId + '_d__r' sfdcInsertRecord = '' for complexFieldValue in fieldValue: detailRecordExists = sfdcObject.get_by_custom_id( _sfdcPrefix + 'fulcrum_id__c', complexFieldValue['id']) if detailRecordExists: sfdcRecordUpdate = generate_sfdc_fulcrum_detail_record( self, complexFieldValue) print sfdcRecordUpdate exit() else: self.create_sfdc_fulcrum_record(record) def generate_sfdc_fulcrum_record(self, record): print '---------------------------------------' print 'Processing Fulcrum Record...' objectId = (_sfdcPrefix + record['form_id'] + '__c').replace('-', '_') sfdcRecord = self.standard_fields_master_record(record) sfdcFields = self.generate_fields(record) objectIdString = '"' + objectId + '"' recordIdString = '"' + record['id'] + '"' sfdcRecord = json.dumps(sfdcRecord).replace('[', '').replace( ']', '').replace('{', '').replace('}', '') sfdcDetailRecords = self.generate_sfdc_fulcrum_detail_records(record) if sfdcDetailRecords is None: sfdcRecord = """{"records": [{"attributes": {"type" : """ + objectIdString + """, "referenceId": """ + recordIdString + """ }, """ + sfdcRecord + ',' + sfdcFields + """ }]}""" else: detailRecordJson = sfdcDetailRecords[0] for detailRecord in sfdcDetailRecords: if detailRecord != detailRecordJson: detailRecordJson += "," + detailRecordJson sfdcRecord = """{"records": [{"attributes": {"type" : """ + objectIdString + """, "referenceId": """ + recordIdString + """ }, """ + sfdcRecord + ',' + sfdcFields + ', ' + detailRecordJson + """ }]}""" return sfdcRecord def generate_sfdc_fulcrum_detail_record(self, complexFieldValue): complexFormValues = complexFieldValue['form_values'] sfdcFields = self.generate_detail_fields(complexFormValues) objectIdString = '"' + objectId + '"' recordIdString = '"' + complexFieldValue['id'] + '"' #sfdcRecord = json.dumps (sfdcRecord).replace('[','').replace(']','').replace('{','').replace('}','') sfdcRecord = json.dumps(sfdcRecord).replace('[', '').replace( ']', '').replace('{', '').replace('}', '') sfdcRecord = """, { "attributes": {"type" : """ + objectIdString + """ , "referenceId": """ + recordIdString + """ }, """ + sfdcRecord + ',' + sfdcFields + """ }""" sfdcInsertRecord += sfdcRecord def standard_fields_master_record(self, record): sfdcRecord = [] if record['status'] is not None: sfdcRecord.append( self.process_generate_field('status', record['status'], 'Status')) if record['version'] is not None: sfdcRecord.append( self.process_generate_field('version', record['version'], 'Version')) if record['id'] is not None: sfdcRecord.append( self.process_generate_field('fulcrum_id', record['id'], 'Id')) if record['created_at'] is not None: sfdcRecord.append( self.process_generate_field('created_at', record['created_at'], 'Created At')) if record['updated_at'] is not None: sfdcRecord.append( self.process_generate_field('updated_at', record['updated_at'], 'Updated At')) if record['client_created_at'] is not None: sfdcRecord.append( self.process_generate_field('client_created_at', record['client_created_at'], 'Client Created At')) if record['client_updated_at'] is not None: sfdcRecord.append( self.process_generate_field('client_updated_at', record['client_updated_at'], 'Client Updated At')) if record['created_by'] is not None: sfdcRecord.append( self.process_generate_field('created_by', record['created_by'], 'Created By')) if record['created_by_id'] is not None: sfdcRecord.append( self.process_generate_field('created_by_id', record['created_by_id'], 'Created By Id')) if record['updated_by'] is not None: sfdcRecord.append( self.process_generate_field('updated_by', record['updated_by'], 'Updated By')) if record['updated_by_id'] is not None: sfdcRecord.append( self.process_generate_field('updated_by_id', record['updated_by_id'], 'Updated By Id')) if record['created_location'] is not None: sfdcRecord.append( self.process_generate_field('created_location', record['created_location'], 'Created Location')) if record['updated_location'] is not None: sfdcRecord.append( self.process_generate_field('updated_location', record['updated_location'], 'Updated Location')) if record['created_duration'] is not None: sfdcRecord.append( self.process_generate_field('created_duration', record['created_duration'], 'Created Duration')) if record['updated_duration'] is not None: sfdcRecord.append( self.process_generate_field('updated_duration', record['updated_duration'], 'Updated Duration')) if record['edited_duration'] is not None: sfdcRecord.append( self.process_generate_field('edited_duration', record['edited_duration'], 'Edited Duration')) if record['project_id'] is not None: sfdcRecord.append( self.process_generate_field('project_id', record['project_id'], 'Project Id')) if record['changeset_id'] is not None: sfdcRecord.append( self.process_generate_field('changeset_id', record['changeset_id'], 'Change Set ID')) if record['assigned_to'] is not None: sfdcRecord.append( self.process_generate_field('assigned_to', record['assigned_to'], 'Assigned To')) if record['assigned_to_id'] is not None: sfdcRecord.append( self.process_generate_field('assigned_to_id', record['assigned_to_id'], 'Assigned To Id')) if record['form_id'] is not None: sfdcRecord.append( self.process_generate_field('form_id', record['form_id'], 'Form Id')) if record['latitude'] is not None: sfdcRecord.append( self.process_generate_field('location', record['latitude'], 'Latitude')) if record['longitude'] is not None: sfdcRecord.append( self.process_generate_field('location', record['longitude'], 'Longitude')) if record['speed'] is not None: sfdcRecord.append( self.process_generate_field('speed', record['speed'], 'Speed')) if record['course'] is not None: sfdcRecord.append( self.process_generate_field('course', record['course'], 'Course')) if record['horizontal_accuracy'] is not None: sfdcRecord.append( self.process_generate_field('horizontal_accuracy', record['horizontal_accuracy'], 'Horizontal Accuracy')) if record['vertical_accuracy'] is not None: sfdcRecord.append( self.process_generate_field('vertical_accuracy', record['vertical_accuracy'], 'Vertical Accuracy')) return sfdcRecord def standard_fields_detail_record(self, complexFieldValue): sfdcRecord = [] if complexFieldValue['version'] is not None: sfdcRecord.append( self.process_generate_field('version', complexFieldValue['version'], 'Version')) if complexFieldValue['id'] is not None: sfdcRecord.append( self.process_generate_field('fulcrum_id', complexFieldValue['id'], 'Id')) if complexFieldValue['created_at'] is not None: sfdcRecord.append( self.process_generate_field('created_at', complexFieldValue['created_at'], 'Created At')) if complexFieldValue['updated_at'] is not None: sfdcRecord.append( self.process_generate_field('updated_at', complexFieldValue['updated_at'], 'Updated At')) if complexFieldValue['created_by_id'] is not None: sfdcRecord.append( self.process_generate_field('created_by_id', complexFieldValue['created_by_id'], 'Created By Id')) if complexFieldValue['updated_by_id'] is not None: sfdcRecord.append( self.process_generate_field('updated_by_id', complexFieldValue['updated_by_id'], 'Updated By Id')) if complexFieldValue['created_duration'] is not None: sfdcRecord.append( self.process_generate_field( 'created_duration', complexFieldValue['created_duration'], 'Created Duration')) if complexFieldValue['updated_duration'] is not None: sfdcRecord.append( self.process_generate_field( 'updated_duration', complexFieldValue['updated_duration'], 'Updated Duration')) if complexFieldValue['edited_duration'] is not None: sfdcRecord.append( self.process_generate_field( 'edited_duration', complexFieldValue['edited_duration'], 'Edited Duration')) if complexFieldValue['changeset_id'] is not None: sfdcRecord.append( self.process_generate_field('changeset_id', complexFieldValue['changeset_id'], 'Change Set ID')) if complexFieldValue['geometry'] is not None: sfdcRecord.append( self.process_generate_field( 'location', complexFieldValue['geometry']['coordinates'][1], 'Latitude')) sfdcRecord.append( self.process_generate_field( 'location', complexFieldValue['geometry']['coordinates'][0], 'Longitude')) return sfdcRecord # Fulcrum Record and SFDC Parent Record ID (prefix and postfix added) def generate_sfdc_fulcrum_detail_records(self, record): print '.......................................' print 'Processing Fulcrum Detail Records...' sfdcRecords = [] for fieldId in record['form_values']: fieldValue = record['form_values'][fieldId] isListField = isinstance(fieldValue, list) if isListField == True: complexFieldType = fieldValue[0] isRepeatingSections = self.checkKey(complexFieldType, 'form_values') if isRepeatingSections == True: sfdcInsertRecord = '' objectId = _sfdcPrefix + record['form_id'][0:13].replace( '-', '_') + '_' + fieldId + '_d__c' objectReferenceId = _sfdcPrefix + record['form_id'][ 0:13].replace('-', '_') + '_' + fieldId + '_d__r' for complexFieldValue in fieldValue: print '.......................................' print 'Processing Detail Record...' print ' Object: ' + objectId print ' ReferenceName: ' + objectReferenceId sfdcRecord = self.standard_fields_detail_record( complexFieldValue) complexFormValues = complexFieldValue['form_values'] sfdcFields = self.generate_detail_fields( complexFormValues) objectIdString = '"' + objectId + '"' recordIdString = '"' + complexFieldValue['id'] + '"' #sfdcRecord = json.dumps (sfdcRecord).replace('[','').replace(']','').replace('{','').replace('}','') sfdcRecord = json.dumps(sfdcRecord).replace( '[', '').replace(']', '').replace('{', '').replace('}', '') sfdcRecord = """, { "attributes": {"type" : """ + objectIdString + """ , "referenceId": """ + recordIdString + """ }, """ + sfdcRecord + ',' + sfdcFields + """ }""" sfdcInsertRecord += sfdcRecord objectReferenceIdString = '"' + str( objectReferenceId) + '"' sfdcInsertRecord = sfdcInsertRecord.replace(',', "", 1) recordJson = objectReferenceIdString + """:{"records":[""" + sfdcInsertRecord + """]}""" sfdcRecords.append(recordJson) return sfdcRecords
def forceBeWithYou(): return Salesforce(username=username, password=password, security_token=accessToken)
from flask import Flask from flask_cors import CORS import os # for environment variables from flask import request, jsonify # imported for parsing arguemnts from simple_salesforce import Salesforce, format_soql # import Salesforce from auth import AuthError, requires_auth import json # global connection to Salesforce so we don't need to connect everytime sf = Salesforce(username=os.environ['SALESFORCE_USERNAME'], password=os.environ['SALESFORCE_PASSWORD'], security_token=os.environ['SALESFORCE_SECURITY_TOKEN']) app = Flask(__name__) app.config['JSON_SORT_KEYS'] = False CORS(app) pod_names = [ 'Trainee_POD_Map__c', 'Associate_POD_Map__c', 'Partner_POD_Map__c' ] @app.route("/starredTasks") @requires_auth(sf) def getStarredTasks(user): """ Gets a list of starred tasks, for display on the favorate tab. """ user_id = user.get('id') full_res = [] pod_data = findValid(user)
SF_connected = False try: logging.info( 'Trying to load previously saved credentials if any were saved on this machine' ) # here we are loading saved user credentials if any exists except Exception: logging.error( 'No saved credentials were found, prompting save-creds dialog') SF_username, SF_password, SF_security_token = save_credentials_dialog() while SF_connected is False: try: SF_connection = Salesforce(username=SF_username, password=SF_password, security_token=SF_security_token) SF_connected = True except simple_salesforce.exceptions.SalesforceAuthenticationFailed as error: logging.error( 'Failed to connect to SalesForce due to the following error:\n' + str(error)) logging.info( 'Need to find any better credentials, please, submit them here:') SF_username, SF_password, SF_security_token = save_credentials_dialog() except TypeError as error: logging.error( 'Failed to connect to SalesForce due to the following error:\n' + str(error)) logging.info(
def test_responses_activated_after(): """ Verify we can activate a user-defined `responses` at the bottom of our Mockforce mocks """ Salesforce(**MOCK_CREDS)
def test_responses_activated_before(): """ Verify we can activate a user-defined `responses` on top of our Mockforce mocks """ Salesforce(**MOCK_CREDS)
def connect_sf(config_data): sf = Salesforce(username=config_data['username'], password=config_data['passwd'], security_token=config_data['token'], sandbox=True) return sf
username = '' password = '' security_token = '' domain = 'login' convert_currency = True format_currency = True sobject_list = ['Account', 'Contact'] file_name = 'soql.csv' # Application name to display in Salesforce login audit CLIENT_ID = 'SOQLGEN' # Create Simple Salesforce instance sf = Salesforce(username=username, password=password, security_token=security_token, domain=domain, client_id=CLIENT_ID) def describe_sobject(sobjectname): sobject = SFType(sobjectname, session_id=sf.session_id, sf_instance=sf.sf_instance) return sobject.describe() def create_sobject(sobjectdescribe): sobject = SObject(sobjectdescribe['label'], apiname=sobjectdescribe['name'])
from sqlalchemy import sql, create_engine, text engine = create_engine('mssql+pymssql://sysdba:[email protected]:1433/ESIDB') from simple_salesforce import Salesforce import salesforce_reporting import requests, json from flask import jsonify sf = Salesforce(username='******', password='******', security_token='3GKZny4jRWgmXNUmvFjzKhggQ') analytic_sf = salesforce_reporting.Connection( '3MVG99OxTyEMCQ3glBkdKh4SE2HJs4uODXEl2Fux.LFlCzqkgs9Tr8XLqmCvUsOSdsVpbGoj9xhN5f4hpJ2OZ', '86072956447270870', '*****@*****.**', 'password123453GKZny4jRWgmXNUmvFjzKhggQ', 'na13') try: mydict = sf.Solution.create({ 'SolutionNote': 'testALM', 'SolutionName': 'testALM' }) except Exception as e: print(str(e)) # def FillSFDC7(*mydict): # try: # with engine.connect() as con: # dict=mydict[0] # val=dict.values() # key=dict.keys() # rs = con.execute('INSERT INTO [SFDC7]([Sales Order Number] )' # 'values('+ val[0] +')') # con.close()
# my_email_to = "*****@*****.**" my_email_to_err = [ '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**' ] my_subj = "Failed - Leads for: " + email_file_processed + " !! Please check Log file for errors !!" my_body = " \n" + ' --- Number of Leads successfully Processed: ' + str_items_updated + " \n" + " Lead Items Failed: " + str_items_failed + " \n" + " Total Leads Processed: " + str_tot_items + my_err_list my_email_body = 'Subject: {}\n\n{}'.format(my_subj, my_body) server.sendmail(my_email_from, my_email_to_err, my_email_body) server.quit() # sign on to Sales Force try: sf = Salesforce(username=my_sf_user, password=my_sf_pass, security_token=my_sf_token, instance_url=my_sf_instance) except Exception as e: error_msg = str(e) error_msg = error_msg send_err_email("1") fatal_err(error_msg) # Check if there is a file to process if len(os.listdir(dir_in)) == 0: my_log_msg = (d_str + " *** No Files Found to Process ** " + "\n") log_file.write(my_log_msg) log_file.close() sys.exit("** No Files Found to Process **") # Get list of files to Process
from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText import smtplib import datetime from simple_salesforce import Salesforce import pandas as pd cur_date = datetime.datetime.now().strftime("%Y-%m-%d") sf = Salesforce(username='******', password='', security_token='') query1 = sf.query( "SELECT Lead_Created_Date__c , PT_Lead_Stage__c, PT_Lead_ID__c FROM Account WHERE CreatedDate >= LAST_N_DAYS:14 AND FulFillment_id__c IN ('0',NULL) AND Fulfillment_Service_Id_For_Digital_Merch__c IN ('0', NULL) AND Agent_Code__c LIKE '%sym%'" ) df1 = pd.DataFrame(query1) result = pd.concat(frames, ignore_index=True) i = len(result.index) s = str(i) msg = MIMEMultipart() msg['From'] = "*****@*****.**" To = ["*****@*****.**"] password = "******" msg['Subject'] = "O2O Onboarding Score : " + cur_date body = """\ <html> <head> <style>
NPQ_COURSES = { '324': 'NPQML', '305': 'NPQH', '325': 'NPQSL', '326': 'NPQEL', } logging.getLogger().setLevel(os.environ.get('LOG_LEVEL', 'DEBUG')) domain = os.environ.get('SALESFORCE_DOMAIN', 'test') session_id, instance = SalesforceLogin(username=os.environ['SALESFORCE_USER'], password=os.environ['SALESFORCE_PASSWORD'], security_token=os.environ['SALESFORCE_SECURITY_TOKEN'], domain=domain) sf = Salesforce(instance=instance, session_id=session_id, domain=domain) def complete_details(detail, participant, date): return detail.replace('<participant>', '' if None == participant else participant).replace('<date>', date[:10]) def lambda_handler(event, context): for record in event['Records']: payload = str(record["body"]) payloads = json.loads(payload)['data'] logging.debug(payload) for payload in payloads: try: actor = payload['actor'] typev = payload['type'] action = payload['action']
def futureInstallData(installList): # installList = ['134662'] recipients = ['*****@*****.**','*****@*****.**','*****@*****.**'] msg = MIMEMultipart() today = str(datetime.today())[:10] msg.preamble = 'Multipart massage.\n' if datetime.today().weekday() == 4: msg['Subject'] = "Prepareing Install Packs For Next Mon & Tue" else: msg['Subject'] = "Prepareing Install Packs For " + str(datetime.today() + timedelta(2))[:10] + "(" + calendar.day_name[(datetime.today() + timedelta(2)).weekday()][:3] + ")" sf = Salesforce(username='******', password='******', security_token='yWlJG8lAKCq1pTBkbBMSVcKg') response = sf.query_all("SELECT Contact_Opp__r.County__c, Contact_Opp__r.FirstName, Contact_Opp__r.LastName, Contact_Opp__r.Name, Contact_Opp__r.Address__c, Contact_Opp__r.City_State_Zip__c, Contact_Opp__r.LASERCA__Home_State__c, Account_Number__c, id, Account.AD_Template__c, System_Size_KW__c, Installed_Panels_Model__c, Installed_Inverter_1__c, Installed_Inverter_2__c, Estimated_Production_kWh__c, No_of_Installed_Panels__c,box_install__c, CAD_Specialist__r.Name, CAD_Specialist__r.Personal_Mobile__c, CAD_Specialist__r.DivisionManager__r.Name, CAD_Specialist__r.DivisionManager__r.Personal_Mobile__c, (select Id, Status, EstimatedProductionKWH__c, DesignArrayOutputKW__c FROM Cases__r WHERE (Record_Type_Bucket__c = 'design' OR Record_Type_Bucket__c = 'Design') and Status = 'Closed'), (SELECT ScheduledDate__c FROM interactions__r WHERE interaction__c.Opportunity__r.InstallDate__c = Null and Subject__c = 'Installation' AND Canceled__c = false) FROM Opportunity WHERE Account_Number__c in " + str(installList).replace('[','(').replace(']',')').replace(' ','').replace('u','')) print json.dumps(response, indent=4, sort_keys=True) queryResult = {} designNotClosed = [] missingInfo = [] notDone = [] for item in response['records']: if item['Cases__r']: info = {} info['preFix'] = str(item['Account_Number__c']) + ' ' + item['Contact_Opp__r']['Name'] print info['preFix'] info['name'] = item['Contact_Opp__r']['Name'] info['idName'] = str(item['Account_Number__c']) + ' - ' + item['Contact_Opp__r']['Name'] info['cityStateZip'] = item['Contact_Opp__r']['City_State_Zip__c'] info['fullAddress'] = item['Contact_Opp__r']['Address__c'] info['CADTemp'] = item['Account']['AD_Template__c'] info['pvSize'] = str(item['System_Size_KW__c']) + ' kW' if (item['System_Size_KW__c'] and item['System_Size_KW__c'] > 0) else str(item['Cases__r']['records'][0]['DesignArrayOutputKW__c']) info['production'] = str(int(round(int(item['Estimated_Production_kWh__c'].split('.')[0]) * 19.07 , -2))) if (item['Estimated_Production_kWh__c'] and item['Estimated_Production_kWh__c'] > 0) else str(int(round(int(item['Cases__r']['records'][0]['EstimatedProductionKWH__c'].split('.')[0]) * 19.07 , -2))) info['panelNum'] = str(int(item['No_of_Installed_Panels__c'])) if item['No_of_Installed_Panels__c'] else None info['inverterNum'] = '2' if item['Installed_Inverter_2__c'] != None else '1' info['panelMan'] = panelManufactory[item['Installed_Panels_Model__c']] if item['Installed_Panels_Model__c'] else None # info['CAD'] = str(item['CAD_Specialist__r']['Name']) # info['CADPhone'] = str(item['CAD_Specialist__r']['Personal_Mobile__c']) info['scheduledDate'] = str(item['Interactions__r']['records'][0]['ScheduledDate__c'])[:10] try: if item['Installed_Inverter_1__c'].find(';') > -1: info['inverterMan'] = inverterManufactory[item['Installed_Inverter_1__c'].split(';')[0]] info['inverterNum'] = '2' else: info['inverterMan'] = inverterManufactory[item['Installed_Inverter_1__c']] if item['Installed_Inverter_1__c'] else None except: info['inverterMan'] = None info['installpackId'] = None try: info['opsBox'] = opsBox[item['Contact_Opp__r']['County__c']] if item['Contact_Opp__r']['LASERCA__Home_State__c'] <> 'MA' else opsBox['Massachussets'] # info['CADMan'] = opsManager[item['Contact_Opp__r']['County__c']]['Name'] if item['Contact_Opp__r']['LASERCA__Home_State__c'] <> 'MA' else opsManager['Massachussets']['Name'] # info['CADManPhone'] = opsManager[item['Contact_Opp__r']['County__c']]['Phone'] if item['Contact_Opp__r']['LASERCA__Home_State__c'] <> 'MA' else opsManager['Massachussets']['Phone'] except: info['opsBox'] = opsBox['Massachussets'] # info['CADMan'] = opsManager['Massachussets']['Name'] # info['CADManPhone'] = opsManager['Massachussets']['Phone'] if item['box_install__c']: info['installId'] = item['box_install__c'] token = boxToken() headers = {'Authorization': 'Bearer ' + token} json_r = requests.get('https://api.box.com/2.0/folders/' + item['box_install__c'] + '/items?limit=1000', headers=headers).json() try: for file in json_r['entries']: if file['type'] == 'file' and file['name'].upper().find('12 INSTALL PACK.PDF') > -1: info['installpackId']=file['id'] except: url = urlHome + 'boxid/'+item['Account_Number__c'] + '?api_key=Jo3y1SAW3S0M3' try: response = requests.get(url).json() info['installpackId']=response['file9'] if response['file9'] != 'no' else None info['installId'] = response['IN_id'] except: info['installpackId'] = None info['installId'] = None else: url = urlHome + 'boxid/'+item['Account_Number__c'] + '?api_key=Jo3y1SAW3S0M3' try: response = requests.get(url).json() info['installpackId']=response['file9'] if response['file9'] != 'no' else None info['installId'] = response['IN_id'] except: info['installpackId'] = None info['installId'] = None if len(info) == len(dict([(k,v) for k,v in info.items() if v is not None])): queryResult[item['Account_Number__c']] = {'accountNumber':item['Account_Number__c']} queryResult[item['Account_Number__c']].update(info) else: print json.dumps(info, indent=4, sort_keys=True) missingInfo.append(item['Account_Number__c']) else: designNotClosed.append(item['Account_Number__c']) print json.dumps(queryResult, indent=4, sort_keys=True) print 'Total ready: ' + str(len(queryResult)) print 'Design Case Not Closed: ' + str(designNotClosed) print 'Missing Info: ' + str(missingInfo) if len(installList) > 1: msgBody = 'Upcoming Scheduled Install: ' + str(len(installList)) + '\n' # msgBody = msgBody + 'Install Packs Ready: ' + str(len(queryResult)) + '\n' part = MIMEText(msgBody) msg.attach(part) # notDone = installPackPDF(queryResult) for custum in queryResult: try: name = queryResult[custum]['name'] fullAddress = queryResult[custum]['fullAddress'] cityStateZip = queryResult[custum]['cityStateZip'] pvSize = queryResult[custum]['pvSize'] panelNum = queryResult[custum]['panelNum'] panelMan = queryResult[custum]['panelMan'] inverterNum = queryResult[custum]['inverterNum'] inverterMan = queryResult[custum]['inverterMan'] production = queryResult[custum]['production'] CADTemp = queryResult[custum]['CADTemp'] installDate = queryResult[custum]['scheduledDate'] # CAD = queryResult[custum]['CAD'] # CADMan = queryResult[custum]['CADMan'] # CADManPhone = queryResult[custum]['CADManPhone'] # CADPhone = queryResult[custum]['CADPhone'] nameOut = "Filled.pdf" if CADTemp == 'NY-1': pathTemp = pdfPath + "System Design Authorization - LI.pdf" txtLocation = [txtGen(name,[190,520]), txtGen(production,[217,622]), txtGen(fullAddress,[190,502]), txtGen(cityStateZip,[190,484]), txtGen('$0',[190,465]), txtGen(installDate,[190,446]), txtGen(str(pvSize),[463,520]), txtGen(str(panelNum),[463,502]), txtGen(panelMan,[463,484]), txtGen(str(inverterNum),[463,465]), txtGen(inverterMan,[463,447]), txtGen('SolarEdge',[463,429])] writePage(pathTemp, pdfPath, nameOut, txtLocation,False) elif CADTemp == 'NY-2': pathTemp = pdfPath + "System Design Authorization - NYC.pdf" txtLocation = [txtGen(name,[190,520+85]), txtGen(production,[270,657]), txtGen(fullAddress,[190,502+85]), txtGen(cityStateZip,[190,484+85]), txtGen('$0',[190,465+85]), txtGen(installDate,[190,446+85]), txtGen(str(pvSize),[463,520+85]), txtGen(str(panelNum),[463,502+85]), txtGen(panelMan,[463,484+85]), txtGen(str(inverterNum),[463,465+85]), txtGen(inverterMan,[463,447+85]), txtGen('SolarEdge',[463,429+85])] writePage(pathTemp, pdfPath, nameOut, txtLocation,False) elif CADTemp == 'MA': pathTemp = pdfPath + "System Design Authorization - MA.pdf" txtLocation = [txtGen(name,[190,520]), txtGen(production,[467,608]), txtGen(fullAddress,[190,502]), txtGen(cityStateZip,[190,484]), txtGen('$0',[190,465]), txtGen(installDate,[190,446]), txtGen(str(pvSize),[463,520]), txtGen(str(panelNum),[463,502]), txtGen(panelMan,[463,484]), txtGen(str(inverterNum),[463,465]), txtGen(inverterMan,[463,447]), txtGen('SolarEdge',[463,429])] writePage(pathTemp, pdfPath, nameOut, txtLocation,False) else: notDone.append(custum) token = boxToken() headers = {'Authorization': 'Bearer ' + token} url = 'https://api.box.com/2.0/files/'+queryResult[custum]['installpackId']+'/content' response = requests.get(url, headers=headers) pdfFile = open(pdfPath + "delete.pdf", "wb") pdfFile.write(response.content) pdfFile.close() print readPdf(pdfPath + 'delete.pdf','Secondary Contact name') print readPdf(pdfPath + 'delete.pdf','Bill Of Materials') with open(pdfPath + 'Filled.pdf', "rb") as f1, open(pdfPath + 'delete.pdf', "rb") as f2, open(pdfPath + 'empty.pdf', "wb") as outputStream: file1 = PdfFileReader(f1, 'rb') file2 = PdfFileReader(f2, 'rb') output = PdfFileWriter() if readPdf(pdfPath + 'delete.pdf','Bill Of Materials') == 2: output.addPage(file2.getPage(0)) output.addPage(file2.getPage(1)) output.addPage(file1.getPage(0)) for i in range(3,file2.numPages): output.addPage(file2.getPage(i)) elif readPdf(pdfPath + 'delete.pdf','Bill Of Materials') == 8: output.addPage(file2.getPage(0)) output.addPage(file2.getPage(1)) output.addPage(file2.getPage(2)) output.addPage(file2.getPage(3)) output.addPage(file2.getPage(4)) output.addPage(file2.getPage(5)) output.addPage(file2.getPage(6)) output.addPage(file2.getPage(7)) output.addPage(file1.getPage(0)) for i in range(9,file2.numPages): output.addPage(file2.getPage(i)) else: output.addPage(file2.getPage(0)) output.addPage(file1.getPage(0)) for i in range(2,file2.numPages): output.addPage(file2.getPage(i)) output.write(outputStream) outputStream.close() with open(pdfPath + 'empty.pdf', "rb") as output: url = 'https://upload.box.com/api/2.0/files/content' # print output files = { 'filename': (str(custum) + ' ' + name+' - 12 Install Pack.pdf', output.read()) } data = { "parent_id": queryResult[custum]['installId'] } # tryBox(url, data, files, headers) data = { "parent_id": queryResult[custum]['opsBox'] } tryBox(url, data, files, headers) print str(custum) + ' install pack is ready.' except Exception as e: notDone.append(custum) print str(custum) + ' broken: ' + str(e) print queryResult[custum] if len(designNotClosed) <> 0 or len(missingInfo) <> 0 or len(notDone) <> 0: msgBody = '--------------------------------------------------\n' msgBody = msgBody + 'AD please take a look into the following cases and prepare the Install Pack.\n' msgBody = msgBody + 'Design Case Not Closed: ' + str(designNotClosed) + '\n' if len(designNotClosed) > 0 else msgBody msgBody = msgBody + 'SF Info Incomplete: ' + str(missingInfo) + '\n' if len(missingInfo) > 0 else msgBody msgBody = msgBody + 'Document Corrupted: ' + str(notDone) + '\n' if len(notDone) > 0 else msgBody part = MIMEText(msgBody) msg.attach(part) if len(installList) > 1: pythonSendEmail(msg, recipients) return notDone
import boto3 import io from simple_salesforce import Salesforce import requests import os from ftplib import FTP s3 = boto3.resource('s3') sf = Salesforce(username='******', password='******', security_token='<TOKEN>', domain='test') sessionId = sf.session_id instance = sf.sf_instance print ('sessionId: ' + sessionId) #HARDCODED HERE FOR ILLUSTRATION fileid = 'ID of Attachment' attachment = sf.query("SELECT Id, Name, Body FROM Attachment where Id='" + fileid + "' LIMIT 1") filename=attachment['records'][0]['Name'] print('filename: ' + filename) response = requests.get('https://' + instance + '/services/data/v39.0/sobjects/Attachment/' + fileid + '/body', headers = { 'Authorization': 'Bearer ' + sessionId })
from simple_salesforce import Salesforce sf = Salesforce(username='', password='', security_token='') #report name 00O15000007XxMm
def get_session(self, username, password, token): return Salesforce( username=username, password=password, security_token=token, )
def get_salesforce_connection(session=None): """Connect to Salesforce.""" return Salesforce(username=SALESFORCE_CREDENTIALS['USERNAME'], password=SALESFORCE_CREDENTIALS['PASSWORD'], security_token=SALESFORCE_CREDENTIALS['SECURITY_TOKEN'], session=session)
# Iterate through FULFILLED Squarespace orders and add them to Salesforce as Opportunties def processOrders(): for order in store.orders( fulfillmentStatus='FULFILLED', modifiedAfter=max_closed_date, modifiedBefore=cur_date): # Iterate through 20 orders if (float(order['orderNumber']) > max_id): lookupContact(order) try: while store.next_page() is not None: for order in store.next_page( ): # Iterate through another 20 orders if (float(order['orderNumber']) > max_id): lookupContact(order) except Exception as e: print(e) # Find new orders in Squarespace and add them to Salesforce as Opportunities print("### running square.py --") soql_string = "select max(Squarespace_Order_ID__c) , max(CloseDate) from Opportunity where Squarespace_Order_ID__c != null" sf = Salesforce(username=os.environ.get('SFUSERNAME'), password=os.environ.get('SFPASSWORD'), security_token=os.environ.get('SFTOKEN')) result = sf.query(soql_string) max_id = result['records'][0]['expr0'] max_closed_date = result['records'][0]['expr1'] + 'T00:00:00.900Z' cur_date = str(date.today()) + 'T00:00:00.900Z' store = Squarespace(os.environ.get('SQUARESPACETOKEN')) processOrders()
def run(self): sf = Salesforce(username='******', password='******', security_token='3GKZny4jRWgmXNUmvFjzKhggQ') print( 'NEW START.............................................................................................................' ) for attemt in attemts: # try: # c.close(); # conn5.commit(); # conn5.close(); # # except Exception as e: # print(e) # try: # c.close(); # conn6.commit(); # conn6.close(); # except Exception as e: # print(e) # if attemt=='RHID': db_path=os.path.abspath("\\\\IXI-APPSVR02\\RHID Sustaining Production\\ttproj.db") # if attemt=='RHIT': db_path=os.path.abspath("\\\\IXI-APPSVR02\\RapidHIT Sustaining\\ttproj.db") #while True: #time.sleep(60) # print("After 5 sec") date_S = datetime.now() - timedelta(days=1) date_E = datetime.now() - timedelta(days=0) print(str(date_S)[0:10]) print(attemt) hastrack = False solution = "" try: if attemt == 'RHID': db_path = os.path.abspath( "\\\\IXI-APPSVR02\\RHID Sustaining Production\\ttproj.db" ) if attemt == 'RHIT': db_path = os.path.abspath( "\\\\IXI-APPSVR02\\RapidHIT Sustaining\\ttproj.db") conn5 = sqlite3.connect(db_path) c = conn5.cursor() hourago = datetime.now() - timedelta(hours=1) #s='select DefectNum,Summary,Status from DEFECTS inner join DEFECTEVTS on DEFECTEVTS.ParentID=DEFECTS.idRecord where dateEvent> '+ str(hourago).rpartition(':')[0] # s='select idRecord,DefectNum,Summary,Status,dateModify from DEFECTS where dateModify >'+ repr(str(hourago).rpartition(':')[0]) print(str(date_S).rpartition(':')[0]) #print (str(date_E).rpartition(':')[4]) s = 'select idRecord,DefectNum,Summary,Status,dateModify from DEFECTS where dateModify >=' + repr( str(date_S).rpartition(':')[0]) print(s) #s='select idRecord,DefectNum,Summary,Status,dateModify from DEFECTS where dateModify >='+ repr(str(date_S).rpartition(':')[0]) + ' and dateModify <='+ repr(str(date_E).rpartition(':')[0]) #s='select dateModify,idRecord,DefectNum,Summary,Status,dateModify from DEFECTS where DefectNum =2976' #'+ repr(str(hourago).rpartition(':')[0]) c.execute(s) rows = c.fetchall() defect_as_dict = [] #file = open("sync.txt","w") for row in rows: DefectNum = row[1] print(DefectNum) Summary = row[2] Status = row[3] if attemt == 'RHID': s = 'select Custvalue from CUSTMVAL where idCustRec=681 and ParentID=' + repr( str(row[0])) + '' if attemt == 'RHIT': s = 'select Custvalue from CUSTMVAL where idCustRec=1072 and ParentID=' + repr( str(row[0])) + '' c.execute(s) rows1 = c.fetchall() casenumber = 0 for row1 in rows1: casenumber = row1[0] print(casenumber) #Synceddict=db.search(CN.casenumber == casenumber) s = 'select Name,dateEvent,DEFECTEVTS.Notes ,OrderNum from DEFECTEVTS inner join EVENTS on DEFECTEVTS.EvtDefID=EVENTS.idRecord and ParentID=' + str( row[0]) + ' order by OrderNum' c.execute(s) tracks_as_dict = [] tracktext = "" tracks = c.fetchall() for track in tracks: hastrack = True if (track[0] == "Verified"): solution = track[2] track_as_dict = { 'Event': track[0], 'Date': track[1], 'Notes': track[2] } if (hastrack): tracks_as_dict.append(track_as_dict) tracktext = str(tracks_as_dict) #UPDATE WORKFLOW list = sf.query( "SELECT Id,Defect_Ref__c FROM Case WHERE CaseNumber = " + repr(str(casenumber))) dict = list["records"] if len(dict) > 0: cid = dict[0]['Id'] CurrentDefectNumber = dict[0]['Defect_Ref__c'] sf.Case.update(cid, {'Workflow_from_ALM__c': tracktext}) if CurrentDefectNumber is None: #sf.headers({'Sforce-Auto-Assign': 'FALSE'}) sf.Case.update(cid, {'Defect_Ref__c': DefectNum}) #Write the log file = open("C:\Python34\ixi_TBOX34\sync.txt", "a") logstr = "|" + str(casenumber) + "|" + str( DefectNum) + "|" + attemt + "|" + repr( str(datetime.now())) file.write(logstr + "\n") file.close() #UPDATE SOLUTIONS if Status == 10: if (str(solution) != ""): list = sf.query( "SELECT Id FROM Case WHERE CaseNumber = " + repr(str(casenumber))) dict = list["records"] if len(dict) > 0: print(dict[0]['Id']) cid = dict[0]['Id'] mydict = sf.Solution.create({ 'SolutionNote': solution, 'SolutionName': 'solution - ' + Summary }) #db.insert({'casenumber': casenumber}) print(mydict['id']) sid = mydict['id'] solution = sf.Solution.get(mydict['id']) print(mydict['success']) #orderdisc=solution('OrderDict') print(solution['SolutionNumber']) sn = solution['SolutionNumber'] mydict = sf.CaseSolution.create({ 'CaseId': cid, 'SolutionId': sid }) print(mydict) #Update case #file.close() #sf.Case.Update except Exception as e: print(e)
try: response_cases = sf.Case.updated(end - datetime.timedelta(minutes=dmin), end) except: return False #print 'response_cases is OK' new_cases = case_list(response_cases) fields = 'CaseNumber,CreatedDate,Priority,Status' for new_case in new_cases: case_attr = sf.Case.get(new_case+'/?fields='+ fields) if case_attr['Status'] == 'New': TimeUsed,SH_Time = cal_time(case_attr['CreatedDate']) print TimeUsed, SH_Time if TimeUsed: send_mail(case_attr['CaseNumber'],SH_Time,case_attr['Priority'],int(30-TimeUsed)) return True if __name__ == '__main__': s_id = '' sf = Salesforce(instance_url='',session_id=s_id) #print sf while main(sf,300): print '%s: working' % datetime.datetime.now() time.sleep(298) send_mail('Notification System Failure','None','None','None')
def setUpClass(cls): cls.connection = Salesforce( instance_url=os.environ["INSTANCE_URL"], session_id=os.environ["ACCESS_TOKEN"], version="48.0", )
from simple_salesforce import Salesforce import salesforce_reporting import requests, json from flask import jsonify from SFDC import dbmodels sf = Salesforce(username='', password='', security_token='3GKZny4jRWggQ') analytic_sf = salesforce_reporting.Connection( '3MVG99OxTyEMCQ3glBkdKh4SE2HJs4uODXEl2Fux.LFlCzqkgs9Tr8XLqmCvUsOSdsVpbGoj9xhN5f4hpJ2OZ', '86072956447270870', 'cgenx.com', 'passKhggQ', 'na13') report = analytic_sf.get_report('00Oa0000008uK2BEAU', filters=None, details=True) parser = salesforce_reporting.ReportParser(report) dict = parser.records() class Opportunity(): def __int__(self, AccountId, Amount, CloseDate, OwnerId, FiscalYear, CreatedById): self.AccountId = AccountId, self.Amount = Amount, self.CloseDate = CloseDate, self.OwnerId = OwnerId, self.FiscalYear = FiscalYear, self.CreatedById = CreatedById, def Load(self): try: #list=sf.query("SELECT AccountId,Amount,CloseDate,OwnerId,FiscalYear,CreatedById FROM Opportunity ") #sf = Salesforce(username='******', password='******', security_token='3GKZny4jRWgmXNUmvFjzKhggQ')
def download_attachments_all(user_v, passwd_v, case_v, token_v, storage_v, new_dir): session = requests.Session() #new_dir = "{}\{}".format(storage_v, case_v) logging.info("New Directory is {}".format(new_dir)) if not os.path.exists(new_dir): #check this line - is it needed? new_dir = "{}\{}".format(storage_v, case_v) os.mkdir(new_dir) logging.debug("Storage path doesn't exist yet - folder {} created".format(case_v)) if not os.path.isdir(storage_v): logging.error("ERROR: Storage path must be a directory") sys.exit(1) logging.basicConfig(level = logging.DEBUG, format = '%(asctime)s - %(levelname)s - %(message)s', filemode = 'w', filename = 'sfdc_log.log') try: sf = Salesforce(username = user_v, password = passwd_v, security_token = token_v, session = session) except: logging.error("Failed to connect SFDC") return auth_id = "Bearer " + sf.session_id req_headers = {'Authorization': auth_id} query_case_id = ("SELECT Id FROM Case WHERE Casenumber = '{}'".format(case_v)) result_case = sf.query(query_case_id) print("Running query 2: {}\n".format(query_case_id)) logging.info("Running query: {}".format(query_case_id)) print("Query 2 result is: {}\n".format(result_case)) try: case_sfdc_id = result_case.get('records')[0].get('Id') logging.debug("The case id is: {}".format(case_sfdc_id)) print("The case id is: {}\n".format(case_sfdc_id)) except: return query = ("SELECT Id, ParentId, Name, Body, BodyLength FROM Attachment WHERE" " ParentId IN (SELECT Id FROM EmailMessage WHERE ParentId = '{}')" " AND BodyLength > 2000 AND BodyLength != 6912 " # " AND (Name LIKE '%.jpg' OR Name LIKE '%.png' OR Name LIKE '%.gif')" " AND IsDeleted = False LIMIT 100".format(case_sfdc_id)) result = sf.query(query) print("Running query 3: {}\n".format(query)) logging.info("Running query: {}".format(query)) print("Query 3 result is: {}\n".format(result)) total_records = result.get('totalSize', 0) print('Total records retrieved: {}'.format(total_records)) storage_dir = new_dir sf_pod = sf.base_url.replace("https://", "").split('.salesforce.com')[0] logging.info('Starting to download {} attachments'.format(total_records)) records = result.get('records', {}) distinct_ids = [] for record in records: if record.get('BodyLength') not in distinct_ids: distinct_ids.append(record.get('BodyLength')) print(distinct_ids) body_uri = record.get('Body') if not body_uri: logging.warning("No body URI for file id {}".format(record.get('Id', ''))) # continue remote_file = record.get('Name') remote_file_lower = remote_file.lower() remote_path = "https://{}.salesforce.com{}".format(sf_pod, body_uri) local_file = "{}_{}".format(record.get('Id'), remote_file) local_path = os.path.join(new_dir, local_file) logging.info("Downloading {} to {}".format(remote_file, local_path)) logging.debug("Remote URL: {}".format(remote_path)) response = session.get(remote_path, headers=req_headers) if response.status_code != 200: logging.error("Download failed {}".format(response.status_code)) continue with open(local_path, 'wb') as out_file: out_file.write(response.content) else: print("Photo {} already exists".format(len(distinct_ids)))