【C#】SalesforceのREST APIを利用してみる

2019年10月18日

本稿では、主に企業で利用されているであろうSalesforceというシステムから情報を取得したり更新したりするプログラムを書いてみたいと思います。

いつもはJavaの記事ばかりですが、気が向いたので今回はC#で書いてみました。使い回しですが一応記事にしておきます。

Salesforceは顧客管理などができるWebシステムです。詳細は「https://www.salesforce.com/jp/」をご覧ください。

REST APIの詳細はこちらからどうぞ。

使用環境はVisualStudioです。プロジェクト作ったらProgram.csファイルができるので、そのファイルにプログラムを書きます。

プロジェクトはコンソールプロジェクトがいいと思います。環境によっては実行結果をみるためのコンソールがすぐ閉じて確認できないかもしれないので、最悪ブレイクポイント仕掛けるなりして確認すると良いかも。



REST APIでログインを行う

ログインを行うには「https://login.salesforce.com/services/oauth2/token」へアクセスします。

methodはPOSTを指定し必要な認証パラメータを設定します。

grant_type=password
client_id=「コンシューマ鍵」
client_secret=「コンシューマの秘密」
username=「ユーザー名」
password=「パスワード」+「セキュリティートークン」

必要な値はSalesforceへログインして取得できます。

ユーザー名とパスワードはわかると思いますが、コンシューマ鍵、コンシューマの秘密、セキュリティートークンは取得方法がわからない方もいると思います。
これらの取得手順は、こちらの記事で紹介しております。

値が取得できたらログイン処理を実行してみましょう。

using System;
using System.IO;
using System.Net;
using System.Text;

namespace SForceTest {
	class Program {
		static void Main(string[] args) {
			login();
		}

		static void login() {
			string url = "https://login.salesforce.com/services/oauth2/token";
			//string url = "https://test.salesforce.com/services/oauth2/token";//Sandbox環境の場合
			string method = "POST";
			string contentType = "application/x-www-form-urlencoded; charset=utf-8";
			StringBuilder sb = new StringBuilder();
			sb.Append("grant_type=password").Append("&");
			sb.Append("client_id=54LOAKJL+DJALH.0224D.__jSSAFfsfM__oKLJLKFJSLKJkjLKJSdkjklsjlkdfk253Ge5153213faADdegft133").Append("&");
			sb.Append("client_secret=LSFJHLS2313221SAD325FAD21321").Append("&");
			sb.Append("username=test%40mail.co.jp").Append("&");
			sb.Append("password=aaaasdkjLKJHGK23DA2dda");
			byte[] body = Encoding.UTF8.GetBytes(sb.ToString());
			byte[] result = executeRequest(url
				, method
				, contentType
				, null
				, body);

			if (result != null && result.Length > 0) {
				Console.WriteLine(Encoding.UTF8.GetString(result));
			} else {
				Console.WriteLine("レスポンスがないよ!!");
			}
		}

		static byte[] executeRequest(string url, string method, string contentType, string accessToken, byte[] body) {
			try {
				//WebRequestの作成
				System.Net.HttpWebRequest req =
					System.Net.WebRequest.Create(url) as HttpWebRequest;

				//アクセストークンの指定
				if (accessToken != null) req.Headers["Authorization"] = "Bearer " + accessToken;

				//メソッドの指定
				req.Method = method;

				//コンテントタイプの指定
				req.ContentType = contentType;

				//POST送信するデータの長さを指定
				if (body != null) req.GetRequestStream().Write(body, 0, body.Length);

				//サーバーからの応答を受信するためのWebResponseを取得
				System.Net.WebResponse res = null;
				try {
					res = req.GetResponse();
				} catch (System.Net.WebException e) {
					res = e.Response;
				}

				//応答データを受信するためのStreamを取得
				using (MemoryStream mem = new MemoryStream())
				using (Stream resStream = res.GetResponseStream()) {
					byte[] buf = new byte[4096];
					int r;
					while ((r = resStream.Read(buf, 0, buf.Length)) > 0) {
						mem.Write(buf, 0, r);
					}
					return mem.ToArray();
				}
			} catch (Exception e) {
				Console.WriteLine(e.StackTrace);
			}
			return null;
		}
	}
}
実行結果コンソール(インデント付与済み)

