33
44with open ("new_ldot_workflows/qualtrics_config.json" ) as f :
55 config = json .load (f )
6- CLIENT_ID = config ["client_id" ]
7- CLIENT_SECRET = config ["client_secret" ]
86QUALTRICS_BASE_URL = config ["QUALTRICS_BASE_URL" ]
7+ HEADERS = config ["HEADERS" ]
98
9+ with open ("new_ldot_workflows/ldot_config.json" ) as f :
10+ config = json .load (f )
11+ CLIENT_ID = config ["client_id" ]
12+ CLIENT_SECRET = config ["client_secret" ]
13+ LDOT_API_URL = config ["LDOT_API_URL" ]
1014
15+ class QualtricsAPIError (Exception ):
16+ """Custom exception for Qualtrics API errors"""
17+ pass
1118
12- def check_contact_in_mailing_list (participant_study_id : str , mailing_list_id : str , directory_id : str ) -> bool :
19+ def check_contact_in_mailing_list (study_identifier : str , mailing_list_id : str , directory_id : str ) -> bool :
1320 """Find who is already in that mailing list, check if the participant's ID is already there."""
1421
1522 print ("Checking for contact in mailing list... " )
@@ -29,18 +36,18 @@ def check_contact_in_mailing_list(participant_study_id: str, mailing_list_id: st
2936
3037 contact_external_data_references = [contact ["extRef" ] for contact in contacts if "extRef" in contact ]
3138
32- if participant_study_id not in contact_external_data_references :
39+ if study_identifier not in contact_external_data_references :
3340 return False
3441 return True
3542
36- def add_contact_to_mailing_list (participant_study_id : str , embedded_data_field : str , mailing_list_id : str , directory_id : str ) -> None :
43+ def add_contact_to_mailing_list (study_identifier : str , embedded_data_field : str , mailing_list_id : str , directory_id : str ) -> None :
3744 """Add contact to a mailing list"""
3845
3946 endpoint = f"{ QUALTRICS_BASE_URL } /directories/{ directory_id } /mailinglists/{ mailing_list_id } /contacts"
4047 contact_information_payload = {
41- "extRef" : participant_study_id ,
48+ "extRef" : study_identifier ,
4249 "embeddedData" : {
43- embedded_data_field : participant_study_id
50+ embedded_data_field : study_identifier
4451 }
4552 }
4653 try :
@@ -56,11 +63,11 @@ def add_contact_to_mailing_list(participant_study_id: str, embedded_data_field:
5663 f"Unexpected response format when adding contact to mailing list."
5764 ) from exc
5865
59- def get_personal_link (qualtrics_survey_id : str , distribution_id : str , participant_study_id : str ) -> str :
66+ def get_personal_link (qualtrics_survey_id : str , distribution_id : str , study_identifier : str ) -> str :
6067 """Get the person link of an individual for a specified survey. Returns personal link for the participant, looks like
6168 https://survey.uu.nl/jfe/form/SV_efCMOg6wHU0T8ii?Q_CHLqe2Pdrma&_g_=g
6269 """
63- print (f"Fetching personal link for { participant_study_id } ... " )
70+ print (f"Fetching personal link for { study_identifier } ... " )
6471 endpoint = f"{ QUALTRICS_BASE_URL } /distributions/{ distribution_id } /links"
6572 parameters = {
6673 "surveyId" : str (qualtrics_survey_id )
@@ -69,45 +76,78 @@ def get_personal_link(qualtrics_survey_id: str, distribution_id: str, participan
6976 response = requests .get (endpoint , headers = HEADERS , params = parameters )
7077 response .raise_for_status ()
7178 data = response .json ()
72- personal_link = [item ["link" ] for item in data ["result" ]["elements" ] if ("externalDataReference" in item ) and (item ["externalDataReference" ] == participant_study_id )][0 ]
79+ personal_link = [item ["link" ] for item in data ["result" ]["elements" ] if ("externalDataReference" in item ) and (item ["externalDataReference" ] == study_identifier )][0 ]
7380 return personal_link
7481
7582 except requests .exceptions .RequestException as exc :
7683 raise QualtricsAPIError (
77- f"Error while fetching personal link of individual { participant_study_id } ."
84+ f"Error while fetching personal link of individual { study_identifier } ."
7885 ) from exc
7986 except (KeyError , TypeError , ValueError ) as exc :
8087 raise QualtricsAPIError (
81- f"Unexpected response format when fetching personal link of individual { participant_study_id } ."
88+ f"Unexpected response format when fetching personal link of individual { study_identifier } ."
8289 ) from exc
8390
84- def add_individuals_to_survey (participant_ids_list : list , embedded_data_field , distribution_id , qualtrics_survey_id , mailing_list_id , directory_id ):
91+ def add_individuals_to_survey (new_subject_ids : list , ldot_study_id : str , eaid_deelnemer_entity : str , embedded_data_field : str , distribution_id : str , qualtrics_survey_id : str , mailing_list_id : str , directory_id : str ):
92+ def convert_api_subject_id_to_study_identifier (api_subject_id ):
93+ """Convert subject ID used by the Ldot API to study identifier that can be used in Qualtrics surveys"""
94+
95+ response = requests .post (
96+ "https://accware.memic.maastrichtuniversity.nl/ldot_identity_server/connect/token" ,
97+ data = {
98+ "grant_type" : "client_credentials" ,
99+ "client_id" : CLIENT_ID ,
100+ "client_secret" : CLIENT_SECRET
101+ }
102+ )
103+ token = response .json ()["access_token" ]
104+ headers = {"accept" : "application/json" ,
105+ "Authorization" : f"Bearer { token } "
106+ }
107+
108+ response = requests .get (
109+ f"https://accware.memic.maastrichtuniversity.nl/memic_ldot_api/api/v1.1/{ ldot_study_id } /Entity/{ eaid_deelnemer_entity } " ,
110+ headers = headers
111+ )
112+
113+ subject_ids = response .json ().get ("Data" , {}).get ("SubjectIds" )
114+ guid_to_registration_id = {subject ["Guid" ]: subject ["RegistrationId" ] for subject in subject_ids if "Guid" in subject and "RegistrationId" in subject }
115+
116+ study_identifier = guid_to_registration_id .get (api_subject_id )
117+ return study_identifier
118+
119+
85120 participant_to_link_dict = {}
86- for participant_id in participant_ids_list :
87- contact_exists = check_contact_in_mailing_list (participant_id , mailing_list_id , directory_id )
121+ for subject_id in new_subject_ids :
122+ study_identifier = convert_api_subject_id_to_study_identifier (subject_id )
123+ print (f"Processing subject ID: { subject_id } (Study Identifier: { study_identifier } )" )
124+
125+ contact_exists = check_contact_in_mailing_list (study_identifier , mailing_list_id , directory_id )
88126
89127 if not contact_exists :
90- add_contact_to_mailing_list (participant_id , embedded_data_field , mailing_list_id , directory_id )
128+ print (f"Adding participant study ID { study_identifier } to mailing list..." )
129+ add_contact_to_mailing_list (study_identifier , embedded_data_field , mailing_list_id , directory_id )
91130 else :
92- print (f"Participant study ID { participant_id } already exists in this mailing list" )
131+ print (f"Participant study ID { study_identifier } already exists in this mailing list" )
93132
94- personal_link = get_personal_link (qualtrics_survey_id , distribution_id , participant_id )
133+ personal_link = get_personal_link (qualtrics_survey_id , distribution_id , study_identifier )
95134
96- participant_to_link_dict [participant_id ] = personal_link
135+ participant_to_link_dict [subject_id ] = personal_link
97136
98137 return participant_to_link_dict
99138
100139if __name__ == "__main__" :
101140 # # Example usage
102- participant_study_id = ["11111TEST11111" , "22222TEST22222" , "33333TEST33333" ]
141+ participant_study_id = ["352fb9d8-962f-4735-9fc7-7b4e18109a51" ]
142+ ldot_study_id = "5c9c6a47-c8d7-8142-a8c8-ccdcb8a8044b"
143+ eaid_deelnemer_entity = "7f61b810-00ed-1d41-8a33-4164f25ebad0"
103144 embedded_data_field = "study_id_child"
104145 qualtrics_survey_id = "SV_efCMOg6wHU0T8ii"
105146 mailing_list_id = "CG_2dMbO6WUBMnCeIK"
106147 distribution_id = "EMD_7AEa416lRwFhrkF"
107148 directory_id = "POOL_10pyxk9leSUisrT"
108149
109-
110- link = add_individuals_to_survey (participant_study_id , embedded_data_field , distribution_id , qualtrics_survey_id , mailing_list_id , directory_id )
150+ link = add_individuals_to_survey (participant_study_id , ldot_study_id , eaid_deelnemer_entity , embedded_data_field , distribution_id , qualtrics_survey_id , mailing_list_id , directory_id )
111151
112152 print (link )
113153
0 commit comments