Search code examples
javascriptjqueryhtmlangularjslinkedin-api

How do you attach a picture to LinkedIn share from a blog post?


I have a blog that I want to make shareable via LinkedIn. The docs LinkedIn presents, while simply stated don't have enough detail for me to understand my use case. My use case requires me to dynamically put the picture and description in each blog post, which isn't being populated right now. This is an Angular project.

My current code: post.html

<script>
  delete IN;
  $.getScript("https://platform.linkedin.com/in.js");
</script>
<script type="IN/Share" data-url={{webAddress}} data-counter="right"></script>

post.js //I have all of my data in $scope variables in this area, which includes // the picture and description I'd like to attach to the post.

Here is what the LinkedIn docs show as the right way to do this: post.html

<script type="text/javascript" src="//platform.linkedin.com/in.js">
  api_key: YOUR_API_KEY_HERE
  authorize: true
  onLoad: onLinkedInLoad
</script>

<script type="text/javascript">

  // Setup an event listener to make an API call once auth is complete
    function onLinkedInLoad() {
      IN.Event.on(IN, "auth", shareContent);
    }

  // Handle the successful return from the API call
  function onSuccess(data) {
    console.log(data);
  }

  // Handle an error response from the API call
  function onError(error) {
    console.log(error);
  }

  // Use the API call wrapper to share content on LinkedIn
  function shareContent() {

    // Build the JSON payload containing the content to be shared
    var payload = { 
      "comment": "Check out developer.linkedin.com! http://linkd.in/1FC2PyG", 
      "visibility": { 
        "code": "anyone"
      } 
    };

    IN.API.Raw("/people/~/shares?format=json")
      .method("POST")
      .body(JSON.stringify(payload))
      .result(onSuccess)
      .error(onError);
  }

</script>

As I understand it, I need to populate the payload object with the right data/links. I have no clue how to do this based on what's in the docs.

Here are a few things I've tried/thought about along with where I'm currently stuck:

1) Get the data from post.js and put it in the payload object between the script tags in post.html. After doing some research, it is not possible to do this. Though I welcome being corrected if I'm wrong.

2) Bring the IN object into angular and populate the payload in post.js. This sounds really great but LinkedIn provides no html with which to call a function in post.js with Angular. Plus the LinkedIn code as presented takes care of formatting for the button and what comes after you click it.

3) Make an http call inside the script tags with JQuery. I rarely if ever use JQuery and have never used http for JQuery before. If this is even a feasible way to think of this problem, this is what I came up with:

<script type="IN/Share" data-url={{webAddress}} data-counter="right">
                  $.get( "https://public-api.wordpress.com/rest/v1.1/sites/myPost", function( response ) {
                    var post = _.first(_.filter(response.posts, function(n){return n.title.replace(/ /g,"-").replace(/[:]/g, "").toLowerCase() === $stateParams.id}));
                    var post1 = _.assign(post, {category: _.first(_.keys(post.categories)), pic: _.first(_.values(post.attachments)).URL, credit: _.first(_.values(post.attachments)).caption, linkCredit: _.first(_.values(post.attachments)).alt, fullStory: post.content.replace(/<(?!\s*\/?\s*p\b)[^>]*>/gi,'')});
                    **var image = post1.pic;**
                    **var title = post1.title;**
                    **var webAddress = window.location.href;**

                    function onLinkedInLoad() {
                      IN.Event.on(IN, "auth", shareContent);
                    }

                   function onSuccess(data) {
                    console.log(data);
                   }

                   function onError(error) {
                    console.log(error);
                   }

                   function shareContent(title, image, webAddress) {

                    var payload = {                         
                      "content": {
                        "title": title,
                        "submitted-image-url": image,
                        "submitted-url": webAddress
                      }
                    };

                    IN.API.Raw("/people/~/shares?format=json")
                      .method("POST")
                      .body(JSON.stringify(payload))
                      .result(onSuccess)
                      .error(onError);
                   }
                  });

                  </script>

