Heroku AppLinkの使い方 (クエリ)

Heroku AppLinkのサンプルコードがもう少し欲しいところ...で、まずはクエリのサンプルでも備忘録として残してみる
※サンプルコードは Node.js 版のSDKを使ったものに限定です。SDKのリポジトリは https://github.com/heroku/heroku-applink-nodejs を参照してください。

1. 1つのオブジェクトだけクエリする

import * as salesforcesdk from "@heroku/applink";

const sfdc_id = 'xxxxx';

async function sample () {
  const sdk = salesforcesdk.init();
  // ※Authorized Userを使います
  const org = await sdk.addons.applink.getAuthorization(process.env.HEROKU_APPLINK_CONNECTION_NAME);

  // 取引先を取得する
  const accountQueryResult: salesforcesdk.RecordQueryResult = await org.dataApi.query(
    `select id,name from account where id = '${sfdc_id}'`
  );
  // accountQueryResult:
  // {
  //   records: (レコードの配列)
  //   totalSize: (クエリした全レコード件数)
  //   done: (falseだと、次のページリンクがある)
  //   nextRecordsUrl: (次ページのリンク)
  // }
  
  const accountRecords: salesforcesdk.QueriedRecord[] = accountQueryResult.records;
  // accountRecords:
  // [
  //   {
  //     type: (オブジェクトAPI)
  //     fields: (レコード内の属性がオブジェクトとして格納)
  //     subQueryResults: (サブクエリがあれば)
  //   }
  // ]
  const accountRecord: salesforcesdk.QueriedRecord = accountRecords[0];
  const account: { [key: string]: unknown } = accountRecord.fields;
  console.log(account.id);
  console.log(account.name);
  
}

2. サブクエリも追加してみる

import * as salesforcesdk from "@heroku/applink";

const sfdc_id = 'xxxxx';

async function sample () {
  const sdk = salesforcesdk.init();
  const org = await sdk.addons.applink.getAuthorization(process.env.HEROKU_APPLINK_CONNECTION_NAME);

  // 取引先と、それに紐つく取引先責任者を取得する
  const accountQueryResult: salesforcesdk.RecordQueryResult = await org.dataApi.query(
    `select id,name,(select name from contacts) from account where id = '${sfdc_id}'`
  );
  
  const accountRecords: salesforcesdk.QueriedRecord[] = accountQueryResult.records;
  const accountRecord: salesforcesdk.QueriedRecord = accountRecords[0];

  // subQueryResults内に、子リレーション名をkeyにした RecordQueryResult があるのでそれを取得する
  const contactQueryResult: salesforcesdk.RecordQueryResult = accountRecord.subQueryResults.contacts;
  if (contactQueryResult.totalSize == 0) {
    console.log('取引先責任者なし');
  }
  const contactRecords: salesforcesdk.QueriedRecord[] = contactQueryResult.records;
  contactRecords.forEach((record) => {
    // 取引先責任者名
    console.log(record.fields.name);
  });
}

3. 親オブジェクトへのリレーションを追加してみる

import * as salesforcesdk from "@heroku/applink";

const sfdc_id = 'xxxxx';

