はじめに
この記事は、Apexを使ったBox連携の話になります。
参考になるかどうかわからないですが、Apexを使ったBox連携の文献が少なかったので残します。
(私の初投稿記事となります。)
SalesforceとBoxの連携
appexchange(Salesforce store)より、Box for Salesforceをインストールします。
こちらをインストールすると少しはApexでの連携が楽になります。
・Box for Salesforce
https://appexchangejp.salesforce.com/appxListingDetail?listingId=a0N3000000B4FmeEAF
Box連携でやったこと
ある帳票をメールで送信するために、添付ファイル形式から、Boxの共有リンクへ変更しました。
Boxの共有リンクを作るために、下記のような流れで処理を行っています。
①ファイル(Attachment)の作成
②ファイル(Attachment)をBoxへアップロード
③Boxへアップロードしたファイルの共有リンクの生成
①ファイル(Attachment)の作成
こちらは、いろいろな方法がありますが、今回はサイト経由でVisualforceを呼び出し、ファイル(Attachment)を生成しています。(サイト経由なのは、CSRFの対策のためです。)
なぜ、ファイル(Attachment)を生成するかというと、box Toolkitを使ってBoxへファイルアップロードをするためとなります。
※box ToolkitとはBox for Salesforceに組み込まれているSalesforce Developer Toolkitとなります。
・box Toolkit
https://ja.developer.box.com/guides/tooling/salesforce-toolkit/
(参考ソース)
global static List<Attachment> getAttachment(List<object> objList) {
List<Attachment> attList = new List<Attachment>();
String ym = String.valueOf(Datetime.now().format('yyyyMM','JST'));
//サイト情報を取得
Site site = [SELECT Id from Site where Name = 'test site' Limit 1];
SiteDetail sd = [SELECT Id, DurableId, IsRegistrationEnabled, SecureUrl FROM SiteDetail where DurableId = :site.Id];
String url = sd.SecureUrl + '/apex/TestForms';
for (object obj : objList) {
PageReference pageRef = new PageReference(url);
pageRef.getParameters().put('id', afItem.Id);
Attachment att = new Attachment();
att.Name = String.format('【テスト】{0}_{1}.pdf', new List<Object>{obj.Name, ym});
//Apexテスト時のエラー回避
if (Test.isRunningTest() == false) {
//通常時
att.Body = pageRef.getContent();
}else{
//テスト時
att.Body = Blob.valueOf('TEST_abc');
}
att.ParentId = obj.Id;
attList.add(att);
}
return attList;
}
②ファイル(Attachment)をBoxへアップロード
③Boxへアップロードしたファイルの共有リンクの生成
box Toolkitを使ってアップロード処理と、共有リンクを生成しています。
共有リンクについては、box Toolkitに準備されていなかったので、HttpRequestで直接APIをコールしています。
・box APIリファレンス
https://ja.developer.box.com/reference/
・box Toolkit:createFileFromAttachment(AttachmentをBoxへアップロードする)
https://ja.developer.box.com/guides/tooling/salesforce-toolkit/methods/#createfilefromattachment
・box Toolkit:sendRequest(Salesforceで設定したユーザで認証するので認証を省略できる)
https://ja.developer.box.com/guides/tooling/salesforce-toolkit/methods/#sendrequest
(参考ソース)
global static List<String> getBoxSharedLink(Id objID, Integer sharedDays, String pw) {
//戻り値([0]true:成功、false:失敗 [1]BoxファイルID [2]共有リンク)
List<String> boxFileID_URL = new List<String>();
String boxFileID = null;
String url = null;
//Objectからファイル(Attachment)を取得する。
List<Attachment> attList = [SELECT Id, Name, Body, ParentId FROM Attachment WHERE ParentId = :objID];
//box Toolkit
box.Toolkit toolkit = new box.Toolkit();
//Boxアップロード処理
try{
//boxへアップロード(box Toolkitでアップロード)
boxFileID = toolkit.createFileFromAttachment(attList[0], null, null, null);
}catch(Exception e){
system.debug('■■■ファイルID:' + boxFileID);
system.debug('■■■エラー内容:' + toolkit.mostRecentError);
boxFileID_URL.add('false');
boxFileID_URL.add('Boxへのアップロード失敗:');
boxFileID_URL.add(toolkit.mostRecentError);
return boxFileID_URL;
}
//リクエスト(共有リンク追加)
Date unshared_date = Date.today() + sharedDays;
String unshared = String.valueOf(unshared_date) + 'T00:00:00+09:00';
String endpoint = 'https://api.box.com/2.0/files/' + boxFileID;
String body = '{"shared_link":{"access": "open", "password":"' +pw+ '", "unshared_at":"' +unshared+ '"}}';
HttpRequest request = new HttpRequest();
request.setMethod('PUT');
request.setEndpoint(endpoint);
request.setHeader('content-type', 'application/json');
request.setBody(body);
//共有リンク作成処理
HttpResponse response;
try{
//認証を省くため、toolkitからリクエストする
response = toolkit.sendRequest(request);
system.debug('■■■res:'+response);
system.debug('■■■res_body:'+response.getBody());
Map<String, Object> mapResponseData = (Map<String, Object>)Json.deserializeUntyped(response.getBody());
Map<String, Object> dataToShardeLink = (Map<String, Object>)mapResponseData.get('shared_link');
//ステータスチェック
if(response.getStatusCode() == 200){
url = dataToShardeLink.get('url').toString();
}else{
boxFileID_URL.add('false');
boxFileID_URL.add('共有リンク作成失敗(ステータス200以外):');
boxFileID_URL.add(response.getBody());
return boxFileID_URL;
}
}catch(Exception e){
boxFileID_URL.add('false');
boxFileID_URL.add('共有リンク作成失敗(catch):');
if(response != null){
boxFileID_URL.add(response.getBody());
}
system.debug('■■■(catch)ファイルID:' + boxFileID);
system.debug('■■■(catch)エラー内容:' + toolkit.mostRecentError);
return boxFileID_URL;
}
boxFileID_URL.add('true');
boxFileID_URL.add(boxFileID);
boxFileID_URL.add(url);
return boxFileID_URL;
}
おわりに
今回、Apexを用いてBox連携を行いました。
Box for Salesforceが提供する、box Toolkitがもう少し充実していたらもっと楽に実装できたかと感じました。
Apexでなければ、Javaや.NET、PythonなどのSDKは準備されているのでApexを使って連携するケースは少ないのかと想定されてます。今後も、ニッチな連携を行ったら記事に残したいと思うので、よろしくお願いします。