From 1bcc10b2a29c1af8633041270e367926011120aa Mon Sep 17 00:00:00 2001 From: RisvanaCybro Date: Fri, 3 May 2024 23:49:35 +0530 Subject: [PATCH] May 03: [FIX] Bug Fixed 'hr_linkedin_recruitment' --- hr_linkedin_recruitment/__manifest__.py | 2 +- .../controller/__init__.py | 3 +- hr_linkedin_recruitment/controller/main.py | 33 ++++++-------- hr_linkedin_recruitment/doc/RELEASE_NOTES.md | 6 ++- hr_linkedin_recruitment/models/auth_outh.py | 4 +- hr_linkedin_recruitment/models/hr_job.py | 45 ++++++++++++------- 6 files changed, 52 insertions(+), 41 deletions(-) diff --git a/hr_linkedin_recruitment/__manifest__.py b/hr_linkedin_recruitment/__manifest__.py index 927ad80e1..c0f47f20c 100644 --- a/hr_linkedin_recruitment/__manifest__.py +++ b/hr_linkedin_recruitment/__manifest__.py @@ -24,7 +24,7 @@ 'summary': "Basic module for LnkedIn-HR Recruitment connector", 'description': "Basic module for LnkedIn-HR Recruitment connector", 'category': 'Generic Modules/Human Resources', - 'version': "16.0.1.0.0", + 'version': "16.0.1.0.1", 'depends': ['hr_recruitment', 'auth_oauth'], 'author': 'Cybrosys Techno Solutions', 'company': 'Cybrosys Techno Solutions', diff --git a/hr_linkedin_recruitment/controller/__init__.py b/hr_linkedin_recruitment/controller/__init__.py index f4c339a49..1178cb52e 100644 --- a/hr_linkedin_recruitment/controller/__init__.py +++ b/hr_linkedin_recruitment/controller/__init__.py @@ -19,5 +19,4 @@ # If not, see . # ############################################################################# - -from . import main \ No newline at end of file +from . import main diff --git a/hr_linkedin_recruitment/controller/main.py b/hr_linkedin_recruitment/controller/main.py index c40ef2b93..deb55fd13 100644 --- a/hr_linkedin_recruitment/controller/main.py +++ b/hr_linkedin_recruitment/controller/main.py @@ -30,11 +30,13 @@ try: from urllib.request import HTTPRedirectHandler as MechanizeRedirectHandler except ImportError: - _logger.error('Odoo module hr_linkedin_recruitment depends on the several external python package' - 'Please read the doc/requirement.txt file inside the module.') + _logger.error('Odoo module hr_linkedin_recruitment depends on the several ' + 'external python package Please read the doc/requirement.txt ' + 'file inside the module.') import json +from bs4 import BeautifulSoup from odoo.exceptions import ValidationError, Warning import requests from odoo import http, _ @@ -58,7 +60,6 @@ class LinkedinSocial(http.Controller): linked_in_url = request.env['hr.job'].browse(int(state)) recruitment = request.env['hr.job'] - access_token = requests.post( 'https://www.linkedin.com/oauth/v2/accessToken', params={ @@ -91,15 +92,13 @@ class LinkedinSocial(http.Controller): li_credential['pw'] = request.env['ir.config_parameter'].sudo().get_param('recruitment.li_password') else: raise ValidationError(_('Please fill up password in LinkedIn Credential settings.')) - url = 'https://api.linkedin.com/v2/ugcPosts' - li_suit_credent = {} li_suit_credent['access_token'] = access_token - member_url = 'https://api.linkedin.com/v2/me' + member_url = 'https://api.linkedin.com/v2/userinfo' response = recruitment.get_urn('GET', member_url, li_suit_credent['access_token']) urn_response_text = response.json() - li_credential['profile_urn'] = urn_response_text['id'] + li_credential['profile_urn'] = urn_response_text['sub'] li_suit_credent['li_credential'] = li_credential payload = json.dumps({ "author": "urn:li:person:" + li_credential['profile_urn'], @@ -107,7 +106,7 @@ class LinkedinSocial(http.Controller): "specificContent": { "com.linkedin.ugc.ShareContent": { "shareCommentary": { - "text": linked_in_url.description + "text": linked_in_url.name + "\n" + BeautifulSoup(linked_in_url.description, 'html.parser').get_text() }, "shareMediaCategory": "NONE" } @@ -117,20 +116,17 @@ class LinkedinSocial(http.Controller): } }) headers = { - 'Authorization': 'Bearer ' + access_token, + 'Authorization': 'Bearer ' + access_token, + 'X-Restli-Protocol-Version': '2.0.0', 'Content-Type': 'application/json', } - if linked_in_url.description: - - response = requests.request("POST", url, headers=headers, data=payload) + response = requests.request("POST", url, data=payload, headers=headers) share_response_text = response.json() linked_in_url.write({ 'access_token': access_token + '+' + share_response_text['id'] }) - share_response_code = response.status_code - if share_response_code == 201: linked_in_url.update_key = True elif share_response_code == 404: @@ -141,20 +137,19 @@ class LinkedinSocial(http.Controller): raise Warning("Error!! Check your connection...") else: raise Warning("Provide a Job description....") - return_uri = 'https://www.linkedin.com/oauth/v2/authorization' - li_permissions = ['r_liteprofile', 'r_member_social', 'r_organization_social', ' r_ads ', - 'r_compliance', 'r_emailaddress', 'w_member_social'] + li_permissions = ['r_liteprofile', 'r_member_social', + 'r_organization_social_feed', ' r_ads ', + 'r_compliance', 'r_emailaddress', + 'w_member_social_feed'] auth = linkedin.LinkedInAuthentication(li_credential['api_key'], li_credential['secret_key'], return_uri, li_permissions) - li_suit_credent = {} li_suit_credent['access_token'] = access_token page_share_url = 'https://api.linkedin.com/v2/ugcPosts' - response = recruitment.get_urn('GET', page_share_url, li_suit_credent['access_token']) urn_response_text = response.json() li_credential['profile_urn'] = share_response_text['id'] diff --git a/hr_linkedin_recruitment/doc/RELEASE_NOTES.md b/hr_linkedin_recruitment/doc/RELEASE_NOTES.md index 0e298103f..9e244abad 100644 --- a/hr_linkedin_recruitment/doc/RELEASE_NOTES.md +++ b/hr_linkedin_recruitment/doc/RELEASE_NOTES.md @@ -1,6 +1,10 @@ ## Module - #### 25.01.2023 #### Version 16.0.1.0.0 ##### ADD - Initial Commit (linkedin api v2) + +### 25.03.2024 +### Version 16.0.1.0.1 +### ADD +- Fixed the issue while fetching the base URL. \ No newline at end of file diff --git a/hr_linkedin_recruitment/models/auth_outh.py b/hr_linkedin_recruitment/models/auth_outh.py index a78b8a3ea..efcbd7189 100644 --- a/hr_linkedin_recruitment/models/auth_outh.py +++ b/hr_linkedin_recruitment/models/auth_outh.py @@ -28,4 +28,6 @@ class OAuthProviderLinkedin(models.Model): linkedIn are using this value for its API operations """ _inherit = 'auth.oauth.provider' - client_secret = fields.Char(string='Client Secret', help="Only need LinkedIn, Twitter etc..") + client_secret = fields.Char(string='Client Secret', help="Only need " + "LinkedIn," + " Twitter etc..") diff --git a/hr_linkedin_recruitment/models/hr_job.py b/hr_linkedin_recruitment/models/hr_job.py index 6b111aae6..06a048168 100644 --- a/hr_linkedin_recruitment/models/hr_job.py +++ b/hr_linkedin_recruitment/models/hr_job.py @@ -30,25 +30,34 @@ from odoo.exceptions import ValidationError _logger = logging.getLogger(__name__) + class HrJobShare(models.Model): """recruitment of different job positions""" _inherit = 'hr.job' update_key = fields.Char(string='Update Key', readonly=True) - access_token = fields.Char(string='Access Token',help='Access token for your linkedin app') - comments = fields.Boolean(default=False,string='Likes Comments',help='Which is used to visible the like comment retrieving button') - like_comment = fields.Boolean(default=False,string='Likes comment',help='Which is used to visible the smart buttons of likes and comments') - post_likes = fields.Integer(string='Likes Count', help="Total Number of likes in the shared post") - post_commands = fields.Integer(string='Comments Count', help="Total Number of Comments in the shared post") + access_token = fields.Char(string='Access Token', + help='Access token for your linkedin app') + comments = fields.Boolean(default=False, string='Likes Comments', + help='Which is used to visible the like comment retrieving button') + like_comment = fields.Boolean(default=False, string='Likes comment', + help='Which is used to visible the smart buttons of likes and comments') + post_likes = fields.Integer(string='Likes Count', + help="Total Number of likes in the shared post") + post_commands = fields.Integer(string='Comments Count', + help="Total Number of Comments in the shared post") def _get_linkedin_post_redirect_uri(self): """finding redirecting url""" - return url_join(self.get_base_url(), '/linkedin/redirect') + if self.get_base_url(): + https_url = self.get_base_url().replace("http://", "https://") + return f"{https_url}/linkedin/redirect" def share_linkedin(self): """ Button function for sharing post """ self.comments = True - linkedin_auth_provider = self.env.ref('hr_linkedin_recruitment.provider_linkedin') + linkedin_auth_provider = self.env.ref( + 'hr_linkedin_recruitment.provider_linkedin') if linkedin_auth_provider.client_id and linkedin_auth_provider.client_secret: linkedin_client_id = linkedin_auth_provider.client_id @@ -57,9 +66,7 @@ class HrJobShare(models.Model): 'client_id': linkedin_client_id, 'redirect_uri': self._get_linkedin_post_redirect_uri(), 'state': self.id, - 'scope': 'r_liteprofile r_emailaddress w_member_social r_1st_connections_size r_ads r_ads_reporting ' - 'r_basicprofile r_organization_admin r_organization_social rw_ads rw_organization_admin ' - 'w_member_social w_organization_social', + 'scope': 'w_member_social email profile openid', } else: raise ValidationError(_('LinkedIn Access Credentials are empty.!\n' @@ -67,7 +74,8 @@ class HrJobShare(models.Model): return { 'type': 'ir.actions.act_url', - 'url': 'https://www.linkedin.com/oauth/v2/authorization?%s' % url_encode(params), + 'url': 'https://www.linkedin.com/oauth/v2/authorization?%s' % url_encode( + params), 'target': 'self' } @@ -81,7 +89,8 @@ class HrJobShare(models.Model): return req_response def get_urn(self, method, has_access_url, access_token): - """ Function will return TRUE if credentials user has the access to update """ + """ Function will return TRUE if credentials user has the access to + update """ headers = {'x-li-format': 'json', 'Content-Type': 'application/json'} params = {} params.update({'oauth2_access_token': access_token}) @@ -100,14 +109,14 @@ class HrJobShare(models.Model): url = "https://api.linkedin.com/rest/socialActions/" + urn payload = {} headers = { - 'LinkedIn-Version': '202208', + 'LinkedIn-Version': '202308', 'Authorization': 'Bearer ' + self.access_token.split('+')[0], } response = requests.request("GET", url, headers=headers, data=payload) response_comm_like = response.json() - self.post_likes = response_comm_like['likesSummary']['totalLikes'] - self.post_commands = response_comm_like["commentsSummary"]['aggregatedTotalComments'] + self.post_commands = response_comm_like["commentsSummary"][ + 'aggregatedTotalComments'] comment_url = "https://api.linkedin.com/v2/socialActions/" + urn + "/comments" headers = { @@ -116,11 +125,13 @@ class HrJobShare(models.Model): } - response = requests.request("GET", comment_url, headers=headers, data=payload) + response = requests.request("GET", comment_url, headers=headers, + data=payload) response_commets = response.json() if response_commets["elements"]: self.env['linkedin.comments'].create({ - 'linkedin_comments': response_commets["elements"][0]['message']['text'], + 'linkedin_comments': response_commets["elements"][0]['message'][ + 'text'], }) else: pass