async function sample () {
  const sdk = salesforcesdk.init();
  const org = await sdk.addons.applink.getAuthorization(process.env.HEROKU_APPLINK_CONNECTION_NAME);

  // 商談と、商談明細をクエリする
  // 商談明細には、商品の商品名もクエリする
  const opportunityQueryResult: salesforcesdk.RecordQueryResult = await org.dataApi.query(
    `select id,name,(select id,product2.name from opportunitylineitems) from opportunity where id = '${sfdc_id}'`
  );

  const opportunityRecords: salesforcesdk.QueriedRecord[] = opportunityQueryResult.records;
  const opportunityRecord: salesforcesdk.QueriedRecord = opportunityRecords[0];

  const opportunitylineitemQueryResult: salesforcesdk.RecordQueryResult = opportunityRecord.subQueryResult.opportunitylineitems;
  const opportunitylineitemRecord: salesforcesdk.QueriedRecord = opportunitylineitemQueryResult.records[0];
  // opportunitylineitemRecord: 
  // {
  //   type: 'opportunitylineitem',
  //   fields: {
  //     id: '00kA...',
  //     product2: {
  //       type: 'product2',
  //       fields: {
  //         name: 'xxxxx...'
  //       }
  //     }
  //   }
  // }

  // 商談明細が参照する商品レコードを取得する
  const productRecord: salesforcesdk.QueriedRecord = opportunitylineitemRecord.fields.product2;
  // productRecord:
  // {
  //   type: 'product2',
  //   fields: {
  //     name: 'xxxx'
  //   }
  // }
  console.log(productRecord.field.name);
  
}

Read more

heroku

Dancing with Heroku AppLink / 2

(ローカルアプリと組み合わせる...?) 構成の概要 Heroku AppLinkの活用例として、こんな構成を試してみた。 * 個別に作成したElectronアプリケーションがあって、そのアプリケーションはSalesforceのデータを参照したり、データを作成する。 * Electronアプリケーションに、Salesforceのアクセストークンを持たせてアクセスできるようにしたい。 * しかし、Electronアプリケーション内にSalesforceのアカウント情報を持たせたくないし、個別のログイン機能なんて作りたくない。 * Electronアプリケーションに渡す情報にはSalesforce外の情報もあり、その諸々の情報をまとめるためにHerokuアプリケーションを設置した。 * (Apexコードを書くのがやや面倒...) といったあたりで、上のような構成を試してみた。 Heroku AppLinkの活用ポイント など ※主に②で大活躍するので、そこに絞った話をしてみよう。 まず、Heroku側の実装としては以下を前提として、Node.jsアプリケ

By Takahiro Yonei

heroku

Dancing with Heroku AppLink / 1

(まずはよくありそうなパターンでも) 構成の概要 Heroku AppLinkの活用例として、こんな構成を試しているところ。 * HerokuとSalesforceを組み合わせて上のようなWebシステムを構築してる。 * HerokuはFrontend(Next.js)とBackend(Medusa.js)を使ってアプリケーションを作成している。 * Salesforceで作成したデータをHeroku Backendに連携する。BackendのAPIを外部サービスとしてSalesforceに登録しておいて、SalesforceからはFlowを使って連携する。 * Fronendから送信されたデータは、Backendを介してSalesforceに連携する。Heroku AppLinkを使ってSalesforceへのアクセストークンを取得してSalesforceにデータを書き込む。 構成としては、よくありそうなパターンではなかろうか。 しかし、Heroku BackendにAppLinkを組み込むことで、BackendとSalesforceの実装工数を削減で

By Takahiro Yonei

Dancing with Heroku vibes / 2

heroku vibesの画面操作を見るに、プロンプトを入力しつつ1つのherokuアプリを自動生成していくように見える。 1つのアプリで完結するようなものであれば、それでも良さそうに思える。 しかし、複数のherokuアプリを組み合わせてシステムを構築することもあるので、その場合はどうサポートしてくれるだろうか? プログラマの視点からすると、アプリの自動生成については...あまり優位性が見出せない。 pipelineを使いたいとかgithubとの連携とかあるので、自分でやった方が良いかなぁと思う。その辺りはむしろheroku MCPサーバの方がやりやすいかもしれない。 ボンヤリとしたアイディアから、構成や使用するadd onをいい感じに提案してくれる壁打ち相手として使えそうだろうか?と思う。 プログラマでない人からすれば、herokuアプリを自動生成してくれるのは助かる場面はありそうだ。 ただの想像だけど、salesforceを拡張する機能としてheroku applinkを使ったherokuアプリを自動生成する...みたいな場面であれば、プログラマでない人には有益かもしれない

By Takahiro Yonei