{ "access_token": "000A000A0a0A0!QAKAJDSKLNDLAS5215153153AD21312A.LKJHSADLKJAL2465461256151111010000254", "instance_url": "https://app.salesforce.com", "id": "https://login.salesforce.com/id/00D0ED/00392HJGJH00XM000000", "token_type": "Bearer", "issued_at": "73268", "signature": "fkhjsakdfl/jksfdljk2/b1olCBVsdsDG+zZC76ad7889DFDJKY=" }

重要なのはaccess_tokenとinstance_urlです。

これらはデータ取得や更新などをする際に必要な値となります。

access_tokenはログインした証となるものでデータ取得などをする際に必要となります。

instance_urlは実際にデータ取得などするときにアクセスするベースURLとなります。

インスタンスID(appの部分)は使用者によって変わると思います。

テストで必要であれば実際に取得できた値をメモっておきましょう。

この記事では、以降この結果をキーに設定したサンプルを掲載していきます。

REST APIでレコードを作成する

レコードを作成するには
「https://<インスタンスID>.salesforce.com/services/data/<APIバージョン>/sobjects/<オブジェクト名>」
にアクセスし、POSTを指定してリクエストします。

登録内容はJSONデータなどで指定します。

それでは取引先にレコード追加してみましょう。

取引先のオブジェクト名はAccountです。

using System;
using System.IO;
using System.Net;
using System.Text;

namespace SForceTest {
	class Program {
		static void Main(string[] args) {
			create();
		}

		static void create() {
			string url = "https://app.salesforce.com/services/data/v44.0/sobjects/Account";
			string method = "POST";
			string contentType = "application/json; charset=utf-8";
			string accessToken = "000A000A0a0A0!QAKAJDSKLNDLAS5215153153AD21312A.LKJHSADLKJAL2465461256151111010000254";
			string body = "{\"Name\":\"Test\"}";
			byte[] result = executeRequest(url: url
			, method: method
			, contentType: contentType
			, accessToken: accessToken
			, Encoding.UTF8.GetBytes(body));

			if (result != null && result.Length > 0) {
				Console.WriteLine(Encoding.UTF8.GetString(result));
			} else {
				Console.WriteLine("レスポンスがないよ!!");
			}
		}

		static byte[] executeRequest(string url, string method, string contentType, string accessToken, byte[] body) {
			try {
				//WebRequestの作成
				System.Net.HttpWebRequest req =
					System.Net.WebRequest.Create(url) as HttpWebRequest;

				//アクセストークンの指定
				if (accessToken != null) req.Headers["Authorization"] = "Bearer " + accessToken;

				//メソッドの指定
				req.Method = method;

				//コンテントタイプの指定
				req.ContentType = contentType;

				//POST送信するデータの長さを指定
				if (body != null) req.GetRequestStream().Write(body, 0, body.Length);

				//サーバーからの応答を受信するためのWebResponseを取得
				System.Net.WebResponse res = null;
				try {
					res = req.GetResponse();
				} catch (System.Net.WebException e) {
					res = e.Response;
				}

				//応答データを受信するためのStreamを取得
				using (MemoryStream mem = new MemoryStream())
				using (Stream resStream = res.GetResponseStream()) {
					byte[] buf = new byte[4096];
					int r;
					while ((r = resStream.Read(buf, 0, buf.Length)) > 0) {
						mem.Write(buf, 0, r);
					}
					return mem.ToArray();
				}
			} catch (Exception e) {
				Console.WriteLine(e.StackTrace);
			}
			return null;
		}
	}
}
実行結果

実行結果コンソール(インデント付与済み)

{ "id": "0011903JO01", "success": true, "errors": [] }

取引先にTestが追加されていれば成功です。

設定できるフィールドはName以外にも多数あります。
指定フィールドはAPIでも取得することはできますし、SOAP APIのレファレンスとかも見てみると案外取れたりします。

idはデータ取得、更新、削除などで使用するキーとなります。

テストで必要であれば実際の値をメモっておきましょう。この記事では以降、この結果をキーに設定したサンプルを掲載していきます。

REST APIでレコードを取得する

レコードを取得するには
「https://<インスタンスID>.salesforce.com/services/data/<APIバージョン>/sobjects/<オブジェクト名>/<オブジェクトID>」
にアクセスし、GETを指定してリクエストします。

先ほど作成したTestレコードのidを設定してデータ取得してみましょう。

using System;
using System.IO;
using System.Net;
using System.Text;

namespace SForceTest {
	class Program {
		static void Main(string[] args) {
			get();
		}