This solution did not result in a solution either. Where to go from here, I have no ideas. I'm sure this simple but idiosyncratic enough that I need a little hand holding.


Solution

  • Unfortunately, I have not worked with linkedin API.

    Perhaps not all will be right in my example. But I've got to use a variable IN in angular and write about the call API wrapper.

    An example of the use of plugins, see page LinkedIn Plugins.

    Live example on jsfiddle.

      //CallBackHell
      function LinkedInServiceFunc(callback) {
        callback && IN.Event.onDOMReady(callback);
      }
    
      angular.module('ExampleApp', [])
        .controller('ExampleController', function($scope, LinkedInService, ShareLinkedINService) {
          console.log('ExampleController IN', IN);
          console.log('ExampleController LinkedInService', LinkedInService);
          LinkedInService.promise.then(function(LIN) {
            console.log('Complete loading script for LinkedIn in ExampleController', LIN.Objects)
          });
    
          //Then you can interact with IN object as angular service. Like this
          $scope.shareContent = function() { // Use the API call wrapper to share content on LinkedIn
    
            // Build the JSON payload containing the content to be shared
            var payload = {
              "comment": $scope.comment,
              "visibility": {
                "code": 'anyone'
              }
            };
            // Handle the successful return from the API call
            function onSuccess(data) {
              console.log(data);
            }
    
            // Handle an error response from the API call
            function onError(error) {
              console.log(error);
            }
            console.log('shareContent', payload);
            LinkedInService.promise.then(function(LIN) {
              LIN.API.Raw("/people/~/shares?format=json")
                .method("POST")
                .body(JSON.stringify(payload))
                .result(onSuccess)
                .error(onError);
            });
          }
          $scope.shareContentService = function() {
            //It's better way, i think
            ShareLinkedINService.shareContent($scope.comment, 'anyone').then(function(data) {
              console.log('success', data);
            }).catch(function(data) {
              console.err('error', data);
            });
          }
        })
        .service('LinkedInService', function($q) {
          var defer = $q.defer();
          LinkedInServiceFunc(function() {
            defer.resolve(IN);
          });
          return {
            promise: defer.promise
          };
        })
        //You can create wrapper on IN API
        .service('ShareLinkedINService', function(LinkedInService, $q) {
          return {
            shareContent: function(comment, visible) {
              var defer = $q.defer();
              var payload = {
                "comment": comment,
                "visibility": {
                  "code": visible
                }
              };
              LinkedInService.promise.then(function(LIN) {
                LIN.API.Raw("/people/~/shares?format=json")
                  .method("POST")
                  .body(JSON.stringify(payload))
                  .result(defer.resolve)
                  .error(defer.reject);
              });
              return defer.promise;
    
            }
          }
        })
        .directive('linkedInShareButton', function(LinkedInService) {
          return {
            restrict: "E",
            replace: false,
            scope: {
              shareUrl: "@",
              counter:"@"
            },
            link: function(scope, elem, attr) {
              var script = document.createElement('script');
              script.setAttribute('type', 'IN/Share');
              script.setAttribute('data-url', scope.shareUrl);
              script.setAttribute('data-counter', scope.counter);
              elem.append(script);
            },
          };
        });
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
    <script type="text/javascript" src="//platform.linkedin.com/in.js">
      authorize: false
      onLoad: LinkedInServiceFunc
        //I don't have api_key, because i delete it
        // api_key: YOUR_API_KEY_HERE
        // authorize: true
        // onLoad: onLinkedInLoad
    </script>
    
    <body ng-app="ExampleApp">
      <div>
        <div ng-controller="ExampleController">
          <input ng-model="comment">
          <button ng-click="shareContent()">
            shareContent
          </button>
          <button ng-click="shareContentService()">
            shareContentService
          </button>
          <script type="IN/Share" data-url="www.mail.ru" data-counter="top"></script>
          <linked-in-share-button share-url="www.mail.ru" counter="top"></linked-in-share-button>
        </div>
      </div>
    </body>