		static void get() {
			string url = "https://app.salesforce.com/services/data/v44.0/sobjects/Account/0011903JO01";
			string method = "GET";
			string accessToken = "000A000A0a0A0!QAKAJDSKLNDLAS5215153153AD21312A.LKJHSADLKJAL2465461256151111010000254";
			byte[] result = executeRequest(url
			, method
			, null
			, accessToken
			, null
			);

			if (result != null && result.Length > 0) {
				Console.WriteLine(Encoding.UTF8.GetString(result));
			} else {
				Console.WriteLine("レスポンスがないよ!!");
			}
		}

		static byte[] executeRequest(string url, string method, string contentType, string accessToken, byte[] body) {
			try {
				//WebRequestの作成
				System.Net.HttpWebRequest req =
					System.Net.WebRequest.Create(url) as HttpWebRequest;

				//アクセストークンの指定
				if (accessToken != null) req.Headers["Authorization"] = "Bearer " + accessToken;

				//メソッドの指定
				req.Method = method;

				//コンテントタイプの指定
				req.ContentType = contentType;

				//POST送信するデータの長さを指定
				if (body != null) req.GetRequestStream().Write(body, 0, body.Length);

				//サーバーからの応答を受信するためのWebResponseを取得
				System.Net.WebResponse res = null;
				try {
					res = req.GetResponse();
				} catch (System.Net.WebException e) {
					res = e.Response;
				}

				//応答データを受信するためのStreamを取得
				using (MemoryStream mem = new MemoryStream())
				using (Stream resStream = res.GetResponseStream()) {
					byte[] buf = new byte[4096];
					int r;
					while ((r = resStream.Read(buf, 0, buf.Length)) > 0) {
						mem.Write(buf, 0, r);
					}
					return mem.ToArray();
				}
			} catch (Exception e) {
				Console.WriteLine(e.StackTrace);
			}
			return null;
		}
	}
}
実行結果コンソール(インデント付与済み)

{ "attributes": { "type": "Account", "url": "/services/data/v44.0/sobjects/Account/0011903JO01" }, "Id": "0011903JO01", "IsDeleted": false, "MasterRecordId": null, "Name": "Test", "Type": null, "ParentId": null, "BillingStreet": null, "BillingCity": null, "BillingState": null, "BillingPostalCode": null, "BillingCountry": null, "BillingLatitude": null, "BillingLongitude": null, "BillingGeocodeAccuracy": null, "BillingAddress": null, "ShippingStreet": null, "ShippingCity": null, "ShippingState": null, "ShippingPostalCode": null, "ShippingCountry": null, "ShippingLatitude": null, "ShippingLongitude": null, "ShippingGeocodeAccuracy": null, "ShippingAddress": null, "Phone": null, "Fax": null, "Website": null, "PhotoUrl": "/services/images/photo/0011903JO01", "Industry": null, "NumberOfEmployees": null, "Description": null, "Site": null, "OwnerId": "039012930", "CreatedDate": "2019-09-29T11:03:41.000+0000", "CreatedById": "039012930", "LastModifiedDate": "2019-09-29T11:03:41.000+0000", "LastModifiedById": "039012930", "SystemModstamp": "2019-09-29T11:03:41.000+0000", "LastActivityDate": null, "LastViewedDate": "2019-09-29T11:04:37.000+0000", "LastReferencedDate": "2019-09-29T11:04:37.000+0000", "Jigsaw": null, "JigsawCompanyId": null, "AccountSource": null, "SicDesc": null, }

ほとんど値を設定していないのでnullですね。

REST APIでレコードを更新する

レコードの更新を行うには
「https://<インスタンスID>.salesforce.com/services/data/<APIバージョン>/sobjects/<オブジェクト名>/<オブジェクトID>」
にアクセスし、PATCHを指定してリクエストします。

更新内容はJSON文字列で指定します。

試しに作成したTestのレコードをTest2という名前に変更してみましょう。

using System;
using System.IO;
using System.Net;
using System.Text;

namespace SForceTest {
	class Program {
		static void Main(string[] args) {
			update();
		}

		static void update() {
			string url = "https://app.salesforce.com/services/data/v44.0/sobjects/Account/0011903JO01";
			string method = "PATCH";
			string contentType = "application/json; charset=utf-8";
			string accessToken = "000A000A0a0A0!QAKAJDSKLNDLAS5215153153AD21312A.LKJHSADLKJAL2465461256151111010000254";
			string body = "{\"Name\":\"Test2\"}";
			byte[] result = executeRequest(url: url
			, method: method
			, contentType: contentType
			, accessToken: accessToken
			, Encoding.UTF8.GetBytes(body));

			if (result != null && result.Length > 0) {
				Console.WriteLine(Encoding.UTF8.GetString(result));
			} else {
				Console.WriteLine("レスポンスがないよ!!");
			}
		}

		static byte[] executeRequest(string url, string method, string contentType, string accessToken, byte[] body) {
			try {
				//WebRequestの作成
				System.Net.HttpWebRequest req =
					System.Net.WebRequest.Create(url) as HttpWebRequest;

				//アクセストークンの指定
				if (accessToken != null) req.Headers["Authorization"] = "Bearer " + accessToken;

				//メソッドの指定
				req.Method = method;

				//コンテントタイプの指定
				req.ContentType = contentType;

				//POST送信するデータの長さを指定
				if (body != null) req.GetRequestStream().Write(body, 0, body.Length);

				//サーバーからの応答を受信するためのWebResponseを取得
				System.Net.WebResponse res = null;
				try {
					res = req.GetResponse();
				} catch (System.Net.WebException e) {
					res = e.Response;
				}

				//応答データを受信するためのStreamを取得
				using (MemoryStream mem = new MemoryStream())
				using (Stream resStream = res.GetResponseStream()) {
					byte[] buf = new byte[4096];
					int r;
					while ((r = resStream.Read(buf, 0, buf.Length)) > 0) {
						mem.Write(buf, 0, r);
					}
					return mem.ToArray();
				}
			} catch (Exception e) {
				Console.WriteLine(e.StackTrace);
			}
			return null;
		}
	}
}
実行結果

取引先名がTest2に変更されればOKです。

実行結果コンソール

レスポンスがないよ!!

REST APIでレコードを削除する

レコードの削除を行うには
「https://<インスタンスID>.salesforce.com/services/data/<APIバージョン>/sobjects/<オブジェクト名>/<オブジェクトID>」
にアクセスし、DELETE を指定してリクエストします。

それでは、先ほど更新したTest2のレコードを削除してみましょう。

using System;
using System.IO;
using System.Net;
using System.Text;

namespace SForceTest {
	class Program {
		static void Main(string[] args) {
			delete();
		}

		static void delete() {
			string url = "https://app.salesforce.com/services/data/v44.0/sobjects/Account/0011903JO01";
			string method = "DELETE";
			string accessToken = "000A000A0a0A0!QAKAJDSKLNDLAS5215153153AD21312A.LKJHSADLKJAL2465461256151111010000254";
			byte[] result = executeRequest(url
			, method
			, null
			, accessToken
			, null
			);

			if (result != null && result.Length > 0) {
				Console.WriteLine(Encoding.UTF8.GetString(result));
			} else {
				Console.WriteLine("レスポンスがないよ!!");
			}
		}

		static byte[] executeRequest(string url, string method, string contentType, string accessToken, byte[] body) {
			try {
				//WebRequestの作成
				System.Net.HttpWebRequest req =
					System.Net.WebRequest.Create(url) as HttpWebRequest;

				//アクセストークンの指定
				if (accessToken != null) req.Headers["Authorization"] = "Bearer " + accessToken;

				//メソッドの指定
				req.Method = method;

				//コンテントタイプの指定
				req.ContentType = contentType;

				//POST送信するデータの長さを指定
				if (body != null) req.GetRequestStream().Write(body, 0, body.Length);

				//サーバーからの応答を受信するためのWebResponseを取得
				System.Net.WebResponse res = null;
				try {
					res = req.GetResponse();
				} catch (System.Net.WebException e) {
					res = e.Response;
				}

				//応答データを受信するためのStreamを取得
				using (MemoryStream mem = new MemoryStream())
				using (Stream resStream = res.GetResponseStream()) {
					byte[] buf = new byte[4096];
					int r;
					while ((r = resStream.Read(buf, 0, buf.Length)) > 0) {
						mem.Write(buf, 0, r);
					}
					return mem.ToArray();
				}
			} catch (Exception e) {
				Console.WriteLine(e.StackTrace);
			}
			return null;
		}
	}
}
実行結果

実行結果コンソール

レスポンスがないよ!!

取引先からTest2が削除されたらOKです。

C#Salesforce

Posted by nompor